Каков наилучший способ иметь список элементов с флажком каждый в Java Swing?
Т.е. JList с элементами, которые имеют некоторый текст и флажок каждый?
Создайте кастом ListCellRenderer
и назначьте его JList
.
Этот обычай ListCellRenderer
должен возвращать a JCheckbox
в реализации getListCellRendererComponent(...)
метода.
Но это JCheckbox
не будет редактируемым, это простая краска на экране, которую вы можете выбрать, когда она JCheckbox
должна быть отмечена или нет,
Например, покажите галочку, когда строка выбрана (параметр isSelected
), но таким образом состояние проверки не будет поддерживаться, если выбор будет изменен. Лучше показать, что он проверен, обращаясь к данным ниже ListModel
, но затем вам нужно реализовать метод, который изменяет статус проверки данных и уведомляет об изменении JList
для перерисовки.
Я опубликую пример кода позже, если вам это нужно
Я, вероятно, хотел бы использовать JTable, а не JList, и поскольку рендеринг флажка по умолчанию довольно уродлив, я бы, вероятно, хотел бы добавить пользовательские TableModel , CellRenderer и CellEditor для представления логического значения. Конечно, я бы предположил, что это было сделано уже несколько раз. У Солнца есть хорошие примеры .
Хорошие шансы, что кто-то уже реализовал нужный вам виджет или утилиту. Часть преимуществ большого сообщества OSS. Не нужно изобретать велосипед, если вы действительно не хотите делать это самостоятельно. В этом случае это было бы хорошим обучающим упражнением в CellRenderers и Editors.
Мой проект имел большой успех с JIDE. Требуемый компонент, список флажков, находится на общем уровне JIDE (который является OSS и размещен на java.net). Коммерческий материал тоже хорош, но он вам не нужен.
http://www.jidesoft.com/products/oss.htm https://jide-oss.dev.java.net/
Прекрасный ответ таков 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
I, я столкнулся с некоторыми проблемами (поведение, которое не работало). Я изменю этот ответ, если обнаружу проблемы со CheckBoxList
ссылками на.
Я рекомендую вам использовать JPanel с GridLayout 1 столбца. Добавьте флажки в JPanel и установите JPanel в качестве источника данных JScrollPane. И чтобы получить выбранные CheckBoxes, просто вызовите getComponents () JPanel, чтобы получить CheckBoxes.
Лучшее решение для 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"));
Вот лишь небольшое дополнение к 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();
}
}
}
});
Просто внедрите 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());
это приведет к
Подробности в пользовательских компонентах рендеринга свинга .
PS: если вы хотите радио элементы просто замените extends JCheckbox
на extends JRadioButton
.
Все агрегатные компоненты в 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