4

我无法理解的是一种方法,例如

    public interface MouseListener extends EventListener {

        public void mouseClicked(MouseEvent e) {
             //code for what happens when you click the mouse on the component
        }
    }

知道鼠标事件的 id。为什么事件执行的时候只发送给 mouseClicked 方法?这些方法的构造函数调用任何可能的鼠标事件,那么为什么当其他方法具有相同的构造函数(即 mousePressed、mouseReleased 等)时才将其发送到 mouseClicked 方法?

4

3 回答 3

5

观察者模式是重要的知识。

此模式用于在运行时形成对象之间的关系。

该模式背后的想法很简单——多个观察者之一对主题的状态感兴趣,并通过附加自己的方式向主题注册他们的兴趣。当 观察者可能感兴趣的主题发生变化时,会发送一条通知消息,该消息会调用每个观察者中的更新方法。当 Observer不再对Subject 的状态感兴趣时,他们可以简单地分离自己。

动作监听器的整个想法就是基于此。一旦你理解了这个模式,它就很简单了。

当您注册ActionListener,它是观察者,按钮是主题。因此,当按钮更改状态时,将启动actionPerformed方法。

请注意,所有侦听器都基于此模式,当事件发生时,已注册的侦听器将收到有关此事件的通知并执行操作。例如,Swing 自己管理所有的注册和事件通知(它已经“内置”了)。

http://java.dzone.com/articles/design-patterns-uncovered

于 2013-05-13T20:20:11.307 回答
3

当您实现它、创建对象并将该对象注册到事件源时,这样的接口就开始有用了。注册部分在这里很关键——如果您注册到鼠标点击事件,那么这就是对象将收到的内容。

所以基本上这些接口看起来很相似,因为它们用于处理类似的事件,但最终你只会被告知你注册的事件。这里没有魔法 - 事件源在内部保留对某些事件感兴趣的侦听器的集合,如果发生此类事件,它会遍历集合并调用侦听器方法。

例如,您提到的鼠标侦听器接口有几个方法:

public interface MouseListener extends EventListener {
    public void mouseClicked(MouseEvent e);
    public void mousePressed(MouseEvent e);
    ...
}

如果您查看该类的一部分,java.awt.Component您会发现它是负责调用正确方法的事件源:

public abstract class Component implements ImageObserver, MenuContainer,
                                       Serializable
{
...
    protected void processMouseEvent(MouseEvent e) {
        MouseListener listener = mouseListener;
        if (listener != null) {
            int id = e.getID();
            switch(id) {
              case MouseEvent.MOUSE_PRESSED:
                  listener.mousePressed(e); // invoking a specific listener's method
                  break;
              case MouseEvent.MOUSE_RELEASED:
                  listener.mouseReleased(e);
                  break;
              ...


}
于 2013-05-13T20:11:00.847 回答
-1

当您注册事件时,您将侦听器传递给您想要听到的对象。该对象保留一个它感兴趣的对象列表,如果发生需要通知的事情,那么它会遍历列表并调用通知方法。

于 2013-05-13T20:23:43.973 回答