2

So what I am trying to do, is to change the color of each row based on values inside of the last column.

I already found this solution: Change Background Color of JTable which worked very well.

But in addition I want to switch the color of the row to green when the fourth column reaches the same value as the second one.

I used the approach of Cristian Marian and wrote my own class

    @Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
    Component comp = super.prepareRenderer(renderer, row, column);


        int second = (int) this.getModel().getValueAt(row, 1);
        int forth = (int) this.getModel().getValueAt(row, 3);
        int kat = Kategorie.getNumber((String) this.getModel().getValueAt(row, 2)); 
        if (kat > 0) {
            if (second == forth) {
                comp.setBackground(Color.GREEN);
            } else {
                comp.setBackground(Color.RED);
            }
        }

    return comp;
}

Still only the last cell in each column changes to green instead of the whole one. But when I clock on the row, the whole row switches the color

The values in the last column are changed by another frame.

Table at the beginning: https://i.stack.imgur.com/qIIVf.jpg

When the value in the last column reaches the same value as in the second one it looks like this:

After reaching the given value: https://i.stack.imgur.com/pSzU7.jpg

Community
  • 1
  • 1
PlaZm0
  • 25
  • 1
  • 5
  • For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example) or [SSCCE](http://www.sscce.org/) (Short, Self Contained, Correct Example). – Andrew Thompson Jul 23 '15 at 11:16
  • Are you sure `table.getModel().getValueAt(row, 1) == table.getModel().getValueAt(row, 3)` are the same reference? why don't you use .equals for comparison? – Ezequiel Jul 23 '15 at 11:22
  • Now I am using `equals()`, but it does not change anything. Like I said, the last column of each row switches to green, so the statement should be true – PlaZm0 Jul 23 '15 at 11:28
  • how many columns you have? could you give us more details, screenshots,... – Ezequiel Jul 23 '15 at 11:32

2 Answers2

4

The problem with your approach is that you use getTableCellRendererComponent so only that cell will have its color changed.

I had to make something similar. Based on the value of a column, I had to color the row.

I used a class that extended the JTable and Override prepareRenderer

@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
    Component comp = super.prepareRenderer(renderer, row, column);
    if (populated) {  //this if was just to make sure that I have data in my table
        /*
        *This piece makes the code ignore the rows that are selected as this approach messes up that blue color that selected rows get
        */
        int[] rows = this.getSelectedRows();
        boolean rowisSelected = false;

        for (int rowIndex : rows) {
            if (row == rowIndex) {
                rowisSelected = true;
                break;
            }
        }
        /*
        *And this is the part that does the coloring
        */
        if (!rowisSelected) {
            Integer status = Integer.parseInt((String) 
            int modelRow = convertRowIndexToModel(row);
            this.getModel().getValueAt(modelRow, Constants.HIDDEN_COLUMN));
            switch (status) {
            case 1:
                comp.setForeground(Color.BLACK);
                comp.setBackground(Color.WHITE);
                break;
            case 2:
                comp.setForeground(Color.LIGHT_GRAY);
                comp.setBackground(Color.WHITE);
                break;
            case 3:
                comp.setForeground(Color.BLACK);
                comp.setBackground(Constants.DOWNLOADED_COLOR);
                break;
            case 4:
                comp.setForeground(Color.LIGHT_GRAY);
                comp.setBackground(Constants.DOWNLOADED_COLOR);
                break;
            }
        }
    }
    return comp;
}

Yours should be something like this (without the selected row thing):

@Override
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
    Component comp = super.prepareRenderer(renderer, row, column);
    int modelRow = convertRowIndexToModel(row);
    String second = this.getModel().getValueAt(modelRow, 1));
    String forth= this.getModel().getValueAt(modelRow, 3));
    if(second.equals(forth)){
        comp.setBackground(Color.GREEN);
    }
    return comp;
}
Bjorn
  • 28
  • 5
Cristian Marian
  • 750
  • 1
  • 8
  • 18
  • Thank you very much, I tested your approch. But still the last column switches the color only. When I click on the row the rest switches to green too – PlaZm0 Jul 23 '15 at 13:25
  • 2
    (1+), @PlaZm0, The selected row color should have priority over your custom row colors. When you click on a row it will be selected. When you edit the cell the value will change but the highlighting will not change until you select another row. Then all the cells in the previous row will be repainted based on your custom coloring and all the cells in the new row will be painted as selected. See [Table Row Rendering](https://tips4java.wordpress.com/2010/01/24/table-row-rendering/) for more examples. – camickr Jul 23 '15 at 14:31
  • Now I got it. Because I only change the last column the rest of the row doesn't get rendered. So only the last column changes it's color. The link helped a lot. Thank you sir! – PlaZm0 Jul 23 '15 at 14:41
  • @PlaZm0, when I first read your comment, I was a bit shocked, because I usually use the JTable only as an output component (I disable the editing) so I never had your problem with the rendering. But I see camickr has done a great job explaining what was going on. Thanks for that! – Cristian Marian Jul 23 '15 at 17:22
0

I have another solution to the problem above. In my case, I had a JTable containing 10 columns. I only wished to highlight a certain subset of cell rows based on a Mark entered. In the example screenshot appended below I entered the Mark 167 and pressed the Find All button. In so doing, the cell renderer highlighted a subset of cells. Namely, the Script No, Candidate, Mark and Gradeenter image description here In order to achieve this, I created a cell renderer to extend the DefaultCellRenderer. I've taken out some code that is unrelated to the problem and so it may not compile. Nonetheless, you get an overview of the solution to your problem:


import java.awt.Component;
import java.awt.Color;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

/*
 *
 * This class is the Color Renderer for the "Find All" Button.
 * It basically highlights all of the scripts with a certain color
 * This renderer is responsible Highlighting the JTable.
 * Based on the particular Mark that has been entered in the find all   
 * text field
 *
 *
 */

public class MarkSearchColorCellRenderer extends DefaultTableCellRenderer     
  implements ColorCellRenderer, GradeValidation
{
   public MarkSearchColorCellRenderer(int aMark, Color aColor)
   {
    the_Mark = aMark;
    theColor = aColor;
    }
    @Override
    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);

        setHorizontalAlignment(RIGHT);


        if ( column == 0 ) // script no column
        {
            //check the current Mark within this row
            //i.e. for this particular candidate
            Object curMark =  table.getValueAt(row, column+2);

            //highlight this cell a certain color if the
            //search mark has been found for this particular candidate
            highlightScripts(curMark, cell);
        }
        else if(column == 1) // Candidate No. Column
        {
            Object curMark =  table.getValueAt(row, column+1);

            highlightScripts(curMark, cell);
        }
        else if ( column == 2 ) // mark column
        {
             Object curMark = value;

             highlightScripts(curMark, cell);
        }
        else if (column == 3) // Grade Column
        {
             setHorizontalAlignment(LEFT);

             Object curMark =  table.getValueAt(row, column-1);

             highlightScripts(curMark, cell);
        }
        else if (column == 5) // script no column
        {
            Object curMark =  table.getValueAt(row, column+2);

            highlightScripts(curMark, cell);

        }
        else if( column == 6) // Candidate No. Column
        {
           Object curMark =  table.getValueAt(row, column+1);

           highlightScripts(curMark, cell);
        }
        else if ( column == 7) // mark column
        {
            Object curMark = value;

            highlightScripts(curMark, cell);

         }
         else if ( column == 8) // Grade Column
         {
            setHorizontalAlignment(LEFT);

             Object curMark =  table.getValueAt(row, column-1);

             highlightScripts(curMark, cell);

         }
         else
         {
             // Should never arrive here.
             // If it does, then you've rendered a column that may not
             // function with this class
             // therefore, I'm going to exit the program

              //System.exit(0);
         }

         table.repaint();

         return cell;

     } // end getTableCellRendererComponent()

     // Change the color of this cell if the aValue matches
     // the value within the particular cell
     private void highlightScripts(Object aValue, Component aCell)
     {
         Object value = aValue;
         Component cell = aCell;

         if ( value != null )
         {
             if (value instanceof Integer )
             {
                Integer amount = (Integer) value;

                if( amount.intValue() == the_Mark )
                {
                    cell.setBackground( theColor );

                 }
                 else
                 {
                     cell.setBackground( Color.white );

                 }
             }
         }
         else
         {
            cell.setBackground( Color.white );
         }
      }// end highlightScripts()

}//end class

/* * * Inside the "Find All" button listener you would attach the * MarkSearchColorCellRenderer to selected JTable columns. * A snippet of the code is as follows: * */ // select a color Color myMarkColor = new Color(226,182,90); // the mark to search Integer markToSearch = new Integer(find_mark_jTextField.getText()); //an instance of the class MarkSearchColorCellRenderer (outlined above) MarkSearchColorCellRenderer my_MarkSearch_CellRenderer = new MarkSearchColorCellRenderer( markToSearch.intValue(),myMarkColor); /* * * Get the all the Table columns of the JTable on which you wish to assign * the particular cell renderer. In my example I have 8 table column's * that I wish to assign the cell renderer * i.e. Script, Candidate, Mark, Grade Script, Candidate, Mark, Grade * * On looking at the screenshot I've ignored the monitor column (check box) */ TableColumn script_column_100_A = first_100_Table.getColumnModel().getColumn(0); TableColumn candidate_column_100_A = first_100_Table.getColumnModel().getColumn(1); TableColumn mark_column_100_A = first_100_Table.getColumnModel().getColumn(2); TableColumn grade_column_100_A = first_100_Table.getColumnModel().getColumn(3); TableColumn script_column_100_B = first_100_Table.getColumnModel().getColumn(5); TableColumn candidate_column_100_B = first_100_Table.getColumnModel().getColumn(6); TableColumn mark_column_100_B = first_100_Table.getColumnModel().getColumn(7); TableColumn grade_column_100_B = first_100_Table.getColumnModel().getColumn(8); /* * * assign the MarkSearchColorCellRenderer to each of the choosen table column's. * * i.e. Script, Candidate, Mark, Grade Script, Candidate, Mark, Grade * */ script_column_100_A.setCellRenderer(my_MarkSearch_CellRenderer ); script_column_100_A.setCellRenderer(my_MarkSearch_CellRenderer ); candidate_column_100_A.setCellRenderer(my_MarkSearch_CellRenderer ); mark_column_100_A.setCellRenderer(my_MarkSearch_CellRenderer ); grade_column_100_A.setCellRenderer(my_MarkSearch_CellRenderer ); script_column_100_B.setCellRenderer(my_MarkSearch_CellRenderer ); candidate_column_100_B.setCellRenderer(my_MarkSearch_CellRenderer ); mark_column_100_B.setCellRenderer(my_MarkSearch_CellRenderer ); grade_column_100_B.setCellRenderer(my_MarkSearch_CellRenderer ); this.repaint();