使用 JavaFX 属性包装的 JavaBean [英] JavaBean wrapping with JavaFX Properties

查看:24
本文介绍了使用 JavaFX 属性包装的 JavaBean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将 JavaFX 属性用于 UI 绑定,但我不希望它们出现在我的模型类中(请参阅 在模型类中使用 javafx.beans 属性).我的模型类有 getter 和 setter,我想基于这些创建属性.例如,假设一个实例 bean 具有方法 String getName()setName(String name),我会写

I want to use JavaFX properties for UI binding, but I don't want them in my model classes (see Using javafx.beans properties in model classes). My model classes have getters and setters, and I want to create properties based on those. For example, assuming an instance bean with methods String getName() and setName(String name), I would write

 SimpleStringProperty property = new SimpleStringProperty(bean, "name")

期望 property.set("Foobar") 会触发对 bean.setName 的调用.但这似乎不起作用.我错过了什么?

expecting that property.set("Foobar") would trigger a call to bean.setName. But this doesn't seem to work. What am I missing?

推荐答案

Simple*Property 类是其对应的 Property 抽象类的完整独立实现,并且不依赖任何其他对象.因此,例如,SimpleStringProperty 包含一个(私有)String 字段本身,该字段保存属性的当前值.

The Simple*Property classes are full, standalone implementations of their corresponding Property abstract classes, and do not rely on any other object. So, for example, SimpleStringProperty contains a (private) String field itself which holds the current value of the property.

你展示的构造函数的参数:

The parameters to the constructor you showed:

new SimpleStringProperty(bean, "name")

是:

  • bean:属性所属的bean,如果有的话
  • name:属性名称
  • bean: the bean to which the property belongs, if any
  • name: the name of the property

beanChangeListenerchanged(...) 方法中很有用,因为您可以检索拥有的 bean"从属性本身改变的属性.name 可以类似地使用(如果你有同一个监听器注册了多个属性,你可以找出哪个属性发生了变化:虽然我从来没有使用过这种模式).

The bean can be useful in a ChangeListener's changed(...) method as you can retrieve the "owning bean" of the property that changed from the property itself. The name can be used similarly (if you have the same listener registered with multiple properties, you can figure out which property changed: though I never use this pattern).

因此,SimpleStringProperty 作为对象的可观察属性的典型用法如下所示:

So a typical use of a SimpleStringProperty as an observable property of an object looks like:

public class Person {
    private final StringProperty firstName 
        = new SimpleStringProperty(this, "firstName");

    public final String getFirstName() {
        return firstName.get();
    }

    public final void setFirstName(String firstName) {
        this.firstName.set(firstName);
    }

    public StringProperty firstNameProperty() {
        return firstName ;
    }

    // ... other properties, etc
}

您正在寻找的功能:将现有 Java Bean 样式属性包装在 JavaFX 可观察属性中是由 javafx.beans.property.adapter 包中的类实现的.所以,例如,你可以做

The functionality you are looking for: to wrap an existing Java Bean style property in a JavaFX observable property is implemented by classes in the javafx.beans.property.adapter package. So, for example, you could do

StringProperty nameProperty = new JavaBeanStringPropertyBuilder()
        .bean(bean)
        .name("name")
        .build();

打电话

nameProperty.set("James");

使用此设置将有效地调用

with this setup will effectively cause a call to

bean.setName("James");

如果 bean 支持 PropertyChangeListeners,JavaBeanStringProperty 将向 bean 注册一个 PropertyChangeListener.对 Java Bean 的 name 属性的任何更改都将由 JavaBeanStringProperty 转换为 JavaFX 属性更改.因此,如果底层 JavaBean 支持 PropertyChangeListeners,则通过

If the bean supports PropertyChangeListeners, the JavaBeanStringProperty will register a PropertyChangeListener with the bean. Any changes to the name property of the Java Bean will be translated by the JavaBeanStringProperty into JavaFX property changes. Consequently, if the underlying JavaBean supports PropertyChangeListeners, then changes to the bean via

bean.setName(...);

将导致向 JavaBeanStringProperty 注册的任何 ChangeListeners(或 InvalidationListeners)被通知更改.

will result in any ChangeListeners (or InvalidationListeners) registered with the JavaBeanStringProperty being notified of the change.

因此,例如,如果 Bean 类是

So, for example, if the Bean class is

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

public class Bean {

    private String name ;
    private final PropertyChangeSupport propertySupport ;

    public Bean(String name) {
        this.name = name ;
        this.propertySupport = new PropertyChangeSupport(this);
    }

    public Bean() {
        this("");
    }

    public String getName() {
        return name ;
    }

    public String setName(String name) {
        String oldName = this.name ;
        this.name = name ;
        propertySupport.firePropertyChange("name", oldName, name);
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        propertySupport.addPropertyChangeListener(listener);
    }
}

然后是下面的代码:

Bean bean = new Bean();
StringProperty nameProperty() = new JavaBeanStringPropertyBuilder()
        .bean(bean)
        .name("name")
        .build();
nameProperty().addListener((obs, oldName, newName) -> System.out.println("name changed from "+oldName+" to "+newName));
bean.setName("James");
System.out.println(nameProperty().get());

将产生输出:

name changed from to James 
James

如果 JavaBean 不支持 PropertyChangeListeners,那么通过 bean.setName(...) 对 bean 的更改将不会传播到 ChangeListenercode>s 或 InvalidationListeners 注册到 JavaBeanStringProperty.

If the JavaBean does not support PropertyChangeListeners, then changes to the bean via bean.setName(...) will not propagate to ChangeListeners or InvalidationListeners registered with the JavaBeanStringProperty.

所以如果 bean 是简单的

So if the bean is simply

public class Bean {

    public Bean() {
        this("");
    }

    public Bean(String name) {
        this.name = name ;
    }

    private String name ;

    public String getName() {
        return name ;
    }

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

JavaBeanStringProperty 将无法观察更改,因此永远不会通过调用 bean.setName() 来调用更改侦听器.所以上面的测试代码只会输出

The JavaBeanStringProperty would have no way to observe the change, so the change listener would never be invoked by a call to bean.setName(). So the test code above would simply output

James

这篇关于使用 JavaFX 属性包装的 JavaBean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆