Reputation: 23
I am trying to use a JavaFX ComboBox
as a search field with history.
This is a sample of my code.
ObservableList<String> patternHistory = FXCollections.observableArrayList();
searchComboBox.setItems(patternHistory);
searchComboBox.valueProperty().addListener((observable, oldValue, newValue) -> {
ObservableList<String> history = searchComboBox.getItems();
// This works fine
// history.add(newValue);
// This does not work
history.add(0, newValue);
});
If I do the history.add(newValue)
the ComboBox
behaves as I expect.
The last entry in the history is added to the end of the list.
However, I would like the last entry to be shown first (I also want to remove duplicates and limit the history size but I keep it simple in this example).
So I decided to simply add the new value in front of the list with history.add(0, newValue)
.
However, when I do that the combobox start to behaves in strange ways and the code does not work anymore. It seems that as long I add/delete items at the end of the list it works fine but if I do the same at the beginning or in the middle it does not work anymore.
Here I'm using the lambda expression syntax but I have tried with the anonymous class notation and it's the same. I also tried to implement my own observable list and there also it's the same result.
I'm currently using JDK 1.8.0_60 but I had the problem with earlier version. Can somebody tell me if there is a way to fix this issue or if I'm doing something wrong?
Upvotes: 1
Views: 2485
Reputation: 209225
A workaround seems to be to replace all the items in the list. The following seems to work OK:
import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HistoryListComboBox extends Application {
@Override
public void start(Stage primaryStage) {
ComboBox<String> combo = new ComboBox<>();
combo.getItems().addAll("One", "Two", "Three");
combo.setEditable(true);
combo.valueProperty().addListener((obs, oldValue, newValue) -> {
if (! combo.getItems().contains(newValue)) {
List<String> newItems = new ArrayList<>();
newItems.add(newValue);
newItems.addAll(combo.getItems());
combo.getItems().setAll(newItems);
}
});
StackPane root = new StackPane(combo);
primaryStage.setScene(new Scene(root, 350, 120));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Upvotes: 1