我有一个包含各种属性的类:
public class Foo extends ??? {
public SimpleBooleanProperty prop1 = new SimpleBooleanProperty();
public SimpleStringProperty prop2 = new SimpleStringProperty();
// ** more properties ** //
}
在大多数情况下,所有属性都会发生变化,对于某些侦听器,当任何属性发生变化时,只能调用一个回调,然后获取所有属性的值(即使并非所有属性都已更改)也会更容易。我应该建立什么课程?
我想在
行注册一个听众Foo foo = new Foo();
foo.addListener( new ChangeListener< >() {
void onChange(Foo newValue,Foo oldValue) {
System.out.println(String.valueOf(newValue.prop1.get());
System.out.println(String.valueOf(newValue.prop2.get());
});
打印到控制台只是一个例子,关键是监听器只需要知道某些内容发生了变化,并且可以调用getter。我有点迷失在哪里开始。有Observable
接口和大量不同的基类(例如ObservableValueBase<T>
或SimpleObjectProperty<T>
)。我应该从/ extend继承哪一个?
答案 0 :(得分:0)
实现ObservableValue<Foo>
作为您的监听器建议意味着您的对象正在包装Foo
对象,显然不是这样。
对于ObservableValue
,会有要扩展的类。对于Observable
,不存在此类,您应该自己实现该接口。这可以通过向/从所有Observable
属性添加/删除侦听器来完成,但为了提高效率,我建议每个属性使用一个侦听器来实现:
public abstract class ObservableBase implements Observable {
private final List<InvalidationListener> listeners = new ArrayList<>();
protected ObservableBase(Observable... dependencies) {
InvalidationListener listener = o -> {
for (InvalidationListener l : listeners) {
try {
l.invalidated(o);
} catch (RuntimeException ex) {
ex.printStackTrace();
}
}
};
for (Observable o : dependencies) {
o.addListener(listener);
}
}
@Override
public final void addListener(InvalidationListener listener) {
Objects.requireNonNull(listener);
listeners.add(listener);
}
@Override
public final void removeListener(InvalidationListener listener) {
listeners.remove(listener);
}
}
public class Foo extends ObservableBase {
public final BooleanProperty prop1;
public final StringProperty prop2;
// ** more properties ** //
private Foo(BooleanProperty prop1, StringProperty prop2) {
super(prop1, prop2);
this.prop1 = prop1;
this.prop2 = prop2;
}
public Foo() {
this(new SimpleBooleanProperty(this, "prop1"), new SimpleStringProperty(this, "prop2"));
}
}
Foo foo = new Foo();
InvalidationListener l = o -> {
ReadOnlyProperty p = (ReadOnlyProperty) o;
System.out.println("changed property: " + p.getName());
Foo bean = (Foo) p.getBean();
System.out.println(bean.prop1.get());
System.out.println(bean.prop2.get());
};
foo.addListener(l);
答案 1 :(得分:0)
不完全确定我是否正确解释了您的需求。这可能就是你所需要的:
public class Foo extends ??? {
public SimpleBooleanProperty prop1 = new SimpleBooleanProperty();
public SimpleStringProperty prop2 = new SimpleStringProperty();
// ** more properties ** //
private final ObjectBinding<Void> binding = Bindings.createObjectBinding(this::bar, prop1, prop2, prop3, prop4);
private final Void bar() {
Optional.of(newValue.prop1.get()).ifPresent(System.out::println);
Optional.of(newValue.prop2.get()).ifPresent(System.out::println);
Optional.of(newValue.prop3.get()).ifPresent(System.out::println);
Optional.of(newValue.prop4.get()).ifPresent(System.out::println);
return null;
}
}
绑定本身会监听你,但你必须保留绑定的强引用,否则它将被垃圾收集。