Как мне сделать список с флажками в Java Swing?

Каков наилучший способ иметь список элементов с флажком каждый в Java Swing?

Т.е. JList с элементами, которые имеют некоторый текст и флажок каждый?

21.08.2008 12:49:12
Вы можете использовать Japura API. Существует компонент List с
user760034 18.05.2011 22:05:34
Эта ссылка на API Japura теперь не работает.
Mike Stoddart 20.02.2020 17:08:04
9 ОТВЕТОВ
РЕШЕНИЕ

Создайте кастом ListCellRendererи назначьте его JList.

Этот обычай ListCellRendererдолжен возвращать a JCheckboxв реализации getListCellRendererComponent(...)метода.

Но это JCheckboxне будет редактируемым, это простая краска на экране, которую вы можете выбрать, когда она JCheckboxдолжна быть отмечена или нет,

Например, покажите галочку, когда строка выбрана (параметр isSelected), но таким образом состояние проверки не будет поддерживаться, если выбор будет изменен. Лучше показать, что он проверен, обращаясь к данным ниже ListModel, но затем вам нужно реализовать метод, который изменяет статус проверки данных и уведомляет об изменении JListдля перерисовки.

Я опубликую пример кода позже, если вам это нужно

ListCellRenderer

16
12.03.2012 13:16:19

Я, вероятно, хотел бы использовать JTable, а не JList, и поскольку рендеринг флажка по умолчанию довольно уродлив, я бы, вероятно, хотел бы добавить пользовательские TableModel , CellRenderer и CellEditor для представления логического значения. Конечно, я бы предположил, что это было сделано уже несколько раз. У Солнца есть хорошие примеры .

11
21.08.2008 13:04:02

Хорошие шансы, что кто-то уже реализовал нужный вам виджет или утилиту. Часть преимуществ большого сообщества OSS. Не нужно изобретать велосипед, если вы действительно не хотите делать это самостоятельно. В этом случае это было бы хорошим обучающим упражнением в CellRenderers и Editors.

Мой проект имел большой успех с JIDE. Требуемый компонент, список флажков, находится на общем уровне JIDE (который является OSS и размещен на java.net). Коммерческий материал тоже хорош, но он вам не нужен.

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

3
21.08.2008 13:18:40

Прекрасный ответ таков CheckBoxList. Он реализует ответ Telcontar (хотя за 3 года до этого :)) ... Я использую его в Java 1.6 без проблем. Я также добавил такой addCheckboxметод (конечно, может быть короче, я давно не использовал Java):

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

Я опробовал демо для Jidesoft, играя с CheckBoxListI, я столкнулся с некоторыми проблемами (поведение, которое не работало). Я изменю этот ответ, если обнаружу проблемы со CheckBoxListссылками на.

22
14.06.2013 13:22:24
Мне нужно было добавить checkbox.setOpaque (true); для рисования фона (используя GTK + L & F).
Sampo 24.07.2013 14:08:15
И как добавить слушателей для каждого флажка?
NumenorForLife 29.04.2014 20:19:16
Я использую это без проблем. У ДРУГОГО, что я упомянул, были проблемы.
Dan Rosenstark 13.05.2014 23:54:22
как вы можете получить все выбранные строки?
Hirad Roshandel 7.07.2015 22:43:25
@HiradRoshandel создает метод, который просматривает все строки и возвращает выбранные. См. Docs.oracle.com/javase/7/docs/api/javax/swing/…
Dan Rosenstark 9.07.2015 14:52:43

Я рекомендую вам использовать JPanel с GridLayout 1 столбца. Добавьте флажки в JPanel и установите JPanel в качестве источника данных JScrollPane. И чтобы получить выбранные CheckBoxes, просто вызовите getComponents () JPanel, чтобы получить CheckBoxes.

3
14.09.2013 15:56:51

Лучшее решение для Java 7 и новее

Я наткнулся на этот вопрос и понял, что некоторые ответы довольно старые и устаревшие. В настоящее время JList является универсальным, и поэтому существуют лучшие решения.

Мое решение универсального 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;
    }
  }
}

Для динамического добавления списков JCheckBox вам нужно создать свою собственную ListModel или добавить DefaultListModel.

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

В DefaultListModel является универсальным и , таким образом , вы можете использовать методы , указанные JAVA 7 API здесь , как это:

model.addElement(new JCheckBox("Checkbox1"));
model.addElement(new JCheckBox("Checkbox2"));
model.addElement(new JCheckBox("Checkbox3"));
6
16.07.2014 10:07:09
Могу я спросить, как получить список отмеченных элементов в моем списке Jcheckboxlist? PS: (я изменил ListSelectionModel.SINGLE_SELECTION на ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
Mehrez 29.06.2015 15:58:26
Я пытался сделать эту работу в NetBeans, но не могу отобразить ее на экране при запуске. Может кто-нибудь опубликовать фрагмент кода, показывающий, как добавить CheckBoxList в JPanel?
Ed S 15.05.2017 23:11:18
Догадаться. Я не установил размер CheckBoxList: 'CheckBoxListYetAnother checkBoxListYetAnother = new CheckBoxListYetAnother (model); checkBoxListYetAnother.setSize (новое измерение (500, 200)); rtPanel.add (checkBoxListYetAnother);»
Ed S 16.05.2017 02:43:29
Я думаю, что наличие модели, полной флажков - это хорошо, если вам не нужно управлять большим количеством из них. По этой причине правильный подход - использовать рендерер и сохранять модель без них
Jan Pešta 5.02.2018 09:26:05
На самом деле модель должна содержать только данные, а не компоненты пользовательского интерфейса (в основном повторяя то, что говорит @ JanPešta).
TT. 24.02.2020 09:59:45

Вот лишь небольшое дополнение к JCheckBoxList от Rawa. Это добавит возможность выбора с помощью пробела. Если выбрано несколько элементов, для всех будет установлено инвертированное значение первого элемента.

        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
27.08.2014 07:13:46

Просто внедрите 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;
    }
}

и установить рендер

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

это приведет к

Пример CheckboxListCellRenderer

Подробности в пользовательских компонентах рендеринга свинга .

PS: если вы хотите радио элементы просто замените extends JCheckboxна extends JRadioButton.

12
30.11.2014 17:22:05
Я могу выбрать только несколько флажков с помощью Ctrl. Это ожидается? Я хотел бы свободно выбирать столько, сколько я хочу, как обычные флажки. Спасибо.
Nikiforos 25.01.2019 10:48:04

Все агрегатные компоненты в Swing, то есть компоненты, состоящие из других компонентов, таких как JTable, JTree или JComboBox, могут быть настроены индивидуально. Например, компонент JTable обычно отображает сетку компонентов JLabel, но он также может отображать JButtons, JTextFields или даже другие JTables. Однако получить эти агрегатные компоненты для отображения объектов не по умолчанию. Заставить их правильно реагировать на события клавиатуры и мыши - гораздо более сложная задача из-за разделения компонентов Swing на «средства визуализации» и «редакторы». Это разделение было (на мой взгляд) неудачным выбором дизайна и только усложняет ситуацию при попытке расширить компоненты Swing.

Чтобы понять, что я имею в виду, попробуйте улучшить компонент Swing JList, чтобы он отображал флажки вместо меток. Согласно философии Swing, эта задача требует реализации двух интерфейсов: ListCellRenderer (для рисования флажков) и CellEditor (для обработки событий клавиатуры и мыши на флажках). Реализация интерфейса ListCellRenderer достаточно проста, но интерфейс CellEditor может быть довольно неуклюжим и трудным для понимания. В этом конкретном случае я бы предложил полностью забыть CellEditor и напрямую обрабатывать входные события, как показано в следующем коде.

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

Здесь я перехватываю щелчки мышью из списка и моделирую щелчок на соответствующем флажке. В результате получается компонент «CheckBoxList», который проще и меньше, чем эквивалентный компонент, использующий интерфейс CellEditor. Чтобы использовать класс, просто создайте его экземпляр, а затем передайте ему массив объектов JCheckBox (или подклассов объектов JCheckBox), вызвав setListData. Обратите внимание, что флажки в этом компоненте не будут реагировать на нажатия клавиш (например, пробел), но вы всегда можете добавить свой собственный слушатель клавиш, если это необходимо.

Источник: DevX.com

0
22.09.2015 08:26:18