Mehrfache Zeilenauswahl in JTable

Lesezeit: 5 Minuten

Mehrfache Zeilenauswahl in JTable
Sasidhar

Ich habe eine JTable, die eine Spalte mit Text enthält, die nicht bearbeitet werden kann, und die zweite Spalte ist ein Kontrollkästchen, das boolesche Werte anzeigt …. Jetzt möchte ich, wenn der Benutzer mehrere Zeilen auswählt und eine der aktivierte Kontrollkästchen, dann sollten alle Kontrollkästchen unter Auswahl deaktiviert werden und umgekehrt.

1646260626 495 Mehrfache Zeilenauswahl in JTable
Müllgott

Unter Verwendung des Beispiels von @Hovercraft und der Ratschläge von @camickr zeigt das folgende Beispiel eine geeignete Benutzeroberfläche. Obwohl es Schaltflächen verwendet, die SelectionAction wäre auch für ein Menü oder Popup geeignet.

Überprüfen Sie ein Bündel

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();
            }
        });
    }
}

  • Siehe Kommentare hier, wenn Sortierung aktiviert.

    – Müllgott

    29. Dezember 2012 um 10:47 Uhr

  • Hallo, es tut mir leid, dass ich antworte, aber ich habe dies erst vor einer Weile gefunden und hätte gerne einen Beitrag zum Hinzufügen eines Listeners für Änderungen in der Liste. Im Moment verwende ich einen mouseListener, aber er wird ausgelöst, bevor die Liste tatsächlich aktualisiert wird. Wie kann ich einen Listener hinzufügen, um Aktualisierungen für die Liste zu erhalten, sobald sie auftreten?

    – Sam

    15. April 2014 um 14:00 Uhr

  • Vielleicht ein TableCellEditorhier gesehen?

    – Müllgott

    15. April 2014 um 14:03 Uhr

Das Problem besteht darin, dass die Auswahl aller Zeilen verloren geht, wenn Sie auf ein Kontrollkästchen klicken, um den Wert des Kontrollkästchens zu ändern. Daher müssen Sie möglicherweise mit der rechten Maustaste klicken, um ein Popup-Menü anzuzeigen, das Werte zum Auswählen/Abwählen enthält.

Dann können Sie table.getSelectedRows() verwenden, um die Indizes aller ausgewählten Zeilen zu erhalten, die Sie aktualisieren müssen.

  • Sie haben Recht …. wenn jemals auf das Kontrollkästchen geklickt wird, geht die gesamte Zeilenauswahl verloren … gibt es eine Möglichkeit, dies zu umgehen, ohne den Rechtsklick zu verwenden …?

    – Sasidhar

    24. Dezember 2010 um 16:37 Uhr

  • Sie können einen Mausklick nicht für zwei verschiedene Funktionen verwenden. Die Lösung ist eine richtige Benutzeroberfläche. Ich habe einen Vorschlag gemacht, ein Popup-Menü zu verwenden. Eine andere Lösung besteht darin, menuItems aus einem Menü mit Zugriffstasten zum Auswählen/Abwählen zu verwenden. Auf diese Weise kann der Benutzer die Maus oder die Tastatur verwenden. Oder Sie können der Benutzeroberfläche Schaltflächen hinzufügen, um dasselbe zu tun.

    – camickr

    24. Dezember 2010 um 18:24 Uhr

  • Ich muss @camickr zustimmen; Ich habe ein Beispiel in der Nähe hinzugefügt.

    – Müllgott

    24. Dezember 2010 um 22:48 Uhr

Sie können das Auswahlintervall mit einem ähnlichen Code wie diesem erhalten:

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

Wenn dann ein Kontrollkästchen aktiviert ist (listen to ItemEvent) sollten Sie von iterieren minSelectedRow zum maxSelectedRow und ändern Sie den Zustand der aktivierten Kästchen. Das ist es.

1646260627 323 Mehrfache Zeilenauswahl in JTable
Hovercraft voller Aale

Ich stimme Roman zu, dass seine Idee funktionieren würde, wenn Sie ein Klassenfeld verwenden, um die Min- und Max-Auswahl zu speichern. Zum Beispiel:

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();
            }
        });
    }
}

916850cookie-checkMehrfache Zeilenauswahl in JTable

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy