Search code examples
javaswingjtabletablecellrenderer

Java jTable color row on defined cell change


Hi all I am not finding what's incorrect about my code below. It populates the table and headers just fine. However, when I change row 1, colum 1 to test and click off it does not color the row like I was expecting. Then clicking off the one I clicked on turns green and anywhere I click on the table from then on just changes green.

The column won't change from 1 (Company) as that will be the default column which changes will be made. The row is the only dynamic number here.

The flow to test:

  • double-click IBM.
  • type in test.
  • click on any another cell in order to save that cell value.
  • the row does not change (row 1).
  • click on the test cell again.
  • all rows will change to the green color.

The Expected flow:

  • double-click IBM.
  • type in test.
  • click on any another cell in order to save that cell value.
  • the cell that was changed to test changes that row green.
  • click on Shares for cell (3, 3).
  • double-click and change 4000 to 1000.
  • click on any another cell in order to save that cell value.
  • the cell that was changed to 1000 changes that row red.

Populated the table and headers:

enter image description here

Clicking and changing the row 1, column 1 value to test:

enter image description here

Clicking off that cell onto another one after edit:

enter image description here

And now, click on any other cell (notice the test row is not green as it should be):

enter image description here

Now clicking on the cell I edited to test:

enter image description here

And you see above it's just coloring each row I click on regardless of the logic I said

if ("test".equals(type)) {....

The java code:

@SuppressWarnings("serial")
public class TableRowRenderingTip extends JPanel {
    public TableRowRenderingTip() {
        Object[] columnNames = {"Type", "Company", "Shares", "Price", "Boolean"};
        Object[][] data =
        {
            {"Buy", "IBM", new Integer(1000), new Double(80.5), Boolean.TRUE},
            {"Sell", "Dell", new Integer(2000), new Double(6.25), Boolean.FALSE},
            {"Short Sell", "Apple", new Integer(3000), new Double(7.35), Boolean.TRUE},
            {"Buy", "MicroSoft", new Integer(4000), new Double(27.50), Boolean.FALSE},
            {"Short Sell", "Cisco", new Integer(5000), new Double(20), Boolean.TRUE}
        };

        DefaultTableModel model = new DefaultTableModel(data, columnNames) {
            @SuppressWarnings({ "unchecked", "rawtypes" })
            public Class getColumnClass(int column) {
                return getValueAt(1, column).getClass();
            }
        };

        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.addTab("Border", createBorder(model));
        add(tabbedPane);
    }

    private JComponent createBorder(DefaultTableModel model) {
        JTable table = new JTable(model) {
            private Border outside      = new MatteBorder(1, 0, 1, 0, Color.RED);
            private Border _outside     = new MatteBorder(1, 0, 1, 0, Color.GREEN);
            private Border inside       = new EmptyBorder(0, 1, 0, 1);
            private Border highlight    = new CompoundBorder(outside, inside);
            private Border _highlight   = new CompoundBorder(_outside, inside);

            public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
                Component c = super.prepareRenderer(renderer, row, column);
                JComponent jc = (JComponent)c;
                String type = (String)getModel().getValueAt(convertRowIndexToModel(row), 1);

                if (isRowSelected(row)) {           
                    if ("test".equals(type)) {
                        jc.setBorder( _highlight ); // Green color
                        jc.setBackground(Color.GREEN);
                    } else {
                        jc.setBorder( highlight ); //Red color
                    }
                }

                return c;
            }
        };

        //table.setPreferredScrollableViewportSize(table.getPreferredSize());
        //table.changeSelection(0, 0, false, false);        
        return new JScrollPane( table );
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    public static void createAndShowGUI()
    {
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("Table Row Rendering");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new TableRowRenderingTip() );
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

So needless to say I am a little frustrated to say the lest since I've been working on this for a few hours now trying to find out what could be the issue.

I'm sure it will be something simple that I'm looking over...


Solution

  • You're forgetting to set the border and highlighting back to default if the test condition is not true. For example

    if (isRowSelected(row)) {
        if ("test".equals(type)) {
            jc.setBorder(_highlight); // Green color
            jc.setBackground(Color.GREEN);
        } else {
            jc.setBorder(highlight); // Red color
        }
    } else {
        jc.setBorder(null);
        jc.setBackground(null);
    }