首页 文章

如果没有显式调用'actionPerformed'方法,它将如何被调用?

提问于
浏览
10

我刚开始用Swing学习GUI,并不完全理解 actionPerformed 方法的工作原理 . 请考虑以下代码:

//code to create a button and change its text when clicked
public class simplegui implements ActionListener {
  JButton button;

  public static void main(String[] args) {
    simplegui gui=new simplegui();
    gui.go();
  }

  public void go() {
    JFrame frame=new Frame();
    button=new JButton("click Me");
    button.addActionListener(this);

    frame.getContentPane().add(button);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(300,300);
    frame.setVisible(true);
  }

  public void actionPerformed(ActionEvent event) {
    button.setText("I've been clicked!");
  }
}

在引发方法之前,不应该为类创建对象(静态方法除外)?

单击该按钮时,将调用 actionPerformed 方法,但如何?电话在哪里?我已经实现了接口 ActionListener ,但是知道当一个动作发生时'ActionEvent'对象应该被发送到'actionPerformed'方法的代码在哪里?它出现在Button类中吗? Button类中是否存在 addActionListener 方法?

当我单击按钮时,如何执行系统调用操作以及执行 gui.actionPerformed() 的代码在哪里?

我一直遵循旧的OO,静态等Java概念,但这整个事件驱动编程令人困惑 .

2 回答

  • 4

    每个事件都由一个对象表示,该对象提供有关事件的信息并标识事件源 . 事件源通常是组件或模型,但其他类型的对象也可以是事件源 .

    在这里,您注册的听众,即

    button.addActionListener(this);
    

    被添加到侦听器列表中,当JVM收到事件(在这种情况下单击)时,它会在列表中的所有侦听器上调用相应的方法 .

    How does this happen? 好吧,我想你应该在java中阅读有关 Callback 机制的内容 .

    您还可以使用回调机制创建 own listeners . 考虑以下代码:

    代码用于信用卡应用程序模拟 . 在下面的代码中,调用 changePin() 方法时 pinChanged() 方法 gets called automatically .

    public interface PinChangeListener {
        public void pinChanged();
    }
    
    public class CreditCard {
        public PinChangeListener pinChangeListener;
    
        private int pin;
    
        public changePin(int pin) {
            this.pin = pin;
            if (pinChangeListener != null) {
                pinChangeListener.pinChanged();
            }
        }
    }
    

    要将回调/监听器连接到信用卡,您只需要实现PinChangeListener方法:

    creditCard.pinChangeListener = new PinChangeListener() {
        public void pinChanged() {
            System.out.println("The pin has been changed");
        }
    };
    

    类似地,当您将一个监听器附加到一个按钮时,JVM会检测到该单击,(您可能不想进入检测到单击的方式!)并且JVM会调用所连接的监听器的 actionPerformed() 您 . 希望这清楚 .

  • 11

    但是对这种方法有一个特定的调用,只是它不在你的代码中,而是在JVM中 . 按钮推动启动内部事件,引导JVM告诉按钮通知其所有侦听器已被推送 . 这将导致调用所有附加的ActionListener的actionPerformed方法 .

    要查看有关其工作原理的信息,请先查看Java API for the AbstractButton class您将找到该方法的位置

    protected void fireActionPerformed(ActionEvent event)
    

    哪里

    通知所有已注册对此事件类型的通知感兴趣的听众 . 使用event参数延迟创建事件实例 .

    然后,为了获得更多信息,您需要超越Java API,找到可以找到的源代码here . 如果你在那里查看Java 8.0源代码,然后查找javax然后swing,然后是AbstractButton,你会发现 fireActionPerformed(ActionEvent event) 方法:

    2002    protected void More ...fireActionPerformed(ActionEvent event) {
    2003        // Guaranteed to return a non-null array
    2004        Object[] listeners = listenerList.getListenerList();
    2005        ActionEvent e = null;
    2006        // Process the listeners last to first, notifying
    2007        // those that are interested in this event
    2008        for (int i = listeners.length-2; i>=0; i-=2) {
    2009            if (listeners[i]==ActionListener.class) {
    2010                // Lazily create the event:
    2011                if (e == null) {
    2012                      String actionCommand = event.getActionCommand();
    2013                      if(actionCommand == null) {
    2014                         actionCommand = getActionCommand();
    2015                      }
    2016                      e = new ActionEvent(AbstractButton.this,
    2017                                          ActionEvent.ACTION_PERFORMED,
    2018                                          actionCommand,
    2019                                          event.getWhen(),
    2020                                          event.getModifiers());
    2021                }
    2022                ((ActionListener)listeners[i+1]).actionPerformed(e);
    2023            }
    2024        }
    2025    }
    

相关问题