从ObjectProperty更新事件(就像在ObservableList中一样) [英] Update events from ObjectProperty (just like in ObservableList)

查看:213
本文介绍了从ObjectProperty更新事件(就像在ObservableList中一样)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以使用提取器( Callback< E,Observable []>提取器)来制作 ListProperty 如果其中一个元素更改了其中一个属性(更新事件),则触发更改事件。

I can use an extractor (Callback<E, Observable[]> extractor) to make a ListProperty fire change events if one of its elements changed one of its properties (update event).

更新ObservableList中的更改事件

ObjectProperty< > ?我有一个 SimpleObjectProperty 我希望在它的值(另一个bean类型)的属性发生变化时触发事件(更新更改事件)。

Is there an equivalent for ObjectProperty<>? I have an SimpleObjectProperty which I want to fire events when properties of it's value (another bean type) change (update change events).

示例代码:

public class TestBean {

    public static <T extends TestBean> Callback<T, Observable[]> extractor() {

    return (final T o) -> new Observable[] { o.testPropertyProperty() };
    }

    private final StringProperty testProperty = new SimpleStringProperty();

    public final StringProperty testPropertyProperty() {
    return this.testProperty;
    }

    public final String getTestProperty() {
    return this.testPropertyProperty().get();
    }

    public final void setTestProperty(final String testProperty) {
    this.testPropertyProperty().set(testProperty);
    }

}

public class SomeType {

    /**
     * How can I listen for changes of TestBean#testProperty?
     */
    private final ObjectProperty<TestBean> property = new SimpleObjectProperty<>();

}

如果值<$,我想收到更改事件c $ c> SomeType#property 更改,但是,如果 SomeType#property#testProperty 更改。

I want to receive change events if the value of SomeType#property changes, but also, if SomeType#property#testProperty changes.

我不能只听 SomeType#property#testProperty ,因为当 SomeType#property 被更改了(我会在错误的对象上听取更改)。

I cannot just listen for SomeType#property#testProperty, since I would not be notified when SomeType#property was changed (I would then listen on the wrong object for changes).

推荐答案

上周我遇到了同样的问题,经过多次尝试,我找到了一个似乎按预期工作的解决方案:

I had the same problem last week, and after many tries, I found a solution that seems to work as expected:


  • 我创建了一个名为的新类ObjectXProperty< E> ,具有 ObjectProperty< E> ;

  • 的相同界面构造函数可以接受 Callback< E,Observable []> ,我们的提取器函数;

  • ObjectXProperty ,我使用 SimpleObjectProperty 删除所有方法;

  • 神奇的技巧在于集合(E值)方法:我创建了一个 ObjectBinding 只是简单地发回,但是它使用提取器函数来决定它何时变为无效!

  • I created a new class called ObjectXProperty<E>, that has the same interface of an ObjectProperty<E>;
  • It has constructors that can accept a Callback<E,Observable[]>, our extractor function;
  • Inside the ObjectXProperty, I use a SimpleObjectProperty that deleguates all methods;
  • The magic trick lies in the set(E value) methods : I create an ObjectBinding that simply send back the value, but it uses the extractor function to decide when it's become invalidated!

如果先前在<$ c $上使用 bind 方法,则不会应用此技巧c> ObjectXProperty ,让真正的绑定完成他的工作;如果调用 unbind 方法,它将再次起作用;

This trick will not be applied if the bind method was used previously on the ObjectXProperty, to let the "real" binding do his job; it will work again if the unbind method is called;

这是我的新班级 ObjectXProperty< E>

import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.util.Callback;

/**
 *
 * @author Claude Bouchard - 2017
 */

public class ObjectXProperty<E> extends ObjectProperty<E> {

SimpleObjectProperty<E> p;
Callback<E, Observable[]> extractor;

boolean externalBound = false;

public ObjectXProperty(Callback<E, Observable[]> extractor) {
    this.extractor = extractor;
}

public ObjectXProperty(E init, Callback<E, Observable[]> extractor) {

    p = new SimpleObjectProperty();
    this.extractor = extractor;
    set(init);

}

public ObjectXProperty(Object bean, String name, Callback<E, Observable[]> extractor) {
    p = new SimpleObjectProperty(bean, name);
    this.extractor = extractor;
}

public ObjectXProperty(Object bean, String name, E init, Callback<E, Observable[]> extractor) {
    p = new SimpleObjectProperty(bean, name);
    this.extractor = extractor;
    set(init);

}

@Override
public void set(E value) {
    if (!externalBound) {
        if (value != null) {
            p.bind(Bindings.createObjectBinding(() -> {
                return value;
            }, extractor.call(value)));

        } else {
            p.bind(Bindings.createObjectBinding(() -> {
                return value;
            }, new Observable[]{}));
        }
    } else {
        p.set(value); //As expected, it will throw a java.lang.RuntimeException
    }
}

@Override
public E get() {
    return p.get();
}

@Override
public void addListener(ChangeListener<? super E> listener) {
    p.addListener(listener);
}

@Override
public void removeListener(ChangeListener<? super E> listener) {
    p.removeListener(listener);
}

@Override
public void addListener(InvalidationListener listener) {
    p.addListener(listener);
}

@Override
public void removeListener(InvalidationListener listener) {
    p.removeListener(listener);
}

@Override
public Object getBean() {
    return p.getBean();
}

@Override
public String getName() {
    return p.getName();
}

@Override
public void bind(ObservableValue<? extends E> observable) {
    p.bind(observable);
    externalBound = true;
}

@Override
public void unbind() {
    p.unbind();
    externalBound = false;
    set(get()); //to reactivate the extractor on the last value
}

@Override
public boolean isBound() {
    return externalBound;
}

}

这篇关于从ObjectProperty更新事件(就像在ObservableList中一样)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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