Combobox refresh value and listview when object content change
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);
}
}
Xavier-Alexandre BILLARD
Java software devoloper on avionics domain
Updated on June 04, 2022Comments
-
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); } }