禁用单个JComboBox项
这是一个相当普遍的问题,我使用的解决方案类似于我之后搜索和发现的解决方案。 一个实现带有JLabel
的ListCellRenderer
,它根据当前选定的索引启用或禁用自身:
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { setText(value.toString()); UIDefaults defaults = UIManager.getDefaults(); Color fc; if (index == 1) { setEnabled(false); fc = defaults.getColor("Label.disabledForeground"); setFocusable(false); } else { // fc = defaults.getColor("Label.foreground"); fc = list.getForeground(); setEnabled(list.isEnabled()); setFocusable(true); } setForeground(fc); setBackground(isSelected ? list.getSelectionBackground() : list .getBackground()); return this; }
问题是即使在视觉上列表项显示为禁用,仍然可以选择它,尽管setFocusable
调用。 我如何实际禁用它?
您需要一些方法来阻止ComboBox
能够设置无法从中选择的项目。
我能想到的最简单的方法是在模型本身中捕获选择中的变化。
public class MyComboBoxModel extends DefaultComboBoxModel { public MyComboBoxModel() { addElement("Select me"); addElement("I can be selected"); addElement("Leave me alone"); addElement("Hit me!!"); } @Override public void setSelectedItem(Object anObject) { if (anObject != null) { if (!anObject.toString().equals("Leave me alone")) { super.setSelectedItem(anObject); } } else { super.setSelectedItem(anObject); } } }
现在,这是一个快速的黑客来certificate这一点。 你真正需要的是将某些items
标记为不可选择。 我能想到的最简单的方法是在item
提供属性,例如isSelectable
。
如果做不到这一点,你可以构造一个特殊的ComboBoxModel
来维护一个单独的内部模型,该内部模型包含对所有不可选项的引用,因此可以使用快速model.contains(item)
来确定该项是否可选。