Question

I've been looking around for a solution to this and I can't make head nor tail from various places of how to get my table to do coloured rows without asking my own question.

From every place I've looked I gather I need to use a cell renderer but the problem is I don't know how to apply it to my own situation.

So I have a simple JTable with 3 columns and I simply want each row to be highlighted in either green, yellow or red depending on the value of a separate variable (not displayed in the table).

It seems like it should be really simple but I can't get how to do it. If it helps my table is defined like:

studentTableModel = new DefaultTableModel(new Object[]{"Name", "StudentNo", "Part"}, 0);
jt_studentTable = new JTable(studentTableModel);
jt_studentTable.getColumnModel().getColumn(2).setPreferredWidth(10);
studentTableModel.addRow(new Object[]{"(empty)", "(empty)", "(empty)"});
JScrollPane jsp_tableScroller = new JScrollPane(jt_studentTable);
jsp_tableScroller.setPreferredSize(new Dimension(200,190));
middleCentrePanel.add(jsp_tableScroller);

The rows in the table change depending of the selection of a combo box.

Thanks in advance.

Was it helpful?

Solution

JTable Cell Coloring

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 RowRendering {

    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(row == 0){
            cellComponent.setBackground(Color.YELLOW);
        } else if ( row == 1){
            cellComponent.setBackground(Color.GRAY);
        } else {
            cellComponent.setBackground(Color.CYAN);
        }
        return cellComponent;
    }
}

OTHER TIPS

I simply want each row to be highlighted in either green, yellow or red depending on the value of a separate variable (not displayed in the table).

Renderers work on data in the table. That is components can only paint themselves when they have all the information needed to do the job.

So somehow you need to add the information to the table. This might be done be adding a 4th column that is hidden. Then the table still has access to the information required.

Then maybe you can use the suggestion in Table Row Renderering.

Maybe this works for you:

class MyCellRenderer extends DefaultTableCellRenderer {
     String separatedVariable;
     public MyCellRenderer(String separatedVariable) {
         this.separatedVariable = separatedVariable;
      }

      @Override
      public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
          Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
          c.setBackground(Color.WHITE);
          c.setForeground(Color.BLACK);
              JLabel l = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col);
          if (separatedVariable.equals("YOUR VALUE TO GREEN")) {
              l.setBackground(Color.GREEN);

              return l;
          } else {
                     if (separatedValue.equals("YOUR VALUE TO YELLOW")) {
                          l.setBackground(Color.YELLOW);
                          return l;
                      } else if (separatedValue.equals("YOUR VALUE TO RED")) {
                          l.setBaground(Color.RED);
                          return l;
                      }
               }
              return c;
      }
}

I just had this same question, but a bit more complicated, since I already had several different renderers for each column, depending on the datatype.

But I found that this works like a charm:

public class MyTable extends JTable {
    @Override
    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
        Component result = super.prepareRenderer(renderer, row, column);

        if (mustBeYellow(row, column)) {
            result.setBackground(Color.yellow);
        }

        return result;
    }

    private boolean mustBeYellow(int row, int column) {
        // implement this depending on your data..
        return false;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top