4

I'm trying to create a table and color specific cells either yellow, red or white, depending on the content of other columns. For that I am looping through the rows filling in the values and then checking on the contents. that works just fine for every row that is currently displayed on the screen, however when the program reaches rows that are not displayed or if the user try's to scroll every cell changes its backgroundcolor back to white. I have searched the web for solutions and the only idea that sounded reasonable was to reset the cellRenderer after each loop, which does not work because it resets every cell too.

I hope someone knows a solution for this or can give me an idea where i mist out on something.

I am using this loop

for(int e = 0; e < modules.size(); e++)
    {
    gui.clearOutputStream();
    gui.getOutputStream().setText("Load Modul " + modules.get(e) + "\r\n");
    version = getVersion(modules.get(e));

    //Update current Row
    updateRow(gui.getReleaseTabelle(), e);
    }

which calls this method

public void updateRow(JTable target, int row){
//...
//insert Values here
//...
CustomRenderer cr = new CustomRenderer();
        cr.tab = target;
        if(!target.getValueAt(row, 2).equals(target.getValueAt(row, 3)))
        {
            cr.Val1 = target.getValueAt(row, 1).toString();
            target.setValueAt("X", row, 1);
        }
        else if(!target.getValueAt(row, 7).equals(""))
        {
            cr.Val1 = target.getValueAt(row, 1).toString();
            target.setValueAt("Y", row, 1);
        }
        else
        {

        }
        target.getColumnModel().getColumn(1).setCellRenderer(cr);

}

and this is my CustomRenderer

class CustomRenderer extends DefaultTableCellRenderer 
    {
private static final long serialVersionUID = 6703872492730589499L;
        public String Val1; 
        public JTable tab;

        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
        {
            Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

            if(tab.getValueAt(row, 1).equals("Y")){
                cell.setBackground(new java.awt.Color(255, 255, 0));
                tab.setValueAt(Val1, row, 1);
            }
            else if(tab.getValueAt(row, 1).equals("X")){
                cell.setBackground(new java.awt.Color(255, 50, 50));
                tab.setValueAt(Val1, row, 1);
            }
            else
            {
                //do nothing
            }
            return cell;
        }
    }
Amarnath
  • 8,736
  • 10
  • 54
  • 81
Steffen Riek
  • 61
  • 1
  • 1
  • 5
  • 1
    for better help sooner post an [SSCCE](http://sscce.org/), short, runnable, compilable – mKorbel Jan 28 '13 at 14:16
  • In your _CustomRenderer_ class _tab.setValueAt(Val1, row, 1);_ is there. Why is this statement required? You should use your _CustomRenderer_ class only for rendering colors. You are resetting something here in the _table_. May be that is the proble. – Amarnath Jan 28 '13 at 14:50
  • _however when the program reaches rows that are not displayed or if the user try's to scroll every cell changes its backgroundcolor back to white._ Some where you logic is wrong which is causing the problem. – Amarnath Jan 28 '13 at 14:53
  • **never-ever** change the table/model in a renderer – kleopatra Jan 28 '13 at 14:56
  • can i check the values of another cell from within the renderer? if so how do i do that? i believe the problem is that on a call of getTableCellRendererComponent without the variables i use the results of the if clauses would be false in every case. – Steffen Riek Jan 28 '13 at 15:06
  • 1
    okay i found a solution after you guys told me to not change anything on the table from within the renderer, that forced me to leave the values alone and check the other columns from within the renderer (which is totaly possible by table.getValueAt(row, column)), also i had to edit the last else to cell.setBackground(new java.awt.Colo(255, 255, 255)); instead of doing nothing. so my last asumption was right, but i would have never had the idea without your comments. thank you Che and kleopatra :) – Steffen Riek Jan 28 '13 at 15:44

1 Answers1

8

Do not update table data in your CutomRenderer class. You Renderer class should check the condition and color the cells. I have used your CustomRenderer class and rendered the cells basing on the data present in the cells. If the data of the cell is 'Y' color it to Yellow. If the data is 'N' then color it to Grey.

Rendering in JTable

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;


public class ColoringCells {

    private static Object[] columnName = {"Yes", "No"};
    private static Object[][] data = {
            {"Y", "N"},
            {"N", "Y"},
            {"Y", "N"}
    };


    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {

                JFrame frame = new JFrame();
                JTable table = new JTable(data, columnName);
                table.getColumnModel().getColumn(0).setCellRenderer(new CustomRenderer());
                table.getColumnModel().getColumn(1).setCellRenderer(new CustomRenderer());

                frame.add(new JScrollPane(table));
                frame.setTitle("Rendering in JTable");
                frame.pack();
                frame.setVisible(true);
            }
        };

        EventQueue.invokeLater(r);
    }
}


class CustomRenderer extends DefaultTableCellRenderer 
{
private static final long serialVersionUID = 6703872492730589499L;

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
    {
        Component cellComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

        if(table.getValueAt(row, column).equals("Y")){
            cellComponent.setBackground(Color.YELLOW);
        } else if(table.getValueAt(row, column).equals("N")){
            cellComponent.setBackground(Color.GRAY);
        }
        return cellComponent;
    }
}
Amarnath
  • 8,736
  • 10
  • 54
  • 81