Combobox refresh value and listview when object content change

12,325

Everytime a new value is added to the object list, set the combobox value again. Works for me. I did a small example to show this. Hope it is helpful

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;


public class ComboTest extends Application {
    int i =0;
    ObservableList<String> list = FXCollections.observableArrayList("A","B");
    ComboBox<String> combo = new ComboBox();
    @Override
    public void start(Stage primaryStage) {
        Button btn = new Button();
        combo.setPromptText("Testing combobox");
        combo.setPrefWidth(300);
        btn.setText("Add items to list");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                list.add(String.valueOf(i));
                System.out.println("size of list " + list.size() );
                i++;
               combo.setItems(list);
            }
        });
        combo.setItems(list);
        VBox root = new VBox();
        root.getChildren().addAll(btn,combo);
        root.setSpacing(20);
        root.setAlignment(Pos.CENTER);
        Scene scene = new Scene(root);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}
Share:
12,325
Xavier-Alexandre BILLARD
Author by

Xavier-Alexandre BILLARD

Java software devoloper on avionics domain

Updated on June 04, 2022

Comments

  • Xavier-Alexandre BILLARD
    Xavier-Alexandre BILLARD almost 2 years

    I would like to update my combobox when the content of the object used to display text in combo changes.

    Here is a sample:

    package com.javafx.example.combobox;
    
    import javafx.application.Application;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    import javafx.collections.FXCollections;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.ComboBox;
    import javafx.scene.control.TextField;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.Priority;
    import javafx.stage.Stage;
    import javafx.util.StringConverter;
    
    public class ComboboxSample extends Application {
    
    
        class Sequence {
            public StringProperty name = new SimpleStringProperty();
    
            public Sequence(String name) {
                super();
                this.name.set(name);
            }
    
            @Override
            public String toString() {
                return "null";
            }
        }
    
        @Override
        public void start(Stage stage) throws Exception {
            stage.setTitle("ComboBoxSample");
    
            ComboBox<Sequence> combo = new ComboBox<>();
            combo.setItems(FXCollections.observableArrayList(
                    new Sequence("Toto"),
                    new Sequence("Titi")));
            combo.getSelectionModel().selectFirst();
            combo.setConverter(new StringConverter<ComboboxSample.Sequence>() {
                @Override
                public String toString(Sequence sequence) {
                    return sequence.name.get();
                }
    
                @Override
                public Sequence fromString(String string) {
                    System.out.println("call fromString");
                    return null;
                }
            });
    
            TextField text = new TextField();
            Button renameButton = new Button("Rename");
    
            renameButton.setOnAction(evt -> combo.getValue().name.set(text.getText()));
    
            HBox root = new HBox(combo, text, renameButton);
            HBox.setHgrow(text, Priority.ALWAYS);
    
            stage.setScene(new Scene(root));
            stage.show();
    
        }
    
        public static void main(String... args) {
            launch(args);
        }
    }
    

    The combobox contains objects with a property name. If i rename this property, the display do not change or sometimes it changes but not all the time. It is the standard behavior as the combobox update when the object changes, and not when its content changes.

    How can i do to force the combobox to refresh its value and the listview on change?

    Thanks

    EDIT1:

    Using a callback in an observaleList seems to be a solution. package com.javafx.example.combobox;

    import javafx.application.Application;
    import javafx.beans.Observable;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.ComboBox;
    import javafx.scene.control.TextField;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.Priority;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    import javafx.util.StringConverter;
    
    public class ComboboxSample extends Application {
    
        ObservableList<Sequence> sequences;
    
    
        class Sequence {
            public StringProperty name = new SimpleStringProperty();
    
            public Sequence(String name) {
                super();
                this.name.set(name);
            }
    
            @Override
            public String toString() {
                return "null";
            }
        }
    
        @Override
        public void start(Stage stage) throws Exception {
            stage.setTitle("ComboBoxSample");
    
            Callback<Sequence, Observable[]> extractor = new Callback<Sequence, Observable[]>() {
                @Override
                public Observable[] call(Sequence s) {
                    return new Observable[] {s.name};
                }
            };
            sequences = FXCollections.observableArrayList(extractor);
            sequences.addAll(
                    new Sequence("Toto"),
                    new Sequence("Titi"));
    
            ComboBox<Sequence> combo = new ComboBox<>();
            combo.setItems(sequences);
            combo.getSelectionModel().selectFirst();
            combo.setConverter(new StringConverter<ComboboxSample.Sequence>() {
                @Override
                public String toString(Sequence sequence) {
                    return sequence.name.get();
                }
    
                @Override
                public Sequence fromString(String string) {
                    System.out.println("call fromString");
                    return null;
                }
            });
            combo.valueProperty().addListener((obs, oldValue, newValue) -> System.out.println("Change from " + oldValue.name.get() + " to " + newValue.name.get())); 
    
            TextField text = new TextField();
            Button renameButton = new Button("Rename");
    
            renameButton.setOnAction(evt -> {
                combo.getValue().name.set(text.getText());
            });
    
            HBox root = new HBox(combo, text, renameButton);
            HBox.setHgrow(text, Priority.ALWAYS);
    
            stage.setScene(new Scene(root));
            stage.show();
    
        }
    
        public static void main(String... args) {
            launch(args);
        }
    }