gpt4 book ai didi

JavaFX 将选择框绑定(bind)到集合中的属性

转载 作者:行者123 更新时间:2023-11-30 02:50:34 24 4
gpt4 key购买 nike

使用 JavaFX,将 ChoiceBox 绑定(bind)到集合属性的最佳方法是什么?在下面的示例中,我尝试将 ChoiceBox 元素绑定(bind)到 ObservableList beansname。这在添加/删除项目时工作正常,但在属性值名称更改时则不然。

我希望有一个干净而简单的解决方案,但尚未找到任何示例......

ExampleBean2 故意不使用属性实现,因为该对象可能对应于我无法控制的外部模型类。

package com.playground;

import org.controlsfx.control.PropertySheet;
import org.controlsfx.property.BeanPropertyUtils;

import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ListView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

public class BindingPlayGround extends Application{

public static void main(String[] args) {
launch();
}

@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("FXPlayGround");
Parent content = createContentPane();
Scene scene = new Scene(content, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
}

protected Parent createContentPane() {
ObservableList<BeanExample2> beans = FXCollections.observableArrayList();
ObservableList<PropertySheet> sheets = FXCollections.observableArrayList();
ListView<PropertySheet> listView = new ListView<PropertySheet>(sheets);
Button addBeanButton = new Button("Add Bean");
addBeanButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
BeanExample2 e = new BeanExample2();
e.setName("Name-not-set");
PropertySheet propertySheet = new PropertySheet(BeanPropertyUtils.getProperties(e));
sheets.add(propertySheet);
beans.add(e);
}
});

VBox vBar = new VBox();
vBar.getChildren().add(listView);
vBar.getChildren().add(addBeanButton);
ObservableList<BeanExample2> names = FXCollections.observableArrayList(new Callback<BeanExample2, Observable[]>() {
@Override
public Observable[] call(BeanExample2 param) {
return new Observable[]{new SimpleStringProperty(param, "name")};
}
});
Bindings.bindContent(names, beans);

Button addChoiceBoxButton = new Button("Add ChoiceBox");
addChoiceBoxButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
ChoiceBox<BeanExample2> choiceBox = new ChoiceBox<BeanExample2>(names);
vBar.getChildren().add(choiceBox);
}
});
vBar.getChildren().add(addChoiceBoxButton);
return vBar;
}

static class BeanExample2 {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "BeanExample2{" +
"name='" + name + '\'' +
'}';
}
}
}

最佳答案

这里

ObservableList<BeanExample2> names = FXCollections.observableArrayList(new Callback<BeanExample2, Observable[]>() {
@Override
public Observable[] call(BeanExample2 param) {
return new Observable[]{new SimpleStringProperty(param, "name")};
}
});

您正在创建一个新属性来监听除 call 方法返回的值之外无法引用的更新。 BeanExample2 实例和 SimpleStringProperty 之间的唯一关系是 BeanExample2 实例用作属性的 bean,除了可通过属性的 getBean() 方法获取。该属性的值永远不会被分配,更不用说在 BeanExample2 实例发生更改时进行修改。

要正确触发 ObservableList 中的更新,您需要确保上述方法返回的数组中的元素实际上收到了更新通知。通常,您将属性添加到类本身:

public static class BeanExample2 {

public final String getName() {
return this.name.get();
}

private final StringProperty name = new SimpleStringProperty();

public final void setName(String value) {
this.name.set(value);
}

@Override
public String toString() {
return "BeanExample2{"
+ "name='" + name.get() + '\''
+ '}';
}

public final StringProperty nameProperty() {
return this.name;
}
}

并返回一个包含来自回调的属性的数组

ObservableList<BeanExample2> names = FXCollections.observableArrayList(new Callback<BeanExample2, Observable[]>() {
@Override
public Observable[] call(BeanExample2 param) {
return new Observable[]{param.nameProperty()};
}
});

请注意,目前 ChoiceBox 中似乎存在一个错误,它将每个中间值的条目添加到 ChoiceBox 中。

ComboBox 不存在此问题,可以用来代替 ChoiceBox

关于JavaFX 将选择框绑定(bind)到集合中的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38785215/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com