Question

I try to change the background color of each second row. The problem is that only first COLUMN is affected. Why?

    table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer()
    {
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
        {
            final Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            c.setBackground(row % 2 == 0 ? Color.LIGHT_GRAY : Color.WHITE);
            return c;
        }
    });
Was it helpful?

Solution 3

Okay, scrap all of what I just wrote.

Attempt #2:

table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        final Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        c.setBackground(row % 2 == 0 ? Color.LIGHT_GRAY : Color.WHITE);
        return this;
    }
});

You need to be returning the current object, not the reference of the super() call.

OTHER TIPS

Using the renderer approach you need to write a custom renderer for every data type in the table. So if you have String, Data, Integer, Boolean you would need to write 4 custom renderers.

See Table Row Rendering for an approach that will allow you to write the code once no matter haw many data types you have in the table. This approach overrides the preparerrenderer(...) method of the JTable.

As stated in Concepts: Editors and Renderers section of How to Use Tables tutorial, if you din not specify a renderer for a particular column then the table invokes the table model's getColumnClass method to get a default renderer for the column type.

If you have overridden getColumnClass method then your approach might not work as expected. For instance:

DefaultTableModel model = new DefaultTableModel(new Object[]{"Column # 1", "Column # 2"}, 0) {
    @Override
    public Class<?> getColumnClass(int columnIndex) {
        Class columnClass = Object.class;
        switch(columnIndex) {
            case 0: columnClass = String.class; break;
            case 1: columnClass = Boolean.class; break;
        }
        return columnClass;
    }
};

Then doing this:

table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {// your code here});

Won't work for the second column since the getColumnClass method will return Boolean.class and there's a default cell renderer for that class (JCheckBox).

In your case I would suggest you override JTable.prepareRenderer() method instead to set rows background color independently of the renderer type (JLabel, JCheckBox, or even custom renderers):

JTable table = new JTable(model) {
    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
        Component c = super.prepareRenderer(renderer, row, column);
        c.setBackground(row % 2 == 0 ? Color.LIGHT_GRAY : Color.WHITE);
        return c;
    }
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top