-2

I know there are previous topics for a similar problem but even with it I wasn't able to resolve my problem.

So the thing is, when I add a new empty row to my JTable I want to highlight it in gray. So it works for the first one but when I try to add a second row, the second will be white...

I tried to debbug but without success, I didn't find my mistake.

Here is the class to highlight a row :

class GrayWhiteRenderer extends DefaultTableCellRenderer {

    private int rowToColored;

    GrayWhiteRenderer(int rowToColored) {
        this.rowToColored = rowToColored;
        Color color = UIManager.getColor ( "table.row" );
    }
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            if (UIManager.getColor ( "table.row" )==Color.GRAY) {
                c.setBackground(Color.GRAY.brighter());
            }
            else if(row == rowToColored) {
                c.setBackground(Color.GRAY.brighter());
            } else {
                c.setBackground(Color.WHITE);
            }
        return c;
    }
}

I store the index of all new row in rowToAdd at the begining of it (for exemple : [19, 20, 21, -1, -1, ...]. -1 is to know when I have to stop looking if I have to highlight more) :

while(rowToAdd[k]!=-1) {
    System.out.println("rowToAdd[k] : "+rowToAdd[k]);
    dataTable.setDefaultRenderer(Object.class, new GrayWhiteRenderer(rowToAdd[k]));
    k++;
}

And here is a class to test it :

package Graphic;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

class Test implements Runnable, ActionListener {

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

    JTable table;

    @Override
    public void run() {
        JFrame frame = new JFrame("Custom Cell Renderer");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        table = new JTable(new DefaultTableModel(0, 2) {
            @Override
            public Class<?> getColumnClass(int c) {
                return Object.class;
            }
        });

        class GrayWhiteRenderer extends DefaultTableCellRenderer {
            private int rowToColored;
            GrayWhiteRenderer(int rowToColored) {
                this.rowToColored = rowToColored;
            }
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                if (UIManager.getColor ( "table.row" )==Color.GRAY) {
                    c.setBackground(Color.GRAY.brighter());
                }
                else if(row == rowToColored) {
                    c.setBackground(Color.GRAY.brighter());
                } else {
                    c.setBackground(Color.WHITE);
                }
                return c;
            }
        }

        table.setDefaultRenderer(Object.class, new GrayWhiteRenderer(table.getRowCount()));
        table.setTableHeader(null);

        JButton btn = new JButton("Add Row");
        btn.addActionListener(this);

        JToolBar bar = new JToolBar();
        bar.setFloatable(false);
        bar.add(btn);

        JPanel content = new JPanel(new BorderLayout());
        content.add(bar, BorderLayout.NORTH);
        content.add(new JScrollPane(table), BorderLayout.CENTER);

        frame.setContentPane(content);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        int nextRow = table.getRowCount();
        DefaultTableModel model = (DefaultTableModel)table.getModel();
        model.addRow(new Object[] { "" + nextRow, "" + nextRow });
        for(int i=0; i<model.getColumnCount(); i++) {
            table.setDefaultRenderer(Object.class, new GrayWhiteRenderer(i));
        }
    }

}
  • Please provide a [mcve] so we can also reproduce your problem. The code, you've posted here, give me no hint about the cause of your problem. – Sergiy Medvynskyy May 28 '18 at 09:38
  • *"I know there are previous topics for a similar problem but even with it I wasn't able to resolve my problem."* List the most helpful 3 & explain why they didn't help. Your report is typical of people who have done 0 research but know that it is expected. – Andrew Thompson May 28 '18 at 09:56
  • Sorry if you think I have done my research, I will list the topics then. And even if I could resolve my problems with it, I would always want to understand where is my mistake to improve myself –  May 28 '18 at 10:01
  • *"Sorry if you think.."* Tip: Add @SergiyMedvynskyy (or whoever, the `@` is important) to *notify* the person of a new comment. (I realise you were replying to me, but thought I'd give you the ti[ for future reference.) *"I will list the topics then"* Let me know when done. – Andrew Thompson May 28 '18 at 11:06
  • @AndrewThompson here are some topics : [link](https://stackoverflow.com/questions/11872003/highlighting-specific-rows-in-a-jtable?s=1|130.6225) , [link](https://stackoverflow.com/questions/13098846/how-to-color-specific-rows-in-a-jtable) –  May 28 '18 at 12:02

1 Answers1

0

So, I've fixed your example. Here is your code with my comments

@Override
public void actionPerformed(ActionEvent ae) {
    int nextRow = table.getRowCount();
    DefaultTableModel model = (DefaultTableModel) table.getModel();
    model.addRow(new Object[] {"" + nextRow, "" + nextRow});
    // the correct row is: nextRow. No loop required here.
    table.setDefaultRenderer(Object.class, new GrayWhiteRenderer(nextRow));
}

I would also correct your renderer to provide selection highlight

class GrayWhiteRenderer extends DefaultTableCellRenderer {
    private int rowToColored;

    GrayWhiteRenderer(int rowToColored) {
        this.rowToColored = rowToColored;
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
            int column) {
        Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        // As I know there is no value is registered for "table.row" in UIManager
        // so I've skipped the first condition
        if (row == rowToColored) {
            c.setBackground(Color.GRAY.brighter());
        } else {
            // use correct color depended on whether the cell is selected or not!
            c.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
        }
        return c;
    }
}
Sergiy Medvynskyy
  • 11,160
  • 1
  • 32
  • 48
  • I thought it was necessary to use a loop. The second part is to clear to me now thanks to you. –  May 28 '18 at 12:06
  • @Corentin lifehack: if you accept my answer as correct (checkbox left to my answer) you'll get 2 reputation points ;) – Sergiy Medvynskyy May 28 '18 at 12:23