Updating JTable Cells with Custom Renderer

Discussion in 'Java' started by Bryan R. Meyer, Sep 3, 2004.

  1. 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;
    }
    }
    Bryan R. Meyer, Sep 3, 2004
    #1
    1. Advertising

  2. 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
    Babu Kalakrishnan, Sep 3, 2004
    #2
    1. Advertising

  3. 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
    Bryan R. Meyer, Sep 4, 2004
    #3
  4. (Bryan R. Meyer) wrote in message news:<>...

    > 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
    Bryan R. Meyer, Sep 6, 2004
    #4
  5. (Bryan R. Meyer) wrote in message news:<>...

    > 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
    Bryan R. Meyer, Sep 6, 2004
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    0
    Views:
    511
  2. RobE
    Replies:
    2
    Views:
    2,001
    =?ISO-8859-1?Q?J=F6rg_Marti?=
    Aug 12, 2003
  3. Branko Kaucic
    Replies:
    4
    Views:
    13,476
    Branko Kaucic
    Sep 13, 2005
  4. news.rcn.com
    Replies:
    2
    Views:
    1,105
    Roedy Green
    Dec 10, 2007
  5. Albert
    Replies:
    0
    Views:
    403
    Albert
    Mar 26, 2009
Loading...

Share This Page