Combobox 对象内容更改时组合框刷新值和列表视图

Combobox 对象内容更改时组合框刷新值和列表视图,combobox,javafx,refresh,onchange,updates,Combobox,Javafx,Refresh,Onchange,Updates,当用于在组合框中显示文本的对象的内容更改时,我想更新我的组合框 以下是一个示例: package com.javafx.example.combobox; import javafx.application.Application; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.collections.FXCollecti

当用于在组合框中显示文本的对象的内容更改时,我想更新我的组合框

以下是一个示例:

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);
    }
}
package com.javafx.example.combobox;
导入javafx.application.application;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.beans.property.StringProperty;
导入javafx.collections.FXCollections;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.ComboBox;
导入javafx.scene.control.TextField;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.Priority;
导入javafx.stage.stage;
导入javafx.util.StringConverter;
公共类ComboboxSample扩展应用程序{
类序列{
public StringProperty name=new SimpleStringProperty();
公共序列(字符串名称){
超级();
this.name.set(name);
}
@凌驾
公共字符串toString(){
返回“null”;
}
}
@凌驾
public void start(Stage)引发异常{
stage.setTitle(“ComboBoxSample”);
ComboBox combo=新ComboBox();
combo.setItems(FXCollections.observableArrayList(
新序列(“Toto”),
新序列(“Titi”);
combo.getSelectionModel().selectFirst();
setConverter(新的StringConverter(){
@凌驾
公共字符串到字符串(序列){
返回sequence.name.get();
}
@凌驾
公共序列fromString(字符串){
System.out.println(“调用fromString”);
返回null;
}
});
TextField text=新的TextField();
按钮重命名按钮=新按钮(“重命名”);
重命名按钮.setOnAction(evt->combo.getValue().name.set(text.getText());
HBox root=新的HBox(组合、文本、重命名按钮);
HBox.setHgrow(文本、优先级、始终);
舞台场景(新场景(根));
stage.show();
}
公共静态void main(字符串…参数){
发射(args);
}
}
组合框包含具有属性名称的对象。如果重命名此属性,则显示不会更改,或者有时会更改,但不会一直更改。这是标准行为,因为组合框在对象更改时更新,而不是在其内容更改时更新

如何强制组合框在更改时刷新其值和listview

谢谢

编辑1:

在observaleList中使用回调似乎是一个解决方案。 包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);
    }
}
导入javafx.application.application;
导入javafx.beans.Observable;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.beans.property.StringProperty;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.ComboBox;
导入javafx.scene.control.TextField;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.Priority;
导入javafx.stage.stage;
导入javafx.util.Callback;
导入javafx.util.StringConverter;
公共类ComboboxSample扩展应用程序{
可观测序列;
类序列{
public StringProperty name=new SimpleStringProperty();
公共序列(字符串名称){
超级();
this.name.set(name);
}
@凌驾
公共字符串toString(){
返回“null”;
}
}
@凌驾
public void start(Stage)引发异常{
stage.setTitle(“ComboBoxSample”);
回调提取器=新回调(){
@凌驾
公共可观察[]调用(序列s){
返回新的可观察[]{s.name};
}
};
序列=FXCollections.observableArrayList(提取器);
序列addAll(
新序列(“Toto”),
新序列(“Titi”);
ComboBox combo=新ComboBox();
集合项(序列);
combo.getSelectionModel().selectFirst();
setConverter(新的StringConverter(){
@凌驾
公共字符串到字符串(序列){
返回sequence.name.get();
}
@凌驾
公共序列fromString(字符串){
System.out.println(“调用fromString”);
返回null;
}
});
combo.valueProperty().addListener((obs,oldValue,newValue)->System.out.println(“从“+oldValue.name.get()+”更改为“+newValue.name.get()));
TextField text=新的TextField();
按钮重命名按钮=新按钮(“重命名”);
重命名按钮。设置操作(evt->{
combo.getValue().name.set(text.getText());
});
HBox root=新的HBox(组合、文本、重命名按钮);
HBox.setHgrow(文本、优先级、始终);
舞台场景(新场景(根));
stage.show();
}
公共静态void main(字符串…参数){
发射(args);
}
}

每次向对象列表添加新值时,请再次设置组合框值。对我有用。我做了一个小例子来说明这一点。希望对你有帮助

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

}
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.geometry.Pos;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.ComboBox;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类ComboTest扩展了应用程序{
int i=0;
ObservableList=FXCollections.observableArrayList(“A”、“B”);
ComboBox combo=新ComboBox();
@凌驾
公共无效开始(阶段primaryStage){
按钮btn=新按钮();
combo.setPro