Combobox refresh value and listview when object content change

这一生的挚爱 提交于 2019-12-02 17:45:56

问题


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

回答1:


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

}


来源:https://stackoverflow.com/questions/26896290/combobox-refresh-value-and-listview-when-object-content-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!