I have a JTable with a checkbox as one of the columns. I also have a checkbox in the title to check / unmark all. AFAIK default behavior JTable by default deselects all selected rows if you select a new row. But can we reach CTRL click like behavior with a checkbox? This saves the previously selected row. The main problem I am facing is to enable multiple selection of JTable strings with a checkbox.
Expected Result
The 1st row is checked, then the first row is selected, and if the third row is checked, then the third row is selected along with the first row (which has already been checked and selected)
Actual output
When the first row is checked and selected, and if you select the third row, it deselects all previously selected rows and only the third is selected.
I have an example code that simulates a script that I want to achieve in the same way as the Add Another One button, but with a checkbox selected.
import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.table.AbstractTableModel; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.event.ListSelectionListener; import javax.swing.table.TableColumn; import javax.swing.event.CellEditorListener; public class JTableRowSelectProgramatically extends JPanel { final JTable table = new JTable(new MyTableModel()); public JTableRowSelectProgramatically() { initializePanel(); } private void initializePanel() { setLayout(new BorderLayout()); setPreferredSize(new Dimension(475, 150)); table.setFillsViewportHeight(true); JScrollPane pane = new JScrollPane(table); JLabel label2 = new JLabel("Row: "); final JTextField field2 = new JTextField(3); JButton add = new JButton("Select"); table.setRowSelectionAllowed(true); table.setColumnSelectionAllowed(false); table.getSelectionModel().addListSelectionListener(new ListSelectionListenerImpl()); TableColumn tc = table.getColumnModel().getColumn(3); tc.setCellEditor(table.getDefaultEditor(Boolean.class)); tc.setCellRenderer(table.getDefaultRenderer(Boolean.class)); ((JComponent) table.getDefaultRenderer(Boolean.class)).setOpaque(true); tc.getCellEditor().addCellEditorListener(new CellEditorListenerImpl()); add.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { int index2 = 0; try { index2 = Integer.valueOf(field2.getText()); } catch (NumberFormatException e) { e.printStackTrace(); } table.addRowSelectionInterval(index2, index2); field2.setText(String.valueOf(index2)); } }); JPanel command = new JPanel(new FlowLayout()); command.add(label2); command.add(field2); command.add(add); add(pane, BorderLayout.CENTER); add(command, BorderLayout.SOUTH); } public static void showFrame() { JPanel panel = new JTableRowSelectProgramatically(); panel.setOpaque(true); JFrame frame = new JFrame("JTable Row Selection"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setContentPane(panel); frame.pack(); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { JTableRowSelectProgramatically.showFrame(); } }); } public class MyTableModel extends AbstractTableModel { private String[] columns = {"ID", "NAME", "AGE", "A STUDENT?"}; private Object[][] data = { {1, "Alice", 20, new Boolean(false)}, {2, "Bob", 10, new Boolean(false)}, {3, "Carol", 15, new Boolean(false)}, {4, "Mallory", 25, new Boolean(false)} }; public int getRowCount() { return data.length; } public int getColumnCount() { return columns.length; } public Object getValueAt(int rowIndex, int columnIndex) { return data[rowIndex][columnIndex]; } @Override public String getColumnName(int column) { return columns[column]; } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { return columnIndex == 3; }