Frage

Was wäre der beste Weg, um in Java Swing eine Liste von Elementen mit jeweils einem Kontrollkästchen zu haben?

D.h.eine JList mit Elementen, die jeweils Text und ein Kontrollkästchen enthalten?

War es hilfreich?

Lösung

Erstellen Sie eine benutzerdefinierte ListCellRenderer und weisen Sie es dem zu JList.

Dieser Brauch ListCellRenderer muss a zurückgeben JCheckbox bei der Umsetzung von getListCellRendererComponent(...) Methode.

Aber dieses JCheckbox Wird nicht bearbeitet werden können, ist es eine einfache Farbe auf dem Bildschirm. Es liegt an Ihnen, zu wählen, wann dies der Fall ist JCheckbox muss angekreuzt sein oder nicht,

Zeigen Sie es beispielsweise mit einem Häkchen an, wenn die Zeile ausgewählt ist (Parameter isSelected), aber auf diese Weise wird der Prüfstatus nicht beibehalten, wenn sich die Auswahl ändert.Es ist besser, anhand der folgenden Daten zu zeigen, dass es überprüft wurde ListModel, aber dann liegt es an Ihnen, die Methode zu implementieren, die den Prüfstatus der Daten ändert, und die Änderung dem mitzuteilen JList neu gestrichen werden.

Ich werde später Beispielcode veröffentlichen, wenn Sie ihn benötigen

ListCellRenderer

Andere Tipps

Eine wunderbare Antwort ist diese CheckBoxList.Es implementiert die Antwort von Telcontar (allerdings 3 Jahre zuvor :) ...Ich verwende es in Java 1.6 ohne Probleme.Ich habe auch eine hinzugefügt addCheckbox Methode wie diese (könnte sicherlich kürzer sein, ich habe Java schon eine Weile nicht mehr verwendet):

public void addCheckbox(JCheckBox checkBox) {
    ListModel currentList = this.getModel();
    JCheckBox[] newList = new JCheckBox[currentList.getSize() + 1];
    for (int i = 0; i < currentList.getSize(); i++) {
        newList[i] = (JCheckBox) currentList.getElementAt(i);
    }
    newList[newList.length - 1] = checkBox;
    setListData(newList);
}

Ich habe die Demo für die Jidesoft-Sachen ausprobiert und damit gespielt CheckBoxList Ich bin auf einige Probleme gestoßen (Verhaltensweisen, die nicht funktioniert haben).Ich werde diese Antwort ändern, wenn ich Probleme damit finde CheckBoxList Ich habe verlinkt.

Ich würde wahrscheinlich nach einem suchen JTable eher als ein JList Und da die Standarddarstellung eines Kontrollkästchens ziemlich hässlich ist, würde ich wahrscheinlich versuchen, ein benutzerdefiniertes Kontrollkästchen einzubauen Tabellenmodell, CellRenderer Und CellEditor um einen booleschen Wert darzustellen.Natürlich könnte ich mir vorstellen, dass dies bereits unzählige Male geschehen ist.Sonne hat gute Beispiele.

Implementieren Sie einfach a ListCellRenderer

public class CheckboxListCellRenderer extends JCheckBox implements ListCellRenderer {

    public Component getListCellRendererComponent(JList list, Object value, int index, 
            boolean isSelected, boolean cellHasFocus) {

        setComponentOrientation(list.getComponentOrientation());
        setFont(list.getFont());
        setBackground(list.getBackground());
        setForeground(list.getForeground());
        setSelected(isSelected);
        setEnabled(list.isEnabled());

        setText(value == null ? "" : value.toString());  

        return this;
    }
}

und legen Sie den Renderer fest

JList list = new JList();
list.setCellRenderer(new CheckboxListCellRenderer());

Dies wird zur Folge haben

CheckboxListCellRenderer example

Details unter Benutzerdefinierte Swing-Komponenten-Renderer.

PS:Wenn Sie Radioelemente wünschen, tauschen Sie diese einfach aus extends JCheckbox mit extends JRadioButton.

Bessere Lösung für Java 7 und neuer

Ich bin über diese Frage gestolpert und habe festgestellt, dass einige der Antworten ziemlich alt und überholt sind.Heutzutage ist JList generisch und daher gibt es bessere Lösungen.

Meine Lösung der generischen JCheckBoxList:

import java.awt.Component;

import javax.swing.*;
import javax.swing.border.*;

import java.awt.event.*;

@SuppressWarnings("serial")
public class JCheckBoxList extends JList<JCheckBox> {
  protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);

  public JCheckBoxList() {
    setCellRenderer(new CellRenderer());
    addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
        int index = locationToIndex(e.getPoint());
        if (index != -1) {
          JCheckBox checkbox = (JCheckBox) getModel().getElementAt(index);
          checkbox.setSelected(!checkbox.isSelected());
          repaint();
        }
      }
    });
    setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  }

  public JCheckBoxList(ListModel<JCheckBox> model){
    this();
    setModel(model);
  }

  protected class CellRenderer implements ListCellRenderer<JCheckBox> {
    public Component getListCellRendererComponent(
        JList<? extends JCheckBox> list, JCheckBox value, int index,
        boolean isSelected, boolean cellHasFocus) {
      JCheckBox checkbox = value;

      //Drawing checkbox, change the appearance here
      checkbox.setBackground(isSelected ? getSelectionBackground()
          : getBackground());
      checkbox.setForeground(isSelected ? getSelectionForeground()
          : getForeground());
      checkbox.setEnabled(isEnabled());
      checkbox.setFont(getFont());
      checkbox.setFocusPainted(false);
      checkbox.setBorderPainted(true);
      checkbox.setBorder(isSelected ? UIManager
          .getBorder("List.focusCellHighlightBorder") : noFocusBorder);
      return checkbox;
    }
  }
}

Zum dynamischen Hinzufügen von JCheckBox-Listen müssen Sie Ihr eigenes ListModel erstellen oder das DefaultListModel hinzufügen.

DefaultListModel<JCheckBox> model = new DefaultListModel<JCheckBox>();
JCheckBoxList checkBoxList = new JCheckBoxList(model);

Der DefaultListModel sind generisch und daher können Sie von der JAVA 7 API angegebene Methoden verwenden Hier so was:

model.addElement(new JCheckBox("Checkbox1"));
model.addElement(new JCheckBox("Checkbox2"));
model.addElement(new JCheckBox("Checkbox3"));

Bei Java stehen die Chancen gut, dass jemand das benötigte Widget oder Dienstprogramm bereits implementiert hat.Ein Teil der Vorteile einer großen OSS-Community.Sie müssen das Rad nicht neu erfinden, es sei denn, Sie möchten es wirklich selbst tun.In diesem Fall wäre es eine gute Lernübung in CellRenderers und Editors.

Mein Projekt hatte mit JIDE großen Erfolg.Die gewünschte Komponente, eine Kontrollkästchenliste, befindet sich im JIDE Common Layer (das OSS ist und auf java.net gehostet wird).Das kommerzielle Zeug ist auch gut, aber man braucht es nicht.

http://www.jidesoft.com/products/oss.htm https://jide-oss.dev.java.net/

Ich empfehle Ihnen, ein JPanel mit einem GridLayout von 1 Spalte zu verwenden.Fügen Sie die Kontrollkästchen zum JPanel hinzu und legen Sie das JPanel als Datenquelle eines JScrollPane fest.Und um die ausgewählten CheckBoxes abzurufen, rufen Sie einfach getComponents() des JPanel auf, um die CheckBoxes abzurufen.

Hier ist nur eine kleine Ergänzung zur JCheckBoxList von Rawa.Dadurch wird die Möglichkeit hinzugefügt, mithilfe der Leertaste auszuwählen.Wenn mehrere Elemente ausgewählt sind, werden alle auf den invertierten Wert des ersten Elements gesetzt.

        addKeyListener(new KeyAdapter() {
        @Override
        public void keyPressed(KeyEvent e) {
            int index = getSelectedIndex();
            if (index != -1 && e.getKeyCode() == KeyEvent.VK_SPACE) {
                boolean newVal = !((JCheckBox) (getModel()
                        .getElementAt(index))).isSelected();
                for (int i : getSelectedIndices()) {
                    JCheckBox checkbox = (JCheckBox) getModel()
                            .getElementAt(i);
                    checkbox.setSelected(newVal);
                    repaint();
                }
            }
        }
        });

Alle Aggregatkomponenten in Swing – also Komponenten, die aus anderen Komponenten wie JTable, JTree oder JComboBox bestehen – können in hohem Maße angepasst werden.Beispielsweise zeigt eine JTable-Komponente normalerweise ein Raster von JLabel-Komponenten an, kann aber auch JButtons, JTextFields oder sogar andere JTables anzeigen.Es ist jedoch einfacher, diese Aggregatkomponenten dazu zu bringen, nicht standardmäßige Objekte anzuzeigen.Es ist eine viel schwierigere Aufgabe, sie ordnungsgemäß auf Tastatur- und Mausereignisse zu reagieren, da Swing von Komponenten in "Renderer" und "Redakteure" getrennt werden. Diese Trennung war (meiner Meinung nach) eine schlechte Designauswahl und dient nur dazu, die Angelegenheit zu komplizieren, wenn versucht wird, Schwungkomponenten zu erweitern.

Um zu verstehen, was ich meine, versuchen Sie, die JList-Komponente von Swing so zu erweitern, dass sie Kontrollkästchen anstelle von Beschriftungen anzeigt.Gemäß der Swing-Philosophie erfordert diese Aufgabe die Implementierung zweier Schnittstellen:ListCellRenderer (zum Zeichnen der Kontrollkästchen) und CellEditor (zur Verarbeitung von Tastatur- und Mausereignissen auf den Kontrollkästchen).Die Implementierung der ListCellRenderer-Schnittstelle ist recht einfach, die CellEditor-Schnittstelle kann jedoch recht umständlich und schwer zu verstehen sein.In diesem speziellen Fall würde ich vorschlagen, CellEditor ganz zu vergessen und Eingabeereignisse direkt zu verarbeiten, wie im folgenden Code gezeigt.

import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;

public class CheckBoxList extends JList
{
   protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);

   public CheckBoxList()
   {
      setCellRenderer(new CellRenderer());

      addMouseListener(new MouseAdapter()
         {
            public void mousePressed(MouseEvent e)
            {
               int index = locationToIndex(e.getPoint());

               if (index != -1) {
                  JCheckBox checkbox = (JCheckBox)
                              getModel().getElementAt(index);
                  checkbox.setSelected(
                                     !checkbox.isSelected());
                  repaint();
               }
            }
         }
      );

      setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
   }

   protected class CellRenderer implements ListCellRenderer
   {
      public Component getListCellRendererComponent(
                    JList list, Object value, int index,
                    boolean isSelected, boolean cellHasFocus)
      {
         JCheckBox checkbox = (JCheckBox) value;
         checkbox.setBackground(isSelected ?
                 getSelectionBackground() : getBackground());
         checkbox.setForeground(isSelected ?
                 getSelectionForeground() : getForeground());
         checkbox.setEnabled(isEnabled());
         checkbox.setFont(getFont());
         checkbox.setFocusPainted(false);
         checkbox.setBorderPainted(true);
         checkbox.setBorder(isSelected ?
          UIManager.getBorder(
           "List.focusCellHighlightBorder") : noFocusBorder);
         return checkbox;
      }
   }
}

Hier fange ich Mausklicks aus der Listbox ab und simuliere einen Klick auf die entsprechende Checkbox.Das Ergebnis ist eine „CheckBoxList“-Komponente, die sowohl einfacher als auch kleiner ist als eine entsprechende Komponente, die die CellEditor-Schnittstelle verwendet.Um die Klasse zu verwenden, instanziieren Sie sie einfach und übergeben ihr dann ein Array von JCheckBox-Objekten (oder Unterklassen von JCheckBox-Objekten), indem Sie setListData aufrufen.Beachten Sie, dass die Kontrollkästchen in dieser Komponente nicht auf Tastendrücke reagieren (d. h.die Leertaste), aber Sie können bei Bedarf jederzeit Ihren eigenen Schlüssel-Listener hinzufügen.

Quelle: DevX.com

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top