Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

ListCellRenderer

Ответ 2

Замечательный ответ: 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, с которыми я связан.

Ответ 3

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

Ответ 4

Просто выполните 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

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

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

Ответ 5

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

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

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

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

Ответ 7

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

Ответ 8

Вот лишь небольшое дополнение к 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();
                }
            }
        }
        });

Ответ 9

Все агрегированные компоненты в 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