Java是否有类似于pubsub或数据绑定的概念?
我正在学习Java GUI(特别是Swing)。我有一些表单,我想通过在它们之间共享事件和单例对象来保持同步。在我所知道的其他语言中,这是通过数据绑定或事件同步/触发来处理的。
我看到你可以做source.getParent().doSomething()
这样的活动,但从网络开发的角度来看,跟踪父母推荐信的想法对我来说简直是疯了。我想我永远都可以追溯到父母,但这感觉不对。
Java就是这样做的吗?是否有任何方法可以影响项目,无论它们在应用程序中的位置如何?
我没能找到任何更像网络的方式来做事情,比如冒泡和捕捉事件生命周期的各个阶段。也许我同时打开多个表单/视图的方法对于Java的工作方式来说太奇怪了。。。我只需要关闭/打开表单,初始化就会获取更新后的值。
不管我的设计是否好,我只是在尝试学习Java,所以即使这个特定的例子不适用,我仍然想知道如何在组件A不知道组件B在监听的情况下从远处影响项目。
在psuedocode中,由于我不知道用Java来表达这一点,我希望能够做到:
没有数据绑定
Foo组件:
private void initialize() {
this.addEventListener(CONSTANTS.NAME_OF_EVENT, this.doSomething); // waits for somebody to tell us to update
}
private void doSomething() {
this.value = singleton.getInstance().value; // gets "123" from Bar's dispatch
...
}
在条形组件中,我希望能够做到:
private void triggerSomething() {
this.singleton.getInstance.setValue(123); // updates the singleton
this.dispatchEvent(CONSTANTS.NAME_OF_EVENT); // tells anybody who cares about NAME_OF_EVENT to do something about it (ideally, the singleton would do the dispatching but for clarity I separated them)
}
使用数据绑定
Foo组件:
private void initialize() {
this.singleton.getInstance().setValue(123);
}
在Bar组件中,我希望txtValue.setText()通过绑定到singleton值而神奇地发生。
private void initialize() {
txtValue.setText(this.singleton.getInstance().getValue());
}
您可能希望从属性更改侦听器而不是事件侦听器的角度进行思考。事件的级别将低于您想要的级别(按钮按下、按钮释放、按键按下、按键释放)。属性更改是更高级别的:"此属性从该值更改为该值。"
public class PropertyChangeBean {
protected PropertyChangeEvent pce(String name, Object from, Object to) {
return new PropertyChangeEvent(this, name, from, to);
}
private PropertyChangeSupport pcs;
public void addPropertyChangeListener(PropertyChangeListener listener) {
if (pcs == null)
pcs = new PropertyChangeSupport(this);
pcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
if (pcs != null)
pcs.removePropertyChangeListener(listener);
}
protected void fireChange(String property, Object from, Object to) {
if (pcs != null && !Objects.equals(from, to))
pcs.firePropertyChange(pce(property, from, to));
}
protected void fireChange(String property, int from, int to) {
if (pcs != null && from != to)
pcs.firePropertyChange(pce(property, from, to));
}
protected void fireChange(String property, boolean from, boolean to) {
if (pcs != null && from != to)
pcs.firePropertyChange(pce(property, from, to));
}
protected void fireChange(PropertyChangeEvent pce) {
if (pcs != null)
pcs.firePropertyChange(pce);
}
}
并创建你的"酒吧"豆状:
public class Bar extends PropertyChangeBean {
private int value = 0;
public void setValue(int new_value) {
fireChange("value", value, value = new_value);
}
public int getValue() {
return value;
}
}
"Foo"将在"Bar"上注册为PropertyChangeListener
class Foo {
Foo() {
bar.addPropertyChangeListener(e -> {
// Fetch and use new value of bar
});
}
}
您甚至可以使用VetoableChangeListener让侦听器在尝试更改时响应"不,这不是一个可接受的值"。