Shaq D.
Shaq D.

Reputation: 15

JavaFX ComboBox - How to get different Prompt Text and Selected Item Text?

I've searched a bit, but couldn't find an answer. The Combobox is editable. How can I show different text in the Combobox prompt text and in the list of Objects below? In the list I want the toString method of the Object to be used, but when I select it, I want only one attribute of the selected Object to be shown in the prompt text.

How can I do this? Is it possible to display the value of an object differently in the prompt text field and in the list below?

An example of the usage would be with songs. Let's say I search a song by title, then it shows me the song with the title, composer and instrument below. When I select the song, I only want the title to be shown in the prompt text (because I display the composer and instrument Information somewhere else).

Upvotes: 1

Views: 2565

Answers (1)

fabian
fabian

Reputation: 82461

Use a converter that uses the short version for the conversion and a custom cellFactory to create cells displaying the extended version:

static class Item {
    private final String full, part;

    public Item(String full, String part) {
        this.full = full;
        this.part = part;
    }

    public String getFull() {
        return full;
    }

    public String getPart() {
        return part;
    }

}

@Override
public void start(Stage primaryStage) {
    ComboBox<Item> comboBox = new ComboBox<>(FXCollections.observableArrayList(
            new Item("AB", "A"),
            new Item("CD", "C")
    ));

    comboBox.setEditable(true);

    // use short text in textfield
    comboBox.setConverter(new StringConverter<Item>(){

        @Override
        public String toString(Item object) {
            return object == null ? null : object.getPart();
        }

        @Override
        public Item fromString(String string) {
            return comboBox.getItems().stream().filter(i -> i.getPart().equals(string)).findAny().orElse(null);
        }

    });

    comboBox.setCellFactory(lv -> new ListCell<Item>() {

        @Override
        protected void updateItem(Item item, boolean empty) {
            super.updateItem(item, empty);

            // use full text in list cell (list popup)
            setText(item == null ? null : item.getFull());
        }

    });

    Scene scene = new Scene(comboBox);

    primaryStage.setScene(scene);
    primaryStage.show();
}

Upvotes: 3

Related Questions