Updating JTable Cells with Custom Renderer

B

Bryan R. Meyer

I currently have a JTable object that utilizes the DefaultTableModel
and has three columns. For simplicity, I'll call them "Column A",
"Column B", and "Column C" and all are text cells. In a for loop in
my class, I'm testing a flag condition, and I'm setting a global
boolean variable that is equal to that flag. I then add my data to
the table. I have a custom renderer for "Column B" that colors the
text red for that particular row if the flag is true.

Unfortunately, it appears that the cells are not rendered until all of
the iterations of the loop are complete. So, if the last value of
testFlag was true, all of the text in Column B is red. If the last
value was false, all of the text in Column B is the standard color.
Why are these cells not rendered immediately after the addRow method
is called? Is there any way to force the update? I thought my
solution was the easiest to color the individual cell.

Any ideas are appreciated. The code is below.

Thanks,
Bryan

boolean testFlag;
for(int i; i<vector.size(); i++) {
if(test condition is true)
testFlag = true;
else
testFlag = false;
Object[] curMedia = {string1, string2, string3};
data.addRow(curMedia);
}

class ColoredCellRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object
value,
boolean isSelected, boolean hasFocus, int row, int column) {

if(testFlag) {
setForeground(Color.red);
}
else {
setForeground(table.getForeground());
}
return this;
}
}
 
B

Babu Kalakrishnan

Bryan R. Meyer wrote:

[Probably would ahve been more appropriate in the comp.lang.java.gui group]
Unfortunately, it appears that the cells are not rendered until all of
the iterations of the loop are complete. So, if the last value of
testFlag was true, all of the text in Column B is red. If the last
value was false, all of the text in Column B is the standard color.
Why are these cells not rendered immediately after the addRow method
is called? Is there any way to force the update? I thought my
solution was the easiest to color the individual cell.

Even though you find a way to force an update immediately, I would say that it
would be a bad design. Remember that the painting mechanism in awt/swing is
asynchronous - you don't have any control over when it occurs. You certainly
wouldn't want your Red cells to suddenly turn into Grey if someone dragged
another window across your program screen - would you ?

The right way to do it is to maintain the state (pertaining to the color) along
with the data itself. Then use your own TableModel to feed it to the UI so that
the renderer can retrieve the color also from the row object itself. For example
(warning - uncompiled, untested):

class RowData
{
private String[] coldata = new string[3];
private boolean flag;

public RowData(String s1, String s2, String s3, boolean flag)
{
coldata[0] = s1;
coldata[1] = s2;
coldata[2] = s3;
this.flag = flag;
}

public String getData(int col)
{
return coldata[col];
}

public boolean getFlag()
{
return flag;
}
}

class MyTableModel extends AbstractTableModel
{
ArrayList data = new ArrayList();

public int getRowCount()
{
return data.size();
}

public int getColumnCount()
{
return 3;
}

public RowData getRowValue(int row)
{
return (RowData)data.get(row);
}

public Object getValue(int row, int col)
{
return getRowValue(row).getData(col);
}

public void addRow(String s1, String s2, String s3, boolean flag)
{
data.add(new RowData(s1,s2,s3,flag));
}


// Other methods for removal of rows, modification etc if required
}

And in the renderer code :

boolean flag = ((MyTableModel)table.getModel()).getRowValue().getFlag();
setForeGround(flag ? Color.red : table.getForeground());


BK
 
B

Bryan R. Meyer

BK:
Remember that the painting mechanism in awt/swing is
asynchronous - you don't have any control over when it occurs. You certainly
wouldn't want your Red cells to suddenly turn into Grey if someone dragged
another window across your program screen - would you ?

Thanks for your response. It totally slipped my mind about what would
happen when the interface would refresh. That's why I was noticing
the odd behavior. The value of the testFlag variable was not being
updated on each refresh, and so the last value was used in redrawing
each JTable cell.
The right way to do it is to maintain the state (pertaining to the color)
along with the data itself.

I certainly appreciate the code fragment you gave me. I thought maybe
an easier way to do this (as your code requires a significant
retooling of my progam) would be to just keep an array or vector of
specific rows that need to be colored red. That way, the data
structure would still be around on each refresh. This would not take
up a significant amount of memory since I'm only storing a few
integers. Any reason why this shouldn't work?

Thanks for your suggestions.

Bryan
 
B

Bryan R. Meyer

I certainly appreciate the code fragment you gave me. I thought maybe
an easier way to do this (as your code requires a significant
retooling of my progam) would be to just keep an array or vector of
specific rows that need to be colored red. That way, the data
structure would still be around on each refresh.

Just a follow-up to my previous message for future reference. I
utilized the vector to hold the rows that needed to be colored and
kept it around for any possible refreshing of the JTable. This worked
perfectly.

Bryan
 
B

Bryan R. Meyer

I certainly appreciate the code fragment you gave me. I thought maybe
an easier way to do this (as your code requires a significant
retooling of my progam) would be to just keep an array or vector of
specific rows that need to be colored red. That way, the data
structure would still be around on each refresh.

Just a follow-up to my previous message for future reference. I
utilized the vector to hold the rows that needed to be colored and
kept it around for any possible refreshing of the JTable. This worked
perfectly.

Bryan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top