【问题标题】:JavaFX - clearing my ComboBox set's off my listener, how do I fix this?JavaFX - 从我的听众中清除我的 ComboBox 集,我该如何解决这个问题?
【发布时间】:2014-08-17 08:31:46
【问题描述】:

我有一个问题,正如您在下面的代码中看到的那样,当我更改 cbGameType ComboBox 中的值时,它会清除 cbPlayerCount ComboBox,它会触发 cbPlayerCount 侦听器并引发错误。这会导致 ComboBox 无响应并且在设置另一个值之前不会更改 cbGameType 组合框值。设置另一个值后,程序又开始正常工作,我该如何解决这个问题?

编辑:顺便说一下,抛出这个的具体代码如下:

cbPlayerCount.getItems().clear();

编辑:整个听众都在这里

// Sets additional player for specific game type
cbGameType.valueProperty().addListener(e -> {
    cbPlayerCount.getItems().clear();
    if (!cbGameType.getValue().equals("Texas Hold 'Em")) {
        cbPlayerCount.getItems().addAll(olPlayerCount.subList(0, 6));
        cbPlayerCount.setValue(olPlayerCount.get(5));
    } else {
        cbPlayerCount.getItems().addAll(olPlayerCount.subList(1, 5));
        cbPlayerCount.setValue(olPlayerCount.get(1));
    }
});

编辑:在清除组合框时触发的 cbPlayerCount ComboBox 侦听器的代码如下。我假设正在发生的事情是它正在尝试 else 语句来设置新值,但它还没有设置值。

    // Set AI count specifically based on the number of players/game
cbPlayerCount.valueProperty().addListener(e -> {
    cbAICount.getItems().clear();
    if (cbGameType.getValue().equals("Texas Hold 'Em")) {
        if (cbPlayerCount.getValue().equals("2 Players")) {
            cbAICount.getItems().addAll(olAI.subList(0, 1));
            cbAICount.setValue(olAI.get(0));
        } else if (cbPlayerCount.getValue().equals("3 Players")) {
            cbAICount.getItems().addAll(olAI.subList(0, 2));
            cbAICount.setValue(olAI.get(1));
        } else if (cbPlayerCount.getValue().equals("4 Players")) {
            cbAICount.getItems().addAll(olAI.subList(0, 3));
            cbAICount.setValue(olAI.get(2));
        } else if (cbPlayerCount.getValue().equals("5 Players")) {
            cbAICount.getItems().addAll(olAI.subList(0, 4));
            cbAICount.setValue(olAI.get(3));
        } else if (cbPlayerCount.getValue().equals("6 Players")) {
            cbAICount.getItems().addAll(olAI.subList(0, 5));
            cbAICount.setValue(olAI.get(4));
        }
    } else {
        if (cbPlayerCount.getValue().equals("1 Player") ||
                cbPlayerCount.getValue().equals("2 Players")) {
            cbAICount.setVisible(false);
        } else if (cbPlayerCount.getValue().equals("3 Players")) {
            cbAICount.setVisible(true);
            cbAICount.getItems().addAll(olAI.subList(0, 1));
            cbAICount.setValue(olAI.get(0));
        } else if (cbPlayerCount.getValue().equals("4 Players")) {
            cbAICount.setVisible(true);
            cbAICount.getItems().addAll(olAI.subList(0, 2));
            cbAICount.setValue(olAI.get(1));
        } else if (cbPlayerCount.getValue().equals("5 Players")) {
            cbAICount.setVisible(true);
            cbAICount.getItems().addAll(olAI.subList(0, 3));
            cbAICount.setValue(olAI.get(2));
        } else if (cbPlayerCount.getValue().equals("6 Players")) {
            cbAICount.setVisible(true);
            cbAICount.getItems().addAll(olAI.subList(0, 4));
            cbAICount.setValue(olAI.get(3));
        }
    }
});

这是剩下的代码

Stage newGameStage = new Stage();
    VBox pane = new VBox(5);

    // Label and ComboBox for gameType selection
    BorderPane gameTypePane = new BorderPane();
    ComboBox<String> cbGameType = new ComboBox<>();
    cbGameType.setPrefWidth(160);
    cbGameType.getItems().addAll("Texas Hold 'Em", "7-Card Stud",
        "Omaha", "5-Card Draw", "High/Low Chicago", "Follow the Queen",
        "BlackJack");
    cbGameType.setValue("Texas Hold 'Em");
    Label lbGameType = new Label("Game Type:");
    lbGameType.setAlignment(Pos.CENTER_LEFT);
    gameTypePane.setLeft(lbGameType);
    gameTypePane.setRight(cbGameType);
    BorderPane.setAlignment(cbGameType, Pos.CENTER_RIGHT);
    pane.getChildren().add(gameTypePane);

    // Label and ComboBox for number of Players
    BorderPane playerCountPane = new BorderPane();
    ObservableList<String> olPlayerCount =
        FXCollections.observableArrayList( "1 Player", "2 Players",
            "3 Players", "4 Players", "5 Players", "6 Players");
    ComboBox<String> cbPlayerCount = new ComboBox<>();
    cbPlayerCount.getItems().addAll(olPlayerCount.subList(1, 6));
    cbPlayerCount.setValue(olPlayerCount.get(5));
    Label lbPlayerCount = new Label("Select Players");
    lbPlayerCount.setAlignment(Pos.CENTER_LEFT);
    playerCountPane.setLeft(lbPlayerCount);
    playerCountPane.setRight(cbPlayerCount);
    BorderPane.setAlignment(cbPlayerCount, Pos.CENTER_RIGHT);
    pane.getChildren().add(playerCountPane);

    // Label and ComboBox for selecting the number of AI Players
    BorderPane aiCountPane = new BorderPane();
    ObservableList<String> olAI = FXCollections.observableArrayList(
            "1 AI", "2 AI", "3 AI",
            "4 AI", "5 AI");
    ComboBox<String> cbAICount = new ComboBox<>();
    cbAICount.getItems().addAll(olAI.subList(0, 5));
    cbAICount.setValue(olAI.get(4));
    Label lbAICount = new Label("How many AI: ");
    lbAICount.setAlignment(Pos.CENTER_LEFT);
    aiCountPane.setLeft(lbAICount);
    aiCountPane.setRight(cbAICount);
    BorderPane.setAlignment(cbAICount, Pos.CENTER_RIGHT);
    pane.getChildren().add(aiCountPane);

    // Sets additional player for specific game type
    cbGameType.valueProperty().addListener(e -> {
        cbPlayerCount.getItems().clear();
        if (!cbGameType.getValue().equals("Texas Hold 'Em")) {
            cbPlayerCount.getItems().addAll(olPlayerCount.subList(0, 6));
            cbPlayerCount.setValue(olPlayerCount.get(5));
        } else {
            cbPlayerCount.getItems().addAll(olPlayerCount.subList(1, 5));
            cbPlayerCount.setValue(olPlayerCount.get(1));
        }
    });

    // Set AI count specifically based on the number of players/game
    cbPlayerCount.valueProperty().addListener(e -> {
        cbAICount.getItems().clear();
        if (cbGameType.getValue().equals("Texas Hold 'Em")) {
            if (cbPlayerCount.getValue().equals("2 Players")) {
                cbAICount.getItems().addAll(olAI.subList(0, 1));
                cbAICount.setValue(olAI.get(0));
            } else if (cbPlayerCount.getValue().equals("3 Players")) {
                cbAICount.getItems().addAll(olAI.subList(0, 2));
                cbAICount.setValue(olAI.get(1));
            } else if (cbPlayerCount.getValue().equals("4 Players")) {
                cbAICount.getItems().addAll(olAI.subList(0, 3));
                cbAICount.setValue(olAI.get(2));
            } else if (cbPlayerCount.getValue().equals("5 Players")) {
                cbAICount.getItems().addAll(olAI.subList(0, 4));
                cbAICount.setValue(olAI.get(3));
            } else if (cbPlayerCount.getValue().equals("6 Players")) {
                cbAICount.getItems().addAll(olAI.subList(0, 5));
                cbAICount.setValue(olAI.get(4));
            }
        } else {
            if (cbPlayerCount.getValue().equals("1 Player") ||
                    cbPlayerCount.getValue().equals("2 Players")) {
                cbAICount.setVisible(false);
            } else if (cbPlayerCount.getValue().equals("3 Players")) {
                cbAICount.setVisible(true);
                cbAICount.getItems().addAll(olAI.subList(0, 1));
                cbAICount.setValue(olAI.get(0));
            } else if (cbPlayerCount.getValue().equals("4 Players")) {
                cbAICount.setVisible(true);
                cbAICount.getItems().addAll(olAI.subList(0, 2));
                cbAICount.setValue(olAI.get(1));
            } else if (cbPlayerCount.getValue().equals("5 Players")) {
                cbAICount.setVisible(true);
                cbAICount.getItems().addAll(olAI.subList(0, 3));
                cbAICount.setValue(olAI.get(2));
            } else if (cbPlayerCount.getValue().equals("6 Players")) {
                cbAICount.setVisible(true);
                cbAICount.getItems().addAll(olAI.subList(0, 4));
                cbAICount.setValue(olAI.get(3));
            }
        }
    });

这是第一次更改 cbGameType ComboBox 中的值时引发的错误

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at Casino_Poker.Main.lambda$newGame$2(Main.java:200)
at Casino_Poker.Main$$Lambda$5/624953014.invalidated(Unknown Source)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:339)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:145)
at javafx.scene.control.ComboBoxBase.setValue(ComboBoxBase.java:167)
at javafx.scene.control.ComboBox.updateValue(ComboBox.java:449)
at javafx.scene.control.ComboBox.access$300(ComboBox.java:164)
at javafx.scene.control.ComboBox$6.changed(ComboBox.java:434)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:347)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.beans.property.ReadOnlyObjectWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyObjectWrapper.java:176)
at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:142)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:145)
at javafx.scene.control.SelectionModel.setSelectedItem(SelectionModel.java:102)
at javafx.scene.control.ComboBox$ComboBoxSelectionModel$1.invalidated(ComboBox.java:481)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:135)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.beans.property.ReadOnlyIntegerWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:176)
at javafx.beans.property.ReadOnlyIntegerWrapper.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:142)
at javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)
at javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:146)
at javafx.scene.control.SelectionModel.setSelectedIndex(SelectionModel.java:68)
at javafx.scene.control.ComboBox$ComboBoxSelectionModel$2.onChanged(ComboBox.java:504)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:315)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:72)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at com.sun.javafx.collections.ObservableListWrapper.clear(ObservableListWrapper.java:155)
at Casino_Poker.Main.lambda$newGame$1(Main.java:169)
at Casino_Poker.Main$$Lambda$4/1075013361.invalidated(Unknown Source)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:339)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:145)
at javafx.scene.control.ComboBoxBase.setValue(ComboBoxBase.java:167)
at javafx.scene.control.ComboBox.updateValue(ComboBox.java:449)
at javafx.scene.control.ComboBox.access$300(ComboBox.java:164)
at javafx.scene.control.ComboBox$6.changed(ComboBox.java:434)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:347)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.beans.property.ReadOnlyObjectWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyObjectWrapper.java:176)
at javafx.beans.property.ReadOnlyObjectWrapper.fireValueChangedEvent(ReadOnlyObjectWrapper.java:142)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:145)
at javafx.scene.control.SelectionModel.setSelectedItem(SelectionModel.java:102)
at javafx.scene.control.ComboBox$ComboBoxSelectionModel$1.invalidated(ComboBox.java:481)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:135)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.beans.property.ReadOnlyIntegerWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:176)
at javafx.beans.property.ReadOnlyIntegerWrapper.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:142)
at javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)
at javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:146)
at javafx.scene.control.SelectionModel.setSelectedIndex(SelectionModel.java:68)
at javafx.scene.control.SingleSelectionModel.updateSelectedIndex(SingleSelectionModel.java:215)
at javafx.scene.control.SingleSelectionModel.select(SingleSelectionModel.java:149)
at com.sun.javafx.scene.control.skin.ComboBoxListViewSkin$9.invalidated(ComboBoxListViewSkin.java:594)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:339)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:80)
at javafx.beans.property.ReadOnlyIntegerWrapper$ReadOnlyPropertyImpl.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:176)
at javafx.beans.property.ReadOnlyIntegerWrapper.fireValueChangedEvent(ReadOnlyIntegerWrapper.java:142)
at javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)
at javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:146)
at javafx.scene.control.SelectionModel.setSelectedIndex(SelectionModel.java:68)
at javafx.scene.control.MultipleSelectionModelBase.select(MultipleSelectionModelBase.java:341)
at javafx.scene.control.MultipleSelectionModelBase.clearAndSelect(MultipleSelectionModelBase.java:309)
at com.sun.javafx.scene.control.behavior.ListCellBehavior.simpleSelect(ListCellBehavior.java:268)
at com.sun.javafx.scene.control.behavior.ListCellBehavior.doSelect(ListCellBehavior.java:208)
at com.sun.javafx.scene.control.behavior.ListCellBehavior.mousePressed(ListCellBehavior.java:127)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:95)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:204)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3746)
at javafx.scene.Scene$MouseHandler.access$1800(Scene.java:3471)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1695)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2486)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:314)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:243)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:345)
at com.sun.glass.ui.View.handleMouseEvent(View.java:526)
at com.sun.glass.ui.View.notifyMouse(View.java:898)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
at java.lang.Thread.run(Thread.java:745)

【问题讨论】:

    标签: java combobox listener javafx-8


    【解决方案1】:

    当组合框被清除时,value 属性设置为null。所以像cbPlayerCount.getValue().equals("2 Players") 这样的语句会抛出一个空指针异常(试图在空引用上调用equals(...) 方法)。

    您有几个选项,具体取决于您要实现的逻辑。您可以使用Objects.equals(...) 进行比较,这将对每个参数进行适当的空检查:

    if (Objects.equals(cbPlayerCount.getValue(), "2 Players")) {
        //...
    }
    

    或者您可以将侦听器的内容包装在

    if (cbPlayerCount.getValue() != null) {
      //...
    }
    

    对于第二个选项,如果没有真正选择任何值,则可能值得考虑是否要对其他组合框进行一些更改。

    【讨论】:

    • 再次感谢@James_D
    【解决方案2】:

    James_D,我在调试器中设置了一个断点并意识到你在说什么。基本上在清除 cbPlayerCount 后,它会从 cbGameType 侦听器跳转到 cbPlayerCount 侦听器。然后它试图在 cbPlayerCount 上执行 'getvalue.equals()' 方法,正如你指出的那样,它是空的。之后它会跳回到 cbGameType 监听器的最后一行并继续添加和设置值。所以最后设置一个 null 的条件就像你上面所说的那样是我解决问题所需要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-25
      • 2020-02-14
      • 2021-07-31
      • 2020-12-28
      • 2019-12-03
      相关资源
      最近更新 更多