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?

Answers


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

Need Your Help

Remove pageIndicator on UIPageViewController on rotation

ios objective-c uipageviewcontroller

When in landscape, I would like the content of the UIPageViewController to be full screen, and I want to hide the page indicators. In portrait, I want to show the page indicators.

Why is no exception thrown when dismissing a ProgressDialog from a background thread?

android

I know that when I try to show ProgressDialog on background thread following exception is thrown Can't create handler inside thread that has not called Looper.prepare(),

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.