2D JComboBox,其中一个使用 ActionListener 控制另一个项目

2D JComboBox that one controling items of the other with ActionListener

我坚持在 Java GUI 表单中制作两个下拉菜单,第一个的选择将决定第二个菜单中的选择。

我希望达到的效果是这样的: enter image description here

在 comboBox1 中切换选择后,它看起来像这样: enter image description here

这是我的测试代码:

    public static void main(String[] args) {
        Tester tester = new Tester();
        String[] flower = {"Rose", "Tulip"};
        String[] color1 = {"Yellow", "Blue", "Red"};
        String[] color2 = {"Purple", "White", "Green"};

        for (String flowerPicked : flower) {
            tester.comboBox1.addItem(flowerPicked);
        }
        tester.comboBox1.addActionListener(e -> {
            // remove previous items in comboBox2 everytime a new item in box1 is selcted
            tester.comboBox2.removeAllItems();
            String flowerChoice = tester.comboBox1.getSelectedItem().toString();
            if (flowerChoice.equalsIgnoreCase("Rose"))
                for (String colorPicked : color1) {
                    tester.comboBox2.addItem(colorPicked );
                }
            else
                for (String type : color2) {
                    tester.comboBox2.addItem(type);
                }
        });    
        tester.comboBox2.addActionListener(e -> {
            String colorChoice = tester.comboBox2.getSelectedItem().toString();
            String flowerChoice = tester.comboBox1.getSelectedItem().toString();
            system.out.println(colorChoice + " " + flowerChoice);
        });
    }

但每次我尝试在 comboBox1 中切换选择时,我总是 运行 在 removeAllItems() 和 comboBox2.getSelectedItems() 处进入 NullPointerException。

我尝试调试它,但似乎是因为每当程序执行 removeAllItems() 和 comboBox2.addItem() 时,都会调用 comboBox2 的 actionListener。我不知道如何处理这个

有点帮助?​​

你是对的,从 JComboBox 中删除所有项目会导致其 ActionListener 触发并 return 选择 null。

可能的解决方案:

  1. 在删除所有项目之前从 JComboBox 中删除所有 ActionListeners,然后在完成后替换侦听器。 -- 或者 --
  2. 不要在项目 returned 上调用 toString()(这就是抛出 NPE 的原因——在 null 引用上调用 toString())而是投射所选项目 returned 作为字符串。演员不会抛出 NPE。

第一个例子:

ActionListener[] actionListeners = tester.comboBox2.getActionListeners();
for (ActionListener actionListener : actionListeners) {
    tester.comboBox2.removeActionListener(actionListener);
}
tester.comboBox2.removeAllItems();
String flowerChoice = tester.comboBox1.getSelectedItem().toString();
if (flowerChoice.equalsIgnoreCase("Rose"))
    for (String colorPicked : color1) {
        tester.comboBox2.addItem(colorPicked);
    }
else {
    for (String type : color2) {
        tester.comboBox2.addItem(type);
    }
}
for (ActionListener actionListener : actionListeners) {
    tester.comboBox2.addActionListener(actionListener);
}

第二个例子:

String colorChoice = (String) tester.comboBox2.getSelectedItem();
String flowerChoice = (String) tester.comboBox1.getSelectedItem();
System.out.println(colorChoice + " " + flowerChoice);