Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JTable: Remove border around cell when clearing row selection

Tags:

java

swing

jtable

I have a JTable and want to allow deselecting all rows by clicking into an empty part of the table. This works fine so far. However, even though I call table.clearSelection(); the table still shows a border around the previously enabled cell (see cell 5 in the example):

Table deselection issue

I would like to get rid of this border as well (it looks especially out of place on the Mac's native look and feel, where the cells suddenly turn black).

Fully working minimal example code:

public class JTableDeselect extends JFrame {
    public JTableDeselect() {
        Object rowData[][] = { { "1", "2", "3" }, { "4", "5", "6" } };
        Object columnNames[] = { "One", "Two", "Three" };
        JTable table = new JTable(rowData, columnNames);
        table.setFillsViewportHeight(true);
        table.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (table.rowAtPoint(e.getPoint()) == -1) {
                    table.clearSelection();
                }
            }
        });
        add(new JScrollPane(table));
        setSize(300, 150);
    }
    public static void main(String args[]) throws Exception {
        UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
        new JTableDeselect().setVisible(true);
    }
}

[edit] Tried to add table.getColumnModel().getSelectionModel().clearSelection(); which was mentioned here around. But this does not help either.

like image 356
qqilihq Avatar asked Apr 16 '17 14:04

qqilihq


People also ask

How do you clear a JTable row?

We can remove a selected row from a JTable using the removeRow() method of the DefaultTableModel class.

How can I tell if a row is selected in JTable?

JTable has a getSelectionModel() method which will give you a ListSelectionModel object. It tells you what rows are selected. You can add a ListSelectionListener to that via the addL..S..


2 Answers

Your problem: your table cell still has focus even though the selection is lost and so it draws itself showing this by showing a thickened border. Knowing one possible solution is to create your own renderer that removes a cell's focus when the cell loses selection. For example:

table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
        if (!isSelected) {
            hasFocus = false;
        }
        return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    }
});
like image 120
Hovercraft Full Of Eels Avatar answered Oct 28 '22 13:10

Hovercraft Full Of Eels


Tried to add table.getColumnModel().getSelectionModel().clearSelection();

The table.clearSelection() method invokes that method and the clearSelection() method of the TableColumnModel.

In addition to clearing the selection you also need to reset the "anchor and lead" indexes of the selection model:

table.clearSelection();

ListSelectionModel selectionModel = table.getSelectionModel();
selectionModel.setAnchorSelectionIndex(-1);
selectionModel.setLeadSelectionIndex(-1);

TableColumnModel columnModel = table.getColumnModel();
columnModel.getSelectionModel().setAnchorSelectionIndex(-1);
columnModel.getSelectionModel().setLeadSelectionIndex(-1);

Now if you use the arrow keys the focus will go to (0, 0), so you do lose the information about the last cell that was clicked.

If you only clear the selection model, then you will lose the row information but the column information will remain.

Experiment with clearing one or both of the models to get the effect you desire.

like image 31
camickr Avatar answered Oct 28 '22 12:10

camickr