Javafx 2 动态JavaFX绑定
我的应用程序必须处理动态绑定。 我有一个JavaBean对象列表,其中有许多必须编辑的属性。 存在具有不同属性的多种类型的对象 我创建一个树状视图来列出对象。 每次在TreeView中选择一个对象时,我都会更新屏幕中的第二个容器,在其中动态创建绑定到当前对象属性的标签和文本字段 我使用JavaBeanStringProperty、JavaBeanIntegerProperty和这个家族的其他对象来创建一个与javabean交互的属性。那很好用。 我将这些JavaBeanProperty对象中的每一个链接到它们对应的TextField的TextAttribute,以便在UI更改时更新Bean,反之亦然 问题是:每次我在TreeView中选择一个新的JavaBean时,以前动态创建的所有对象似乎都仍然是活动的。我第一次选择Bean并编辑它时,它会起作用,但第二次,它就不起作用了 我尝试创建已创建绑定的列表,以便在选择新Bean时可以解除绑定,但这是不可能的,因为StringProperties和IntegerProperty不共享公共接口,所以我可以解除绑定 有人知道如何应对吗 例如: 豆类及其特性:Javafx 2 动态JavaFX绑定,javafx-2,Javafx 2,我的应用程序必须处理动态绑定。 我有一个JavaBean对象列表,其中有许多必须编辑的属性。 存在具有不同属性的多种类型的对象 我创建一个树状视图来列出对象。 每次在TreeView中选择一个对象时,我都会更新屏幕中的第二个容器,在其中动态创建绑定到当前对象属性的标签和文本字段 我使用JavaBeanStringProperty、JavaBeanIntegerProperty和这个家族的其他对象来创建一个与javabean交互的属性。那很好用。 我将这些JavaBeanProperty对象中的每
- Bean1:名称(字符串)、金额(整数)
- Bean2:名称(字符串)、类型(字符串)
- Bean3:名称(字符串)、地址(字符串)
- 一个表示名称的TextField,一个与Bean接口的JavaBeanStringProperty,并将其与文本字段的TextProperty双向绑定
- 一个表示数量的TextField,一个与Bean接口的JavaBeanIntegerProperty,并使用NumberConverter将其与文本字段的TextProperty双向绑定
- 一个表示名称的TextField,一个与Bean接口的JavaBeanStringProperty,并将其与文本字段的TextProperty双向绑定
- 一个表示类型的TextField,一个与Bean接口的JavaBeanStringProperty,并将其与文本字段的TextProperty双向绑定
- 一个表示名称的TextField,一个与Bean接口的JavaBeanStringProperty,并将其与文本字段的TextProperty双向绑定
- 一个表示地址的TextField,一个与Bean接口的JavaBeanStringProperty,并将其与文本字段的TextProperty双向绑定
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.lang.ref.WeakReference;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.adapter.JavaBeanIntegerProperty;
import javafx.beans.property.adapter.JavaBeanIntegerPropertyBuilder;
import javafx.beans.property.adapter.JavaBeanStringProperty;
import javafx.beans.property.adapter.JavaBeanStringPropertyBuilder;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.converter.NumberStringConverter;
public class Main extends Application {
//=============================================================================================
public abstract class Bean {
public abstract void createUI(Pane container);
}
//=============================================================================================
public class Bean1 extends Bean {
private String name;
private int amount;
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public Bean1(String name, int amount) {
this.name = name;
this.amount = amount;
}
public String toString() { return name; }
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
System.out.println("Bean 1 PCS has " + pcs.getPropertyChangeListeners().length + " listeners. 1 was possuibly added.");
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener);
System.out.println("Bean 1 PCS has " + pcs.getPropertyChangeListeners().length + " listeners. 1 was possuibly removed.");
}
public String getName() { return name; }
public void setName(String name) {
String last = this.name;
this.name = name;
pcs.firePropertyChange("name", last, this.name);
System.out.println("Bean 1: name changed: " + last + " -> " + this.name);
}
public int getAmount() { return amount; }
public void setAmount(int amount) {
int last = this.amount;
this.amount = amount;
pcs.firePropertyChange("amount", last, this.amount);
System.out.println("Bean 1: amount changed: " + last + " -> " + this.amount);
}
public void createUI(Pane container) {
HBox nameContainer = new HBox();
Label nameLabel = new Label("name: ");
nameLabel.setPrefWidth(80);
TextField nameValue = new TextField();
nameValue.setPrefWidth(140);
try {
JavaBeanStringProperty wrapper = new JavaBeanStringPropertyBuilder().bean(this).name("name").build();
nameValue.textProperty().bindBidirectional(wrapper);
} catch (NoSuchMethodException e) {
e.printStackTrace();
System.out.println("Exception binding Bean 1 name property.");
}
nameContainer.getChildren().addAll(nameLabel, nameValue);
HBox amountContainer = new HBox();
Label amountLabel = new Label("amount: ");
amountLabel.setPrefWidth(80);
TextField amountValue = new TextField();
amountValue.setPrefWidth(140);
try {
JavaBeanIntegerProperty wrapper = new JavaBeanIntegerPropertyBuilder().bean(this).name("amount").build();
Bindings.bindBidirectional(amountValue.textProperty(), wrapper, new NumberStringConverter());
} catch (NoSuchMethodException e) {
e.printStackTrace();
System.out.println("Exception binding Bean 1 amount property.");
}
amountContainer.getChildren().addAll(amountLabel, amountValue);
container.getChildren().clear();
container.getChildren().addAll(nameContainer, amountContainer);
}
}
//=============================================================================================
public class Bean2 extends Bean {
private String name;
private String type;
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public Bean2(String name, String type) {
this.name = name;
this.type = type;
}
public String toString() { return name; }
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
System.out.println("Bean 2 PCS has " + pcs.getPropertyChangeListeners().length + " listeners. 1 was possuibly added.");
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener);
System.out.println("Bean 2 PCS has " + pcs.getPropertyChangeListeners().length + " listeners. 1 was possuibly removed.");
}
public String getName() { return name; }
public void setName(String name) {
String last = this.name;
this.name = name;
pcs.firePropertyChange("name", last, this.name);
System.out.println("Bean 2: name changed: " + last + " -> " + this.name);
}
public String getType() { return type; }
public void setType(String type) {
String last = this.type;
this.type = type;
pcs.firePropertyChange("type", last, this.type);
System.out.println("Bean 2: type changed: " + last + " -> " + this.type);
}
public void createUI(Pane container) {
HBox nameContainer = new HBox();
Label nameLabel = new Label("name: ");
nameLabel.setPrefWidth(80);
TextField nameValue = new TextField();
nameValue.setPrefWidth(140);
try {
JavaBeanStringProperty wrapper = new JavaBeanStringPropertyBuilder().bean(this).name("name").build();
nameValue.textProperty().bindBidirectional(wrapper);
} catch (NoSuchMethodException e) {
e.printStackTrace();
System.out.println("Exception binding Bean 2 name property.");
}
nameContainer.getChildren().addAll(nameLabel, nameValue);
HBox typeContainer = new HBox();
Label typeLabel = new Label("type: ");
typeLabel.setPrefWidth(80);
TextField typeValue = new TextField();
typeValue.setPrefWidth(140);
try {
JavaBeanStringProperty wrapper = new JavaBeanStringPropertyBuilder().bean(this).name("type").build();
typeValue.textProperty().bindBidirectional(wrapper);
} catch (NoSuchMethodException e) {
e.printStackTrace();
System.out.println("Exception binding Bean 2 type property.");
}
typeContainer.getChildren().addAll(typeLabel, typeValue);
container.getChildren().clear();
container.getChildren().addAll(nameContainer, typeContainer);
}
}
//=============================================================================================
public class Bean3 extends Bean {
private String name;
private String address;
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public Bean3(String name, String address) {
this.name = name;
this.address = address;
}
public String toString() { return name; }
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
System.out.println("Bean 3 PCS has " + pcs.getPropertyChangeListeners().length + " listeners. 1 was possuibly added.");
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener);
System.out.println("Bean 3 PCS has " + pcs.getPropertyChangeListeners().length + " listeners. 1 was possuibly removed.");
}
public String getName() { return name; }
public void setName(String name) {
String last = this.name;
this.name = name;
pcs.firePropertyChange("name", last, this.name);
System.out.println("Bean 3: name changed: " + last + " -> " + this.name);
}
public String getAddress() { return address; }
public void setAddress(String address) {
String last = this.address;
this.address = address;
pcs.firePropertyChange("type", last, this.address);
System.out.println("Bean 3: address changed: " + last + " -> " + this.address);
}
public void createUI(Pane container) {
HBox nameContainer = new HBox();
Label nameLabel = new Label("name: ");
nameLabel.setPrefWidth(80);
TextField nameValue = new TextField();
nameValue.setPrefWidth(140);
try {
JavaBeanStringProperty wrapper = new JavaBeanStringPropertyBuilder().bean(this).name("name").build();
nameValue.textProperty().bindBidirectional(wrapper);
} catch (NoSuchMethodException e) {
e.printStackTrace();
System.out.println("Exception binding Bean 3 name property.");
}
nameContainer.getChildren().addAll(nameLabel, nameValue);
HBox addressContainer = new HBox();
Label addressLabel = new Label("type: ");
addressLabel.setPrefWidth(80);
TextField addressValue = new TextField();
addressValue.setPrefWidth(140);
try {
JavaBeanStringProperty wrapper = new JavaBeanStringPropertyBuilder().bean(this).name("address").build();
addressValue.textProperty().bindBidirectional(wrapper);
} catch (NoSuchMethodException e) {
e.printStackTrace();
System.out.println("Exception binding Bean 3 address property.");
}
addressContainer.getChildren().addAll(addressLabel, addressValue);
container.getChildren().clear();
container.getChildren().addAll(nameContainer, addressContainer);
}
}
//=============================================================================================
private class TreeItemRefresher implements PropertyChangeListener {
private String property;
private WeakReference<TreeItem<Bean>> treeItem;
TreeItemRefresher(String property, TreeItem<Bean> treeItem) {
this.property = property;
this.treeItem = new WeakReference<>(treeItem);
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (property.equals(evt.getPropertyName())) {
// Workaround to repaint the tree item when its value object changes.
TreeItem<Bean> item = treeItem.get();
if (item != null) {
item.setExpanded(false);
item.setExpanded(true);
}
}
}
}
//=============================================================================================
private TreeView<Bean> treeView = new TreeView<>();
private VBox container = new VBox();
//=============================================================================================
@SuppressWarnings("unchecked")
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Dynamic Bindings tests.");
HBox mainContainer = new HBox();
container.setPadding(new Insets(10));
// Creating beans.
Bean1 bean1 = new Bean1("Bean 1", 10);
Bean2 bean2 = new Bean2("Bean 2", "Type O");
Bean3 bean3 = new Bean3("Bean 3", "10, Central Park Av.");
// Creating TreeView
treeView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
treeView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<TreeItem<Bean>>() {
@Override
public void changed(ObservableValue<? extends TreeItem<Bean>> arg0, TreeItem<Bean> oldValue, TreeItem<Bean> newValue) {
Bean newItem = newValue.getValue();
newItem.createUI(container);
}
});
TreeItem<Bean> bean1item = new TreeItem<Bean>(bean1);
bean1.addPropertyChangeListener(new TreeItemRefresher("name", bean1item));
TreeItem<Bean> bean2item = new TreeItem<Bean>(bean2);
bean2.addPropertyChangeListener(new TreeItemRefresher("name", bean2item));
TreeItem<Bean> bean3item = new TreeItem<Bean>(bean3);
bean3.addPropertyChangeListener(new TreeItemRefresher("name", bean3item));
bean1item.setExpanded(true);
treeView.setRoot(bean1item);
bean1item.getChildren().addAll(bean2item, bean3item);
mainContainer.getChildren().addAll(treeView, container);
Scene scene = new Scene(mainContainer, 500, 300, Color.WHITE);
primaryStage.setScene(scene);
primaryStage.show();
}
//=============================================================================================
public Main() {
}
//=============================================================================================
public static void main(String[] args) {
launch(Main.class, args);
}
}
import java.beans.PropertyChangeEvent;
导入java.beans.PropertyChangeListener;
导入java.beans.PropertyChangeSupport;
导入java.lang.ref.WeakReference;
导入javafx.application.application;
导入javafx.beans.binding.Bindings;
导入javafx.beans.property.adapter.JavaBeanIntegerProperty;
导入javafx.beans.property.adapter.JavaBeanIntegerPropertyBuilder;
导入javafx.beans.property.adapter.JavaBeanStringProperty;
导入javafx.beans.property.adapter.JavaBeanStringPropertyBuilder;
导入javafx.beans.value.ChangeListener;
导入javafx.beans.value.observeValue;
导入javafx.geometry.Insets;
导入javafx.scene.scene;
导入javafx.scene.control.Label;
导入javafx.scene.control.SelectionMode;
导入javafx.scene.control.TextField;
导入javafx.scene.control.TreeItem;
导入javafx.scene.control.TreeView;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.Pane;
导入javafx.scene.layout.VBox;
导入javafx.scene.paint.Color;
导入javafx.stage.stage;
导入javafx.util.converter.NumberStringConverter;
公共类主扩展应用程序{
//=============================================================================================
公共抽象类Bean{
公共抽象void createUI(窗格容器);
}
//=============================================================================================
公共类Bean1扩展了Bean{
私有字符串名称;
私人整数金额;
私有PropertyChangeSupport pcs=新PropertyChangeSupport(此);
公共Bean1(字符串名称,整数金额){
this.name=名称;
这个。金额=金额;
}
公共字符串toString(){return name;}
public void addPropertyChangeListener(PropertyChangeListener侦听器){
pcs.addPropertyChangeListener(listener);
System.out.println(“Bean 1 PCS有“+PCS.getPropertyChangeListeners().length+”监听器。1可能已添加。”);
}
public void removePropertyChangeListener(PropertyChangeListener侦听器){
pcs.removePropertyChangeListener(监听器);
System.out.println(“Bean 1 PCS有“+PCS.getPropertyChangeListeners().length+”监听器。1可能已被删除。”);
}
公共字符串getName(){return name;}
公共void集合名(字符串名){
字符串last=this.name;
this.name=名称;
pcs.firePropertyChange(“名称”,最后一个,this.name);
System.out.println(“Bean 1:名称更改:“+last+”->“+this.name”);
}
public int getAmount(){return amount;}
公共无效设置金额(整数金额){
int last=此数值;
这个。金额=金额;
pcs.firePropertyChange(“金额”,最后一个,本金额);
System.out.println(“Bean 1:金额更改:“+last+”->“+this.amount”);
}
公共void createUI(窗格容器){
HBox nameContainer=新的HBox();
标签名称标签=新标签(“名称:”);
nameLabel.setPrefWidth(80);
beanPathAdaptor.setBean(myNewBean);