Guava EventBus:监听事件超类型(例如EventObject或Object)意味着什么?

ktu*_*nho 3 java guava

Google Guava EventBusExplained页面中,我不明白他们何时说出以下内容:


在传统的Java事件中监听常见的事件超类型(如EventObject或Object)...... :不容易.
...使用EventBus:事件会自动分派给任何超类型的侦听器,允许侦听器用于接口类型或"通配符侦听器"用于Object.

  1. 听一个常见的事件超类是什么意思?
  2. 当他们提到EventObject时,他们是在谈论java.util.EventObject吗?
  3. 允许"接口类型的监听器"或"对象"的通配符监听器是什么意思?

Bri*_*ian 6

这与Guava的EventBus类可以克服的方法重载和接口的局限性有关.

对于接口,请考虑以下情形:

我有相同的代码,可以调用多种形式的输入.例如,侦听鼠标事件,键事件和焦点事件的侦听器,但所有方法都执行相同的操作:重新绘制源.这意味着我的代码看起来像这样:

public class BunchOfListeners implements MouseListener, KeyListener, FocusListener {

    @Override
    public void focusGained(FocusEvent e) {
        doSomething(e);
    }

    @Override
    public void focusLost(FocusEvent e) {
        doSomething(e);
    }

    @Override
    public void keyTyped(KeyEvent e) {
        doSomething(e);
    }

    @Override
    public void keyPressed(KeyEvent e) {
        doSomething(e);
    }

    @Override
    public void keyReleased(KeyEvent e) {
        doSomething(e);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        doSomething(e);
    }

    @Override
    public void mousePressed(MouseEvent e) {
        doSomething(e);
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        doSomething(e);
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        doSomething(e);
    }

    @Override
    public void mouseExited(MouseEvent e) {
        doSomething(e);
    }

    public void doSomething(EventObject e) {
        ((Component) e.getSource()).repaint();
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意这是多么丑陋?对此有10种不同的方法,最终我们关心的唯一事情是从事件中获取源(EventObject顺便说一下,这就是他们在他们的例子中使用它的原因)并调用repaint它.

使用番石榴EventBus,它变得超级,超级简单.我班上所需要的只是一种方法:GuavaIsAwesome ComponentRepainter

public class ComponentRepainter {

    @Subscribe
    public void doSomething(EventObject e) {
        ((Component) e.getSource()).repaint();
    }
}
Run Code Online (Sandbox Code Playgroud)

当你注册这个EventBus以及随后的火灾时,比如,a MouseEvent:

EventBus eventBus = ... ;
eventBus.register(new ComponentRepainter());
Run Code Online (Sandbox Code Playgroud)

然后:

MouseEvent e = ... ;
eventBus.post(e);
Run Code Online (Sandbox Code Playgroud)

这将调用doSomething的方法ComponentRepainter,因为它不仅会触发事件@Subscribe与方法MouseEvent的参数,但也有一个参数是任何方法分配MouseEvent.换句话说,因为MouseEvent延伸EventObject,Guava EventBus会将它传递给任何接受的东西EventObject.如果我们doSomething接受了Object,那么我们就可以获得发布到的每个事件EventBus,使其成为一种全局监听器(因为Java中的所有内容都会延伸Object).

同样的事情也适用于接口.如果将具体实现传递给EventBus某个接口,则将@Subscribe调用使用该接口的方法(而不是具体类型).它更加灵活,并且克服了"十种无用的方法"方法.