Search code examples
javaswingjtable

Jtable cell selection and highlighting


I have an attached code, it working but with a little issue. I'm able to highlight a cell with blue color. What I want is after highlighting a single cell with a blue color I want to be able to un-highlight the same cell by clicking it again. For example when I highlight cell 1, it will be highlighted with blue but when I click it again it won't be un-highlighted unless I click another cell then click cell 1 again.

How can I fix this problem.

In the code I'm only testing cell 1 to 4.


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

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;

public class myJTable extends JFrame {

    Container container;
    JTable table;
    JScrollPane pane;
   
    static String oneSelected = "";
    static String twoSelected = "";
    static String threeSelected = "";
    static String fourSelected = "";
   
    int oneCount = 0;
    int twoCount = 0;
    int threeCount = 0;
    int fourCount = 0;
   
    public myJTable() {

        container = this.getContentPane();
        container.setLayout(new BorderLayout());

        String[] columnNames = {"No.1","No.2", "No.3", "No.4"};
        Object[][] rowData = {{"1", "2", "3", "4"},
            {"5", "6", "7", "8"},
            {"9", "10", "11", "12"},
            {"13", "14", "15", "16"},
            {"17", "18", "19", "20"}};

        table = new JTable(rowData, columnNames);
        table.setRowHeight(50);
        table.setDefaultRenderer(Object.class, new TableRenderer());
        table.setCellSelectionEnabled(true);
        pane = new JScrollPane(table);
        container.add(pane);
       
           table.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(final MouseEvent e) {
        if (e.getClickCount() == 1) {
        final JTable jTable= (JTable)e.getSource();
        final int row = jTable.getSelectedRow();
        final int column = jTable.getSelectedColumn();
        final String cellValue = (String)jTable.getValueAt(row, column);
        //textfield.setText(valueInCell);
       
        if (cellValue.equals("1") && oneCount == 0) {
        oneSelected  = cellValue;
        oneCount++;
        System.out.println("cell value is " +oneSelected);
        System.out.println("one count is " +oneCount);
        }
        else if (cellValue.equals("1") && oneCount >= 1) {
        oneSelected  = "";
        oneCount = 0;
        System.out.println("cell value is " +oneSelected);
        System.out.println("one count is " +oneCount);
        }
       
            if (cellValue.equals("2") && twoCount == 0) {
          twoSelected  = cellValue;
          twoCount++;
          System.out.println("cell value is " +twoSelected);
        }
            else if (cellValue.equals("2") && twoCount >= 1) {
        twoSelected  = "";
        twoCount = 0;
        System.out.println("cell value is " +twoSelected);
        System.out.println("two count is " +twoCount);
        }
           
            if (cellValue.equals("3") && threeCount == 0) {
          threeSelected  = cellValue;
          threeCount++;
          System.out.println("cell value is " +threeSelected);
           }
            else if (cellValue.equals("3") && threeCount >= 1) {
        threeSelected  = "";
        threeCount = 0;
        System.out.println("cell value is " +threeSelected);
        System.out.println("three count is " +threeCount);
        }
           
            if (cellValue.equals("4") && fourCount == 0) {
         fourSelected  = cellValue;
         fourCount++;
         System.out.println("cell value is " +fourSelected);
           }
            else if (cellValue.equals("4") && fourCount >= 1) {
        fourSelected  = "";
        fourCount = 0;
        System.out.println("cell value is " +fourSelected);
        System.out.println("four count is " +fourCount);
        }
        }
        }
        });
    }

    public static void main(String[] args) {
   
        myJTable frame = new myJTable();
        frame.setTitle("JTable Example");
        frame.setVisible(true);
        frame.setSize(700, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

class TableRenderer extends DefaultTableCellRenderer {

    @Override
   public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
   
    String oneSValue = myJTable.oneSelected;
    String twoSValue = myJTable.twoSelected;
    String threeSValue = myJTable.threeSelected;
    String fourSValue = myJTable.fourSelected;
       
    Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
       
        if (value.equals(oneSValue) || value.equals(twoSValue) || value.equals(threeSValue) || value.equals(fourSValue)) {
            c.setBackground(Color.BLUE);
            c.setForeground(Color.WHITE);
          }
        else {
        c.setBackground(Color.WHITE);
        c.setForeground(Color.BLACK);
        }
       
        return c;
       
    }
}
      

FIRST EDIT:

I've edited the code and used the boolean variable isSelected to print whether the cells boolean 2D array changes from false to true but does not change

class TableRenderer extends DefaultTableCellRenderer {

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

boolean cells[][] = new boolean [4][4];


Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

if(isSelected) {
if(cells[0][0] == false) {
System.out.println("cell 0 0 is " + cells[0][0]);
cells[0][0] = true;
}
else if(cells[0][0] == true) {
System.out.println("cell 0 0 is " + cells[0][0]);
}
}

return c;
}
}

Solution

  • In the example below the "state" of the highlight is contained in a 2D Array that has been added as data to the table by using a "client property".

    The MouseListener is used to toggle the highlighting state every time you click on a cell.

    The renderer will then query the highlighting state in order to paint the background.

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.table.*;
    import java.awt.event.*;
    
    public class TableHighlight extends JPanel
    {
        public TableHighlight()
        {
            setLayout( new BorderLayout() );
    
            JTable table = new JTable(4, 4);
            add( new JScrollPane( table ) );
    
            boolean[][] highlights = new boolean[4][4];
            table.setDefaultRenderer(Object.class, new TableRenderer());
            table.putClientProperty("highlights", highlights);
    
            table.addMouseListener(new MouseAdapter()
            {
                @Override
                public void mousePressed(final MouseEvent e)
                {
                    JTable table = (JTable)e.getSource();
                    int row = table.getSelectedRow();
                    int column = table.getSelectedColumn();
    
                    boolean[][] highlights = (boolean[][])table.getClientProperty("highlights");
                    highlights[row][column] = !highlights[row][column];
    
                    table.repaint();
                }
            });
        }
    
        private class TableRenderer extends DefaultTableCellRenderer
        {
            @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);
    
            boolean[][] highlights = (boolean[][])table.getClientProperty("highlights");
            boolean highlighted = highlights[row][column];
    
            if (highlighted)
                c.setBackground(Color.BLUE);
            else
                c.setBackground(Color.WHITE);
    
            return c;
        }
    }
    
        private static void createAndShowGUI()
        {
            JFrame frame = new JFrame("TableHighlight");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new TableHighlight());
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationByPlatform( true );
            frame.setVisible( true );
        }
    
        public static void main(String[] args) throws Exception
        {
            java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
        }
    }