Comment faire une liste avec des cases à cocher dans Java Swing?

quelle serait la meilleure façon d'avoir une liste d'éléments avec une case à cocher chacun dans Java Swing?

<!-C'est-à-dire: une liste avec des éléments qui ont du texte et une case à cocher chacun?

29
demandé sur David 'mArm' Ansermot 2008-08-21 16:49:12

9 réponses

Créer un custom ListCellRenderer et assigner à l' JList.

cette coutume ListCellRenderer doit retourner un JCheckbox dans le implementantion de getListCellRendererComponent(...) méthode.

Mais ce JCheckbox ne sera pas modifiable, est une simple peinture à l'écran est à vous de choisir lors de cette JCheckbox doit être cochée ou pas,

Par exemple, montrent une légère lorsque la ligne est sélectionnée (paramètre isSelected), mais de cette façon le statut de contrôle ne sera pas maintenu si la sélection changement. Il est préférable de montrer vérifié en consultant les données en dessous de la ListModel, mais c'est alors à vous de mettre en œuvre la méthode qui modifie l'état de vérification des données, et de notifier le changement à la JList pour être repeint.

je Vais poster un exemple de code plus tard, si vous en avez besoin

ListCellRenderer

16
répondu Telcontar 2012-03-12 13:16:19

Une merveilleuse réponse est CheckBoxList. Il implémente la réponse de Telcontar (bien que 3 ans auparavant :)... Je l'utilise en Java 1.6 sans problème. J'ai aussi ajouté un addCheckbox méthode comme celle-ci (sûrement plus courte, je N'ai pas utilisé Java depuis un moment):

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

j'ai essayé la démo pour le truc de Jidesoft, en jouant avec le CheckBoxList j'ai rencontré quelques problèmes (comportements qui n'ont pas fonctionné). Je modifierai cette réponse si je trouve des problèmes avec le CheckBoxList j'ai fait un lien de.

21
répondu Dan Rosenstark 2013-06-14 13:22:24

je cherche probablement à utiliser un JTable plutôt que JList et puisque le rendu par défaut d'une case à cocher est plutôt laid, je serais probablement à la recherche de laisser tomber un custom TableModel, CellRenderer et CellEditor pour représenter une valeur booléenne. Bien sûr, j'imagine que cela a déjà été fait des millions de fois. Soleil a bons exemples.

11
répondu ninesided 2008-08-21 13:04:02

il suffit d'implémenter un 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;
    }
}

et définissez le moteur de rendu

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

résultat

CheckboxListCellRenderer example

Détails composante sur mesure renderers.

PS: Si vous voulez des éléments radio, remplacez extends JCheckboxextends JRadioButton.

10
répondu René Link 2014-11-30 17:22:05

meilleure solution pour Java 7 et les versions plus récentes

je suis tombé sur cette question et a réalisé que certaines réponses sont assez vieux et dépassé. Aujourd'hui, JList est générique et il y a donc de meilleures solutions.

Ma solution du générique 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;
    }
  }
}

pour ajouter dynamiquement des listes JCheckBox, vous devez créer votre propre ListModel ou ajouter le Defaullistmodel.

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

Defaullistmodel sont génériques et ainsi, vous pouvez utiliser les méthodes spécifiées par L'API JAVA 7 ici comme ceci:

model.addElement(new JCheckBox("Checkbox1"));
model.addElement(new JCheckBox("Checkbox2"));
model.addElement(new JCheckBox("Checkbox3"));
5
répondu Rawa 2014-07-16 10:07:09

les chances sont bonnes w / Java que quelqu'un a déjà mis en œuvre le widget ou l'utilitaire dont vous avez besoin. Une partie des avantages d'une grande communauté de logiciels libres. Pas besoin de réinventer la roue si vous voulez vraiment le faire vous-même. Dans ce cas, ce serait un bon exercice d'apprentissage chez les violoncellistes et les rédacteurs en chef.

mon projet a eu beaucoup de succès avec JIDE. Le composant que vous voulez, une liste de cases à cocher, est dans la couche commune JIDE (qui est OSS et hébergé sur java.net). La pub est bonne. trop, mais vous n'en avez pas besoin.

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

3
répondu basszero 2008-08-21 13:18:40

je vous recommande D'utiliser un JPanel avec un GridLayout de 1 colonne. Ajoutez les cases à cocher au JPanel, et définissez le JPanel comme la source de données d'un JScrollPane. Et pour obtenir les cases à cocher sélectionnées, il suffit d'appeler les getComponents() du JPanel pour obtenir les cases à cocher.

3
répondu Zero_8 2013-09-14 15:56:51

Voici juste un petit ajout à la JCheckBoxList de Rawa. Cela ajoutera la capacité de sélectionner en utilisant la barre d'espace. Si plusieurs items sont sélectionnés, tous seront définis à la valeur inversée du premier item.

        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();
                }
            }
        }
        });
0
répondu Željko Vuković 2014-08-27 07:13:46

toutes les composantes globales dans Swing--c'est-à-dire, les composantes composées d'autres composantes, telles que JTable, JTree, ou JComboBox--peuvent être fortement personnalisées. Par exemple, un composant JTable affiche normalement une grille de composants JLabel, mais il peut aussi afficher des JButtons, JTextFields, ou même d'autres JTables. Obtenir ces composants agrégés pour afficher des objets non-par défaut est la partie facile, cependant. Leur faire répondre correctement aux évènements clavier et souris est une tâche beaucoup plus difficile, en raison de Swing la séparation des composants dans des "convertisseurs" et "des éditeurs."Cette séparation était (à mon avis) Un mauvais choix de conception et ne sert qu'à compliquer les choses lorsque l'on essaie d'étendre les composants Swing.

pour voir ce que je veux dire, essayez d'améliorer le composant JList de Swing pour qu'il affiche des cases à cocher au lieu des étiquettes. Selon la philosophie Swing, cette tâche nécessite l'implémentation de deux interfaces: ListCellRenderer (pour dessiner les cases à cocher) et CellEditor (pour gérer les évènements clavier et souris). sur les cases à cocher). Mettre en œuvre L'interface ListCellRenderer est assez facile, mais L'interface CellEditor peut être plutôt maladroit et difficile à comprendre. Dans ce cas précis, je suggérerais d'oublier entièrement CellEditor et de gérer les événements d'entrée directement, comme le montre le code suivant.

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

ici, j'intercepte les clics de souris de la liste et simule un clic sur la case à cocher appropriée. Le résultat est un composant "CheckBoxList" à la fois plus simple et plus petit que un composant équivalent utilisant L'interface CellEditor. Pour utiliser la classe, instanciez-la simplement, puis passez-lui un tableau D'objets JCheckBox (ou des sous-classes d'objets JCheckBox) en appelant setListData. Notez que les cases à cocher de ce composant ne répondront pas aux touches (c'est-à-dire la barre d'espacement), mais vous pouvez toujours ajouter votre propre écouteur de touches si nécessaire.

Source:DevX.com

0
répondu Lucky 2015-09-22 08:26:18