禁用单个JComboBox项

时间:2012-08-10 05:12:19

标签: java swing jcombobox jlist

这是一个相当常见的问题,我使用的解决方案类似于what I searched,稍后会发现。一个实现ListCellRenderer JLabel,根据当前选定的索引启用或禁用自身:

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来调用它。 我如何实际禁用它?

1 个答案:

答案 0 :(得分:3)

您需要某种方法来阻止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);

        }

    }

}

现在这是一个证明重点的快速黑客。你真正需要的是将某些items标记为不可选择的。我能想到的最简单的方法是在item中提供一个属性,例如isSelectable

如果不这样做,您可以构建一个特殊的ComboBoxModel来维护一个单独的内部模型,该模型包含对所有不可选择的items的引用,以便可以使用快速model.contains(item)来确定如果该项目是可选择的。