【问题标题】:JavaFX 11 Editable ComboBox throws IndexOutOfBoundsExceptionJavaFX 11 可编辑组合框抛出 IndexOutOfBoundsException
【发布时间】:2021-05-09 18:10:00
【问题描述】:

我一直在努力为可编辑的ComboBox 实现一个事件侦听器,它会将已编辑的项目添加到应用程序列表的末尾,但是当提交已编辑的项目时会抛出IndexOutOfBoundsException。我不明白为什么会这样。

因此,我创建了一个简化的应用程序,如下所示,并尝试将添加编辑项的代码包含在 Platform.runLater() 块中,但问题仍然存在。

任何人都可以建议可能导致此异常的原因吗?

非常感谢。

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;

public class ComboBoxTest extends Application {
    ComboBox<String> cbItems;
    Label lblResponse;

    public static void main(String[] args) {
        launch(args);
    }

    public void start(Stage stage) {
        stage.setTitle("ComboBox Demo");
        FlowPane root = new FlowPane(10, 10);
        root.setAlignment(Pos.TOP_CENTER);
        Scene scene = new Scene(root, 240, 120);
        stage.setScene(scene);
        lblResponse = new Label();
        ObservableList<String> items =
                FXCollections.observableArrayList("item1", "item2", "item3", "item4", "item5");
        cbItems = new ComboBox<String>(items);
        cbItems.setValue("item1");
        cbItems.setEditable(true);
        lblResponse.setText("Selected item is " + cbItems.getValue());

        // Listen for action events on the combo box.
        cbItems.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent ae) {
                lblResponse.setText("Selected item is " + cbItems.getValue());

                //add the modified item to the end of the list
                int i = cbItems.getSelectionModel().getSelectedIndex();
                if(!items.get(i).equals(cbItems.getValue())){
                    items.add(cbItems.getValue());
                }
            }
        });
        root.getChildren().addAll(cbItems, lblResponse);
        stage.show();
    }
}

【问题讨论】:

  • 欢迎来到 StackOverflow!第一个问题好!您甚至可以通过添加确切的错误消息和堆栈跟踪来改进它。

标签: java javafx-11


【解决方案1】:

查看堆栈跟踪的[开始]...

Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 5
    at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
    at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
    at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
    at java.base/java.util.Objects.checkIndex(Objects.java:359)
    at java.base/java.util.ArrayList.get(ArrayList.java:427)
    at javafx.base/com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
    at jfxprjct/jfxtests.ComboBoxTest$1.handle(ComboBoxTest.java:52)

现在查看文件 ComboBoxTest.java 中的第 52 行。
(请注意,它可能是堆栈跟踪中的不同行号。)
对我来说,这是第 52 行

if(!items.get(i).equals(cbItems.getValue())){

换句话说,i 的值是-1(减一)。并且iif 语句之前的行中被分配了一个值。

int i = cbItems.getSelectionModel().getSelectedIndex();

换句话说,没有没有选定的索引。所以你应该首先检查i的值,而不是假设它是一个有效的索引值。

但是,更好的条件(在我看来)是

if(!cbItems.getItems().contains(cbItems.getValue())){

那么你根本不需要选中的索引。

【讨论】:

  • 谢谢。我错误地认为编辑后的项目会保留与最初选择的项目相同的 inex。您建议的替代方案更优雅并解决了问题。
猜你喜欢
  • 2014-07-21
  • 1970-01-01
  • 2012-12-03
  • 1970-01-01
  • 2014-10-23
  • 1970-01-01
  • 1970-01-01
  • 2018-01-08
  • 2014-06-18
相关资源
最近更新 更多