Сведения о вопросе

Oleksandrop

05:58, 5th August, 2020

Теги

java   swing   jcheckbox    

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

Просмотров: 626   Ответов: 9

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

I.e. a JList с элементами, которые имеют некоторый текст и A checkbox каждый?



  Сведения об ответе

Chhiki

15:39, 29th August, 2020

Замечательный ответ - это 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, играя с CheckBoxList , я столкнулся с некоторыми проблемами (поведение, которое не работало). Я изменю этот ответ, если найду проблемы с CheckBoxList , с которым я связан.


  Сведения об ответе

darknet

09:50, 17th August, 2020

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

Этот пользовательский ListCellRenderer должен возвращать JCheckbox в реализации метода getListCellRendererComponent(...) .

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

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

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

ListCellRenderer


  Сведения об ответе

dumai

22:09, 16th August, 2020

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


  Сведения об ответе

#hash

20:43, 3rd August, 2020

Просто реализовать 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 example

Детали на заказ swing компонент визуализации .

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


  Сведения об ответе

DINO

00:55, 2nd August, 2020

Лучшее решение для 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"));

  Сведения об ответе

park

17:07, 3rd August, 2020

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

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

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


  Сведения об ответе

darknet

22:41, 13th August, 2020

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


  Сведения об ответе

VCe znayu

12:26, 27th August, 2020

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

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


  Сведения об ответе

DO__IT

18:55, 23rd August, 2020

Все агрегатные компоненты в Swing-то есть компоненты, состоящие из других компонентов, таких как JTable, JTree или JComboBox-могут быть сильно настроены. Например, компонент JTable обычно отображает сетку из JLabel компонентов, но он также может отображать JButtons, JTextFields или даже другие JTables. Однако получить эти агрегатные компоненты для отображения объектов, не являющихся объектами по умолчанию, очень просто. Заставить их правильно реагировать на события клавиатуры и мыши-гораздо более сложная задача, поскольку разделение компонентов Swing на "renderers" и "editors." было (на мой взгляд) плохим выбором дизайна и только усложняет дело при попытке расширить компоненты 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;
      }
   }
}

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

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться