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

Time:12-04

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. Below is my code:

import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.*;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class CustomerNotif extends JFrame {
    private static final long serialVersionUID = 1L;
    private JPanel contentPane;
    private JTable table;
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    CustomerNotif frame = new CustomerNotif();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    public CustomerNotif() {
        setTitle("Notifications");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(650, 10, 623, 235);
        contentPane = new JPanel();
        contentPane.setBackground(new Color(0, 128, 128));
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

        setContentPane(contentPane);
        contentPane.setLayout(null);
        
        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setBounds(0, 0, 614, 205);
        contentPane.add(scrollPane);
        
        table = new JTable();
        table.setBackground(new Color(231, 20, 63));
        table.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                int row = table.getSelectedRow();
                
                
            }
        });
        table.setFont(new Font("SansSerif", Font.PLAIN, 14));
        table.setModel(new DefaultTableModel(
            new Object[][] {
                {null, null, null},
            },
            new String[] {
                "Account Number", "Request", "Status"
            }
        ));
        table.getColumnModel().getColumn(2).setPreferredWidth(78);
        scrollPane.setViewportView(table);
        
    }

}

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.

CodePudding user response:

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 by setting its max and min width to 0.
  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.getColumn(COLUMN_NAMES.length - 1).setMinWidth(0);
        columnModel.getColumn(COLUMN_NAMES.length - 1).setMaxWidth(0);
        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();
        
        // get value from invisible column
        boolean selected = (boolean) table.getValueAt(table.getSelectedRow(), table.getColumnCount() - 1);
        
        // then toggle its value: !selected and set the cell with it
        table.setValueAt(!selected, table.getSelectedRow(), table.getColumnCount() - 1);
        
        // repaint the table so that the whole row is painted, not just this cell
        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);
        int selectionColumn = table.getModel().getColumnCount() - 1;
        
        // get invisible column's boolean value for this row
        boolean selected = (boolean) table.getValueAt(row, selectionColumn);
        
        // set row background color based on this value
        Color background = selected ? SELECTED_COLOR : null;
        renderer.setBackground(background);
        return this;
    } 
    
}

CodePudding user response:

To change the color of a selected row in a table in Java, you can use a custom cell renderer to set the color of each cell in the row depending on whether it is selected or not.

Here is an example of how you could implement this in your code:

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

public class CustomerNotif extends JFrame {
    private static final long serialVersionUID = 1L;
    private JTable table;
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    CustomerNotif frame = new CustomerNotif();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    public CustomerNotif() {
        // Set up the frame and other UI components here...

        // Create a custom cell renderer that sets the cell color based on whether the row is selected
        DefaultTableCellRenderer cellRenderer = new DefaultTableCellRenderer() {
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                // Set the default cell color to white
                setBackground(Color.WHITE);

                // If the row is selected, set the cell color to red
                if (isSelected) {
                    setBackground(Color.RED);
                }

                // Return the configured renderer
                return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            }
        };

        // Set the cell renderer for each column in the table
        for (int i = 0; i < table.getColumnCount(); i  ) {
            table.getColumnModel().getColumn(i).setCellRenderer(cellRenderer);
        }
    }
}

In this example, we create a custom DefaultTableCellRenderer that sets the background color of each cell in the table depending on whether the row is selected or not. The renderer sets the background color to white for unselected rows, and to red for selected rows.

To use this renderer, we iterate through each column in the table and set the cell renderer for each column to the custom renderer we just created. This will cause the custom renderer to be used to render the cells in each column, and the selected rows will be colored red.

I hope this helps! Let me know if you have any questions.

  • Related