Search code examples
javaswingjtablecellhighlight

highlight the cell in jtable


I have this code fom stackoverflow how to highlight multiple cells in jtable :

private static class CellHighlighterRenderer extends JLabel implements TableCellRenderer {

    public CellHighlighterRenderer() {
        setOpaque(true); // Or color won't be displayed!
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        String val = (String)value;
        Color c;
        if (val.matches(".*MIN.*")) // Add a method to configure the regexpr
            c = Color.YELLOW; // Add a method to configure color
        else
            c = UIManager.getColor("Table.background");
        setBackground(c);
        setText(val);
        return this;
    }
}

But when i use it for highlighting a cell , it gives wrong action like the whole data gets lost . Iam new to java swing. Please help to make a cell gets highlighted on a button press action event.
UPDATE: adding my sample code:

package myPackage;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

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

public class JTableCreatingDemo {
    public static void main(String args[]) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Object rowData[][] = { { "Row1-Column1"},
        { "Row2-Column1" } ,{ "Row3-Column1"},{ "Row4-Column1"},};
    Object columnNames[] = { "Column One" };
    final JTable table = new JTable(rowData, columnNames);
    JButton button = new JButton("Highlight cell-1");
    //Add action listener to button
    button.addActionListener(new ActionListener() {

            @Override
        public void actionPerformed(ActionEvent arg0) {
         table.setDefaultRenderer(Object.class, new CellHighlighterRenderer()); 
        }
    });    
    JPanel pnl = new JPanel();
    pnl.add(button);
    JScrollPane scrollPane = new JScrollPane(table);
    frame.add(scrollPane, BorderLayout.CENTER);
    frame.add(pnl,BorderLayout.SOUTH);
    frame.setSize(300, 150);
    frame.setVisible(true);

  }
}

class CellHighlighterRenderer extends JLabel implements TableCellRenderer {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public CellHighlighterRenderer() {
        setOpaque(true); // Or color won't be displayed!
    }

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        String val = (String)value;
        Color c;
        if (isSelected) // Add a method to configure the regexpr
            c = Color.YELLOW; // Add a method to configure color
        else
            c = UIManager.getColor("Table.background");
        setBackground(c);
        setText(val);
        return this;
    }
}

What i want is on clicking the button i want to highlight just the cell number-1 (Row1-Column1).


Solution

  • I use this class to style JTables

    public class CellRenderer extends DefaultTableCellRenderer {
    
    @Override
    public Component getTableCellRendererComponent(JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int column) {
        Component cell = super.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, column);
    
        if (isSelected)
            cell.setBackground(Color.YELLOW);
        else if (column == 0)
            cell.setBackground(new Color(0xDDDDD));
        else 
            cell.setBackground(new Color(0xFFFFFF));
    
        return cell;
    }
    

    create an instance of this class and apply it to the cells that you need to style. You can use the isSelected parameter to edit the cell highlight color.

    EDIT

    Thanks for your updated example, here is an example of a toggle button to change the cell renderer

    First create a color style for the cell using a default table cell renderer

    public class CellHighlighterRenderer extends DefaultTableCellRenderer {
    
    @Override
    public Component getTableCellRendererComponent(JTable table, Object obj,
            boolean isSelected, boolean hasFocus, int row, int column) {
    
        Component cell = super.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, column);
    
        cell.setBackground(Color.YELLOW);
    
        return cell;
    }
    

    Create your JFrame and add the JTable and button

    public class Main extends JFrame {
    
    public Main() {
        super("Table Demo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(300, 300));
        setLocationRelativeTo(null);
        setLayout(new BorderLayout());
    
        DefaultTableModel model = new DefaultTableModel();
        model.setColumnCount(5);
        model.setRowCount(5);
    
        JTable table = new JTable();
        table.setModel(model);
    
        //Get an instance of the column and the style to apply and hold a default style instance
        final TableColumn column = table.getColumnModel().getColumn(1);
        final CellHighlighterRenderer cellRenderer = new CellHighlighterRenderer();
        final TableCellRenderer defaultRenderer = column.getCellRenderer();
    
        //Now in your button listener you can toggle between the styles 
        JButton button = new JButton("Click!");
        button.addActionListener(new ActionListener() {
            private boolean clicked = false;
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
                if (clicked) {
                    column.setCellRenderer(cellRenderer);
                    clicked = false;
                } else {
                    column.setCellRenderer(defaultRenderer);
                    clicked = true;
                }
                repaint(); //edit
            }
        });
    
        getContentPane().add(table, BorderLayout.CENTER);
        getContentPane().add(button, BorderLayout.NORTH);
        pack();
        setVisible(true);
    }
    
    public static void main(String[] args) {
         new Main();
    }
    

    Hope this helps

    EDIT I added a repaint to clean up the last example. If you only want to target a specific cell change the table cell renderer to only render the cell you need like this

        @Override
    public Component getTableCellRendererComponent(JTable table, Object obj,
            boolean isSelected, boolean hasFocus, int row, int column) {
    
        Component cell = super.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, column);
    
        //add condition for desired cell
        if (row == 1 && column == 1)
            cell.setBackground(Color.YELLOW);
    
        return cell;
    }