How to permanently change the color of a selected row in a table in java

86 Views Asked by At

I would like to know how to add code in my action listener that would make the row I select or press on with my mouse change from the color red to the color white. I have tried getRowSelected() and tried to use the index but that ultimately only changes the row color when it is selected and it goes back to red. I have also attempted to user Renderer which is a newer concept to me but didn't know how to implement it the right way. Any help or guidance would be appreciated.

Tried getRowSelected() but the row color change was only temporary and went back to red once it was unselected. Tried Renderer but didn't know how to fully implement it as it is a new concept to me.

1

There are 1 best solutions below

6
Hovercraft Full Of Eels On

One way to do this is to:

  1. Create a JTable and table model with an invisible extra column, one that holds a boolean value, set to false initially. One way to make the column invisible is by removing the column from the JTable's TableColumnModel as suggested here by Swing expert Rob Camick and as per his previous answer to a Swing question on the topic.
  2. Create a table cell renderer that colors the background of a row based on the value of the boolean mentioned above
  3. Toggle the value of this boolean using either a mouse listener or a list selection listener.

For example:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.*;
import javax.swing.table.*;

public class TestTableRowColor {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            ChangeRowColorPanel mainPanel = new ChangeRowColorPanel();

            JFrame frame = new JFrame("GUI");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }

}
@SuppressWarnings("serial")
class ChangeRowColorPanel extends JPanel {
    private static final String[] COLUMN_NAMES = { "One", "Two", "Three", "Selected" };
    private DefaultTableModel model = new DefaultTableModel(COLUMN_NAMES, 0);
    private JTable table = new JTable(model);

    public ChangeRowColorPanel() {
        TableColumnModel columnModel = table.getColumnModel();
        columnModel.removeColumn(columnModel.getColumn(columnModel.getColumnCount() - 1));
        table.setDefaultRenderer(Object.class, new RowColorRenderer());
        table.addMouseListener(new MyMouse());

        int max = 5;
        for (int i = 0; i < max; i++) {
            Object[] row = new Object[COLUMN_NAMES.length];
            for (int j = 0; j < COLUMN_NAMES.length - 1; j++) {
                row[j] = (int) (100 * Math.random());
            }
            row[COLUMN_NAMES.length - 1] = false;
            model.addRow(row);
        }

        setLayout(new BorderLayout());
        add(new JScrollPane(table));
    }
}
class MyMouse extends MouseAdapter {
    @Override
    public void mousePressed(MouseEvent e) {
        JTable table = (JTable) e.getSource();
        TableModel model = table.getModel();
        boolean selected = (boolean) model.getValueAt(table.getSelectedRow(), model.getColumnCount() - 1);
        model.setValueAt(!selected, table.getSelectedRow(), model.getColumnCount() - 1);
        table.repaint();
    }
}
@SuppressWarnings("serial")
class RowColorRenderer extends DefaultTableCellRenderer {
    private static final Color SELECTED_COLOR = Color.PINK;

    public RowColorRenderer() {
        setOpaque(true);
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
            int row, int column) {
        Component renderer = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        TableModel model = table.getModel();
        int selectedColumn = model.getColumnCount() - 1;
        boolean selected = (boolean) model.getValueAt(row, selectedColumn);
        Color background = selected ? SELECTED_COLOR : null;
        renderer.setBackground(background);
        return this;
    }

}