Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
246 views
in Technique[技术] by (71.8m points)

java - JavaFX 11 Editable ComboBox throws IndexOutOfBoundsException

I have been endeavoring to implement an event listener for an editable ComboBox which will add the edited item to the end of the list in an application, but this throws IndexOutOfBoundsException when the edited item is committed. I do not understand why this should be.

Consequently I have created a simplified application as follows and also tried enclosing the code which adds the edited item in a Platform.runLater() block but the issue persists.

Can anybody please suggest what may be causing this exception?

Thanks very much.

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();
    }
}
question from:https://stackoverflow.com/questions/66062626/javafx-11-editable-combobox-throws-indexoutofboundsexception

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Look at [the start of] the stack trace...

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)

Now look at line 52 in file ComboBoxTest.java.
(Note that it may be a different line number in your stack trace.)
For me, this is line 52

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

In other words, the value of i is -1 (minus one). And i is assigned a value in the line preceding the if statement.

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

In other words, there is no selected index. So you should first check the value of i and not assume that it is a valid index value.

However, a better condition (in my opinion) would be

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

Then you don't need the selected index at all.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...