【问题标题】:Is there a guaranteed priority in Swing events of the same type?相同类型的 Swing 事件是否有保证的优先级?
【发布时间】:2019-07-24 17:16:49
【问题描述】:

快速示例:我有一个带有两个 ActionListener 的 JButton。它们会以有保证的顺序执行吗?同类型的所有EventListener都一样吗?

JButton b = new JButton();
b.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e) {
        System.out.println("event 1");
});
b.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e) {
        System.out.println("event 2");
});

【问题讨论】:

  • IIRC,事件监听器的调用顺序与添加的相反,但我认为这不能保证。如果需要保证,创建一个复合监听器?
  • 我通过将Callable 传递给ActionListener 解决了我的具体问题

标签: java swing actionlistener event-listener


【解决方案1】:

正如@daniu 在评论部分提到的那样,当一个按钮(或任何组件)具有多个相同类型的侦听器时(在我们的示例中,我们在JButton 中有两个动作侦听器)它们将从最后一个到第一个被触发. AbstractButton#fireActionPerformed 里面的评论说得很清楚:

protected void fireActionPerformed(ActionEvent event) {
    // Guaranteed to return a non-null array
    Object[] listeners = listenerList.getListenerList();
    ActionEvent e = null;
    // Process the listeners last to first, notifying
    // those that are interested in this event
    for (int i = listeners.length-2; i>=0; i-=2) {
        if (listeners[i]==ActionListener.class) {
            // Lazily create the event:
            if (e == null) {
                  String actionCommand = event.getActionCommand();
                  if(actionCommand == null) {
                     actionCommand = getActionCommand();
                  }
                  e = new ActionEvent(AbstractButton.this,
                                      ActionEvent.ACTION_PERFORMED,
                                      actionCommand,
                                      event.getWhen(),
                                      event.getModifiers());
            }
            ((ActionListener)listeners[i+1]).actionPerformed(e);
        }
    }
}

当然,创建一个自己测试的示例非常容易:

public class ListenersTest extends JFrame {

    public ListenersTest() {
        super("tests");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        getContentPane().setLayout(new FlowLayout());

        JButton button = new JButton("press me");
        for (int i = 1; i <= 5; i++) {
            button.addActionListener(new Listener(i));
        }
        add(button);

        setSize(400, 400);
        setLocationRelativeTo(null);

    }

    private static class Listener implements ActionListener {
        private int id;

        private Listener(int id) {
            this.id = id;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("My ID is:" + id);
        }

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new ListenersTest().setVisible(true);
        });
    }
}

如果你按下按钮,你会得到:

我的 ID 是:5 我的 ID 是:4 我的 ID 是:3 我的 ID 是:2 我的 ID 是:1

【讨论】:

  • 是的,这是当前的实现,但在 Java 规范中并不能保证。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-05
  • 1970-01-01
  • 1970-01-01
  • 2018-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多