禁用单个JComboBox项

这是一个相当普遍的问题,我使用的解决方案类似于我之后搜索和发现的解决方案。 一个实现带有JLabelListCellRenderer ,它根据当前选定的索引启用或禁用自身:

 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)来确定该项是否可选。