Multiple row selection in JTable

后端 未结 4 1759
余生分开走
余生分开走 2020-11-22 07:53

I have a JTable, that has one column that is text which is not editable and the second column is a check box that displays boolean values.... Now what i want is, when the us

相关标签:
4条回答
  • 2020-11-22 08:16

    You can get the selection interval with code similar to this:

    table.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
        public void valueChanged(ListSelectionEvent e) {
            minSelectedRow = ((DefaultListSelectionModel)e.getSource()).getMinSelectionIndex();
            maxSelectedRow = ((DefaultListSelectionModel)e.getSource()).getMaxSelectionIndex();
        }
    });
    

    Then, when one checkbox is checked (listen to ItemEvent) you should iterate from the minSelectedRow to the maxSelectedRow and change checked boxes state. That's it.

    0 讨论(0)
  • 2020-11-22 08:21

    I agree with Roman that his idea would work if you use a class field to hold the min and max selection. For instance:

    import javax.swing.*;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.DefaultTableModel;
    
    public class CheckABunch extends JPanel {
        private static final Object[][] DATA = {{"One", Boolean.TRUE}, {"Two", Boolean.FALSE},
            {"Three", Boolean.TRUE}, {"Four", Boolean.FALSE}, {"Five", Boolean.TRUE},
            {"Six", Boolean.FALSE}, {"Seven", Boolean.TRUE}, {"Eight", Boolean.FALSE}};
        private static final String[] COLUMNS = {"Number", "CheckBox"};
        private DefaultTableModel model = new DefaultTableModel(DATA, COLUMNS) {
            @Override
            public Class<?> getColumnClass(int columnIndex) {
                if (columnIndex == 1) {
                    return getValueAt(0, 1).getClass();
                }
                return super.getColumnClass(columnIndex);
            }
        };
        private JTable table = new JTable(model);
        private int minSelectedRow = -1;
        private int maxSelectedRow = -1;
        boolean tableModelListenerIsChanging = false;
    
        public CheckABunch() {
            add(new JScrollPane(table));
    
            table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
                public void valueChanged(ListSelectionEvent e) {
                    if (e.getValueIsAdjusting()) {
                        return;
                    }
                    minSelectedRow = ((DefaultListSelectionModel) e.getSource()).getMinSelectionIndex();
                    maxSelectedRow = ((DefaultListSelectionModel) e.getSource()).getMaxSelectionIndex();
                }
            });
    
            model.addTableModelListener(new TableModelListener() {
                public void tableChanged(TableModelEvent e) {
                    if (tableModelListenerIsChanging) {
                        return;
                    }                
                    int firstRow = e.getFirstRow();
                    int column = e.getColumn();
    
                    if (column != 1 || maxSelectedRow == -1 || minSelectedRow == -1) {
                        return;
                    }
                    tableModelListenerIsChanging = true;
                    boolean value = ((Boolean)model.getValueAt(firstRow, column)).booleanValue();
                    for (int i = minSelectedRow; i <= maxSelectedRow; i++) {
                        model.setValueAt(Boolean.valueOf(value), i, column);
                    }
    
                    // *** edit: added two lines
                    minSelectedRow = -1;
                    maxSelectedRow = -1;
    
                    tableModelListenerIsChanging = false;
                }
            });
        }
    
        private static void createAndShowUI() {
            JFrame frame = new JFrame("CheckABunch");
            frame.getContentPane().add(new CheckABunch());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    createAndShowUI();
                }
            });
        }
    }
    
    0 讨论(0)
  • 2020-11-22 08:22

    The problem is that when you click on a check box to change the value of the check box, the selection of all the rows will be lost. So you may need to use a right mouse click to display a popup menu that contains select/deselect values.

    Then you can use table.getSelectedRows(), to get the indexes of all the selected rows you need to update.

    0 讨论(0)
  • 2020-11-22 08:25

    Using @Hovercraft's example and @camickr's advice, the example below shows a suitable user interface. Although it uses buttons, the SelectionAction would also be suitable for a menu or popup.

    Check A Bunch

    import java.awt.*;
    import java.awt.event.ActionEvent;
    import javax.swing.*;
    import javax.swing.DefaultListSelectionModel;
    import javax.swing.table.DefaultTableModel;
    
    /** @see http://stackoverflow.com/questions/4526779 */
    public class CheckABunch extends JPanel {
    
        private static final int CHECK_COL = 1;
        private static final Object[][] DATA = {
            {"One", Boolean.TRUE}, {"Two", Boolean.FALSE},
            {"Three", Boolean.TRUE}, {"Four", Boolean.FALSE},
            {"Five", Boolean.TRUE}, {"Six", Boolean.FALSE},
            {"Seven", Boolean.TRUE}, {"Eight", Boolean.FALSE},
            {"Nine", Boolean.TRUE}, {"Ten", Boolean.FALSE}};
        private static final String[] COLUMNS = {"Number", "CheckBox"};
        private DataModel dataModel = new DataModel(DATA, COLUMNS);
        private JTable table = new JTable(dataModel);
        private DefaultListSelectionModel selectionModel;
    
        public CheckABunch() {
            super(new BorderLayout());
            this.add(new JScrollPane(table));
            this.add(new ControlPanel(), BorderLayout.SOUTH);
            table.setPreferredScrollableViewportSize(new Dimension(250, 175));
            selectionModel = (DefaultListSelectionModel) table.getSelectionModel();
        }
    
        private class DataModel extends DefaultTableModel {
    
            public DataModel(Object[][] data, Object[] columnNames) {
                super(data, columnNames);
            }
    
            @Override
            public Class<?> getColumnClass(int columnIndex) {
                if (columnIndex == CHECK_COL) {
                    return getValueAt(0, CHECK_COL).getClass();
                }
                return super.getColumnClass(columnIndex);
            }
    
            @Override
            public boolean isCellEditable(int row, int column) {
                return column == CHECK_COL;
            }
        }
    
        private class ControlPanel extends JPanel {
    
            public ControlPanel() {
                this.add(new JLabel("Selection:"));
                this.add(new JButton(new SelectionAction("Clear", false)));
                this.add(new JButton(new SelectionAction("Check", true)));
            }
        }
    
        private class SelectionAction extends AbstractAction {
    
            boolean value;
    
            public SelectionAction(String name, boolean value) {
                super(name);
                this.value = value;
            }
    
            @Override
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < dataModel.getRowCount(); i++) {
                    if (selectionModel.isSelectedIndex(i)) {
                        dataModel.setValueAt(value, i, CHECK_COL);
                    }
                }
            }
        }
    
        private static void createAndShowUI() {
            JFrame frame = new JFrame("CheckABunch");
            frame.add(new CheckABunch());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            java.awt.EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    createAndShowUI();
                }
            });
        }
    }
    
    0 讨论(0)
提交回复
热议问题