Java Swing 事件冒泡/捕获

标签 java swing

Java 是否有类似于 pubsub 或数据绑定(bind)的概念?

我正在学习 Java GUI(特别是 Swing)。我有一些表单,我想通过在它们之间共享事件和单例对象来保持同步。在我知道的其他语言中,这是通过数据绑定(bind)或事件同步/触发来处理的。

我已经看到您可以执行诸如 source.getParent().doSomething() 之类的事件,但是来自 Web 开发,跟踪家长引用的想法对我来说似乎绝对是疯狂的。我想我总是能够追溯到 parent ,但这感觉不对。

这就是 Java 的工作方式吗?有什么方法可以影响项目,无论它们在应用程序中的位置如何?

我没有运气找到任何关于更像网络的做事方式的东西,例如冒泡和捕获事件生命周期的阶段。也许我同时打开多个表单/ View 的方法对于 Java 的工作方式来说太奇怪了...我可以只关闭/打开表单,初始化就会获取更新的值。

不管我的设计是否好,我只是想学习Java,所以即使这个特定的例子不适用,我仍然想知道如何影响远处的项目,而无需组件A知道组件 B 正在监听。

在伪代码中,因为我不知道表达这一点的Java方式,我希望能够做到:

没有数据绑定(bind)

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
   ...
}

Bar Component中,我希望能够做到:

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)
}

具有数据绑定(bind)

Foo 组件:

private void initialize() {
    this.singleton.getInstance().setValue(123);
}

Bar Component中,我希望 txtValue.setText() 能够通过绑定(bind)到单例值而神奇地发生。

private void initialize() {
   txtValue.setText(this.singleton.getInstance().getValue());
}

最佳答案

您可能想用 Property Change Listener 来思考,而不是事件监听器。事件的级别将低于您想要的级别(按钮按下、按钮释放、按键按下、按键释放)。属性更改是更高级别的:“此属性从该值更改为该值。”

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);
    }
}

并创建你的“Bar”bean,如下所示:

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
        });
    }
}

您甚至可以使用Vetoable Change Listener当尝试进行更改时,让监听器可以响应“不,这不是可接受的值”。

关于Java Swing 事件冒泡/捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36990531/

相关文章:

java - Seam 2 内置工厂有什么优势

java - Android 按顺序从 Gallery 接收图片

Java Swing - 在子菜单中选择项目时增加宽大度

java - 垂直JPanel手动定位: which layout?

java - 如何将输出流设置为 TextArea

java - Bluemix 中的流分析服务出错

java - Java从文件中读取大量BitSet对象

java - Java 设计 hashCode 方法

java - 如何更改 NetBeans 中 JFrame 和 JLabel 之间的空间?

java - 方法 hibernate 直到事件触发