MrPisarik MrPisarik - 4 months ago 29
Java Question

ComboBox strange behaviour (JavaFX 8)

I have this code in start method:

ObservableList<StringBuilder> list = FXCollections.observableArrayList();
list.add(new StringBuilder("0"));
list.add(new StringBuilder("1"));
list.add(new StringBuilder("2"));
list.add(new StringBuilder("3"));
list.add(new StringBuilder("4"));
list.add(new StringBuilder("5"));
list.add(new StringBuilder("6"));
list.add(new StringBuilder("7"));
list.add(new StringBuilder("8"));
list.add(new StringBuilder("9"));

ComboBox<StringBuilder> combo = new ComboBox<>(list);
Button change = new Button("change");
change.setOnAction((event) -> {
list.set(5, new StringBuilder("-"));
});

BorderPane borderPane = new BorderPane(combo, null, null, change, null);
Scene scene = new Scene(borderPane);
primaryStage.setScene(scene);
primaryStage.show();


I start my program and select second item and then I click on "change" button several times. Nothing happens and it's good.
But If I select item "6" and click on "change" button then comboBox autoselects next item ("7").
Why does it happen?

Then we can change the row

list.set(5, new StringBuilder("-");


on

list.remove(5);


Then if I select item "2" and click "change" button then nothing happens. And again if I select item "9" and click "change" button then comboBox autoselects previous item ("8").

I expect that if I just change item, i.e. use set method of list, then comboBox doesn't change selection. How to cope with it?

Answer

I am not sure why this is happening, this might have something to do with the way ComboBox handles ObservabeList in it. But this cannot be replicated using ChoiceBox. Can you please raise a JIRA with the JavaFX team, so that they can have a look at it?

As a turnaround, you may do the following in your code to fix it temporarily :

ComboBox<String> combo = new ComboBox<String>(list);
Button change = new Button("change");
change.setOnAction((event) -> {
    StringBuilder str = combo.getValue();
    list.set(5, new String("-"));
    combo.setValue(str);
});