在Java Swing中有一个带有复选框的项目列表的最佳方法是什么?
即。一个JList,其中的项目包含一些文本和每个复选框?
答案 0 :(得分:21)
这是一个很好的答案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
的问题,我会修改此答案。
答案 1 :(得分:16)
创建自定义ListCellRenderer
并将其与JList
。
此自定义ListCellRenderer
必须在JCheckbox
方法的实施中返回getListCellRendererComponent(...)
。
但是这个JCheckbox
是不可编辑的,只有当JCheckbox
必须“勾选”时才会选择屏幕上的简单画颜,
例如,在选择行时显示它(参数isSelected
),但是这样,如果选择更改,则不会保留检查状态。最好通过咨询ListModel
下面的数据来检查它,但是由您来实现更改数据检查状态的方法,并通知更改JList
要重新绘制
如果您需要,我会稍后发布示例代码
答案 2 :(得分:11)
我可能希望使用 JTable 而不是 JList ,因为复选框的默认呈现相当丑陋,我可能会期待放入自定义 TableModel , CellRenderer 和 CellEditor 以表示布尔值。当然,我想这已经完成了数百次。 Sun有good examples。
答案 3 :(得分:10)
只需实施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());
这将导致
Custom swing component renderers的详细信息。
PS:如果你想要无线电元素,只需用extends JCheckbox
替换extends JRadioButton
。
答案 4 :(得分:5)
我偶然发现了这个问题,并意识到有些问题已经过时了。如今,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 here指定的方法,如下所示:
model.addElement(new JCheckBox("Checkbox1"));
model.addElement(new JCheckBox("Checkbox2"));
model.addElement(new JCheckBox("Checkbox3"));
答案 5 :(得分:3)
有些人已经实现了您需要的小部件或实用程序,这对Java很有好处。大型OSS社区的部分好处。除非你真的想自己动手,否则无需重新发明轮子。在这种情况下,它将是CellRenderers和Editors的一个很好的学习练习。
我的项目在JIDE取得了巨大成功。您需要的组件,复选框列表,位于JIDE公共层(OSS并托管在java.net上)。商业用品也很好,但你不需要它。
http://www.jidesoft.com/products/oss.htm https://jide-oss.dev.java.net/
答案 6 :(得分:3)
我建议你使用一个GridLayout为1列的JPanel。将复选框添加到JPanel,并将JPanel设置为JScrollPane的数据源。要获取选定的CheckBox,只需调用JPanel的getComponents()来获取CheckBoxes。
答案 7 :(得分:0)
这是Rawa对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();
}
}
}
});
答案 8 :(得分:0)
Swing中的所有聚合组件 - 即组成其他组件的组件,例如JTable,JTree或JComboBox - 可以高度自定义。例如,JTable组件通常显示JLabel组件的网格,但它也可以显示JButtons,JTextFields甚至其他JTable。但是,获取这些聚合组件以显示非默认对象是很容易的部分。由于Swing将组件分离为&#34;渲染器&#34;使得它们对键盘和鼠标事件做出正确响应是一项艰巨的任务。和&#34;编辑。&#34;这种分离(在我看来)是一个糟糕的设计选择,只会在尝试扩展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;
}
}
}
在这里,我拦截了列表框中的鼠标点击,并模拟了相应复选框上的点击。结果是&#34; CheckBoxList&#34;使用CellEditor接口比同等组件更简单和更小的组件。要使用该类,只需实例化它,然后通过调用setListData将其传递给JCheckBox对象(或JCheckBox对象的子类)数组。请注意,此组件中的复选框不会响应按键(即空格键),但如果需要,您可以随时添加自己的键侦听器。
来源:DevX.com