如何在不明确调用“actionPerformed”方法的情况下调用该方法?
我刚刚开始使用Swing学习GUI,但并不完全了解actionPerformed
方法的工作原理。请考虑以下代码:如何在不明确调用“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()
?
我遵循Java的OO概念,静态等,直到现在,但这整个事件驱动编程是混乱。
每个事件都由一个对象表示,该对象提供有关事件的信息并标识事件源。事件源通常是组件或模型,但其他类型的对象也可以是事件源。
在这里,你注册了侦听器, 就是
button.addActionListener(this);
被添加到听众的名单,而当JVM接收到事件(请在这种情况下),它会调用适当的方法上列表中的所有听众。
这是怎么发生的?嗯,我想你应该阅读关于在java中的Callback
机制。
您还可以使用回拨机制创建自己的听众。 考虑下面的代码:
的代码是一个信用卡应用simulation.In下面的代码中,pinChanged()
方法时changePin()
方法被调用就会自动调用。
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检测,(您可能不想进入检测点击的方式!),并且附加的侦听器的actionPerformed()
由JVM为您调用。希望这个清除。
非常感谢,这是一个非常明确的解释。 – 2014-08-31 13:32:50
我很高兴它帮助:) – 2014-08-31 13:38:28
但是有一个特定的调用这个方法,只是它不是在你的代码中发生,而是在JVM中发生。按钮推动引发内部事件,导致JVM通知按钮通知其所有听众已被推送。这将导致所有连接的ActionListener的actionPerformed方法被调用。
要看到这是如何工作的,在先来看看在那里你会找到方法
protected void fireActionPerformed(ActionEvent event)
凡
通知已注册对获得此事件的通知感兴趣的所有侦听信息类型。事件实例是使用事件参数延迟创建的。
然后,有关详细信息,您将希望超越Java API的源代码,可以找到here。如果检查出的Java 8.0的源代码存在,并期待的javax挥杆,然后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 }
作为参考,这种方法在['EventListenerList'](http://docs.oracle.com/javase/8/docs/api/javax/swing/event/ EventListenerList.html)API,检查[这里](http://stackoverflow.com/q/2159803/230513)。 – trashgod 2014-08-31 13:41:26
非常感谢你 – 2014-09-01 14:51:03
嗨,@Hovercraft。是否可以从方法actionPerformed()调用方法。例如: - 我想调用一个_void_方法** add()**并将3个变量传递给它'add(int a,int b,int c)',然后获取这些变量和我想要的过程在** add()**方法中。提前致谢。 – Learner 2017-01-11 09:02:08
但有**是**特定调用此方法,只它不会发生在您的代码中,而是发生在JVM中。按钮推动引发内部事件,导致JVM通知按钮通知其所有听众已被推送。这将导致所有连接的ActionListener的actionPerformed方法被调用。 – 2014-08-31 12:49:39
@HovercraftFullOfEels我建议添加一个完整的答案(可能与指向Java/swing运行时库源的链接) – hexafraction 2014-08-31 12:52:11
是的,我明白了,但是如果在其他地方有一个调用是在任何这些类中的代码,如果是这样,请将我的相关API文档链接到清楚的地方? – 2014-08-31 12:53:35