Search code examples
javaswingjtabletablecellrenderer

How to change the color of a JTable entire row having a particular column value


I have a Jtable which gets populated from an array of values. My code is like this:

  private static final String[] columnNames = {"Line Number", "Error","Fix Proposed","Percentage (%)"};
  static DefaultTableModel model = new DefaultTableModel(null,columnNames);

  public static void DisplayMyJList(List<CaptureErrors> x,String extension,
        ArrayList<Integer> l,ArrayList<Integer> p,
        ArrayList<String> e,ArrayList<String> s) throws IOException {//Method to Dynamic get values to be populated in Jtable.

    String theExtension = extension;
    if(FILE_EXTENSION.equals("java")) {
        for(CaptureErrors ex: x) {

            Vector row = new Vector();
            row.add(ex.getLinenumber());
            row.add(ex.getMyfounderror());
            row.add(ex.getMycorrection());
            row.add(ex.getMyPercentage()+"%");

            model.addRow( row );

            //model.setRowColour(1, Color.YELLOW);
        }
    }

table = new JTable(model);
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);    
    table.setFillsViewportHeight(true);
    table.setShowGrid(true);
    table.setShowVerticalLines(true);
    table.setGridColor(new Color(0,128,0));
    JTableHeader header = table.getTableHeader();
    table.setBackground(new Color(255,228,225));
    table.setEnabled(true);
    header.setFont(new Font("Dialog", Font.CENTER_BASELINE, 12));
    header.setBackground(Color.black);
    header.setForeground(Color.yellow);
    JScrollPane pane4 = new JScrollPane(table); 

I can populate the Jtable from the array of values by Using a JButton. I want to have a condition where if column "percentage" ,get all values in this column >30, it highlights the rows to color.red.

I dont want to user TableCellRendererComponent .I want this action to be performed upon clicking the Jbutton.

The actual Jtable looks like this: enter image description here

Then according to what I want to get, the first 2 rows should be highlighted in red. Any help appreciated.


Solution

  • One of the problems with the render API is that it's difficult to provide compound renderers. There are ways to do, don't get me wrong, but it would have been nice to have it built in...[end rant]...

    The basic idea is you you want to set up a series of renderers that extend from a base renderer which contains the logic required to determine what it should do under the required conditions.

    public class FilterRenderer extends DefaultTableCellRenderer {
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
            Double percent = (Double) table.getValueAt(row, 3);
            // You'll need some way to supply the filter value, may via a centralised 
            // manager of some kind.
            if (percent > 0.3 && !isSelected) {
                setOpaque(true);
                setBackground(Color.RED);
            } else {
                setOpaque(false);
            }
            return this;
        }
    }
    
    public class OtherCellRenderer extends FilterRenderer {
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
            // Apply any special renderer requirements, like translating an object value to String
            return this;
        }
    }
    

    You'll need a custom renderer for each column (from you example, that's 4) and apply each to the table column

    TableColumnModel model = table.getColumnModel();
    model.getColumn(0).setCellRenderer(new LineNumberRenderer());
    model.getColumn(1).setCellRenderer(new ErrorRenederer());
    model.getColumn(2).setCellRenderer(new FixProposedRenderer());
    model.getColumn(3).setCellRenderer(new Percentage());
    

    Or you could just use SwingLabs JXTable which has inbuilt support for row highlighters