简体   繁体   中英

javafx combobox items list issue

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?

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM