禁用 JList 中的项目
Posted
技术标签:
【中文标题】禁用 JList 中的项目【英文标题】:Disable items in JList 【发布时间】:2012-01-10 18:40:12 【问题描述】:我使用 JList 作为向导的一部分来显示要执行的所有步骤(它还允许单击一个步骤转到它)。根据前面步骤中完成的内容,并不总是需要某些步骤。我想在列表中禁用这些不适用的步骤。
如何禁用(防止选择)列表中的某些项目?有没有比继承 JList 并覆盖所有与选择相关的方法更好的方法?
【问题讨论】:
【参考方案1】:如果您从列表模型中删除不适用的项目,而不是禁用它们会更容易。用户真的希望看到禁用的项目吗?我不认为它增加了任何价值,而是增加了视觉上的混乱。
【讨论】:
这是一个很好的观点。经过一番思考,我决定将它们变灰,但允许它们被选中。使用下一个/上一个时会跳过它们,但如果它们故意进入灰显步骤,则会显示一条消息,说明“启用”该步骤所需的操作【参考方案2】:你必须实现DefaultListSelectionModel,然后你可以设置标志是否启用
简单例子
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class JListDisabledItemDemo implements ItemListener, Runnable
private JFrame f = new JFrame("Colors");
private static final String ITEMS[] = " black ", " blue ", " green ",
" orange ", " purple ", " red ", " white ", " yellow ";
private JList jList;
private JCheckBox[] checkBoxes;
private boolean[] enabledFlags;
@Override
public void run()
JPanel pnlEnablers = new JPanel(new GridLayout(0, 1));
pnlEnablers.setBorder(BorderFactory.createTitledBorder("Enabled Items"));
checkBoxes = new JCheckBox[ITEMS.length];
enabledFlags = new boolean[ITEMS.length];
for (int i = 0; i < ITEMS.length; i++)
checkBoxes[i] = new JCheckBox(ITEMS[i]);
checkBoxes[i].setSelected(true);
checkBoxes[i].addItemListener(this);
enabledFlags[i] = true;
pnlEnablers.add(checkBoxes[i]);
jList = new JList(ITEMS);
jList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jList.setSelectionModel(new DisabledItemSelectionModel());
jList.setCellRenderer(new DisabledItemListCellRenderer());
jList.addListSelectionListener(new ListSelectionListener()
@Override
public void valueChanged(ListSelectionEvent e)
if (!e.getValueIsAdjusting())
System.out.println("selection");
);
JScrollPane scroll = new JScrollPane(jList);
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
Container contentPane = f.getContentPane();
contentPane.setLayout(new GridLayout(1, 2));
contentPane.add(pnlEnablers);
contentPane.add(scroll);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocation(240, 280);
UIManager.put("List.background", Color.lightGray);
UIManager.put("List.selectionBackground", Color.orange);
UIManager.put("List.selectionForeground", Color.blue);
UIManager.put("Label.disabledForeground", Color.magenta);
SwingUtilities.updateComponentTreeUI(f);
f.pack();
javax.swing.SwingUtilities.invokeLater(new Runnable()
@Override
public void run()
f.setVisible(true);
);
@Override
public void itemStateChanged(ItemEvent event)
JCheckBox checkBox = (JCheckBox) event.getSource();
int index = -1;
for (int i = 0; i < ITEMS.length; i++)
if (ITEMS[i].equals(checkBox.getText()))
index = i;
break;
if (index != -1)
enabledFlags[index] = checkBox.isSelected();
jList.repaint();
public static void main(String args[])
SwingUtilities.invokeLater(new JListDisabledItemDemo());
private class DisabledItemListCellRenderer extends DefaultListCellRenderer
private static final long serialVersionUID = 1L;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
Component comp = super.getListCellRendererComponent(list, value, index, false, false);
JComponent jc = (JComponent) comp;
if (enabledFlags[index])
if (isSelected & cellHasFocus)
comp.setForeground(Color.black);
comp.setBackground(Color.red);
else
comp.setForeground(Color.blue);
if (!isSelected)
if ((value.toString()).trim().equals("yellow"))
comp.setForeground(Color.orange);
comp.setBackground(Color.magenta);
return comp;
comp.setEnabled(false);
return comp;
private class DisabledItemSelectionModel extends DefaultListSelectionModel
private static final long serialVersionUID = 1L;
@Override
public void setSelectionInterval(int index0, int index1)
if (enabledFlags[index0])
super.setSelectionInterval(index0, index0);
else
/*
* The previously selected index is before this one,
* so walk forward to find the next selectable item.
*/
if (getAnchorSelectionIndex() < index0)
for (int i = index0; i < enabledFlags.length; i++)
if (enabledFlags[i])
super.setSelectionInterval(i, i);
return;
/*
* Otherwise, walk backward to find the next selectable item.
*/ else
for (int i = index0; i >= 0; i--)
if (enabledFlags[i])
super.setSelectionInterval(i, i);
return;
【讨论】:
当您想显示禁用的项目时,这是一个很好的答案。在某些用例中,实际上这样做更好。我有这样一个用例,这就像一个魅力。【参考方案3】:一种解决方案:您可能想在 Java API 中查找 AbstractAction。然后,实现 COMMAND 模式。
这个想法是通过将它们变成类(实现 AbstractAction)来赋予方法状态。然后,它们可以互相禁用。
http://en.wikipedia.org/wiki/Command_pattern
http://docs.oracle.com/javase/6/docs/api/
【讨论】:
【参考方案4】:我想要一个包含无法选择且透明的单元格的 JList。所以这就是我所做的:
class DisabledItemListCellRenderer extends JLabel implements ListCellRenderer<Object>
private static final long serialVersionUID = 1L;
public DisabledItemListCellRenderer()
setOpaque(false);
@Override
public Component getListCellRendererComponent(JList<?> list, Object value,
int index, boolean isSelected, boolean cellHasFocus)
String txt = (String) value;
setText(txt);
return this;
【讨论】:
以上是关于禁用 JList 中的项目的主要内容,如果未能解决你的问题,请参考以下文章
使用 DefaultListModel 将项目从 ArrayList 添加到 JList