Java 'actionPerformed' 方法如何在没有显式调用的情况下被调用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25592125/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does the 'actionPerformed' method get called without an explicit call to it?
提问by Sainath S.R
I just started learning GUI with Swing and don't exactly understand how the actionPerformed
method works. Consider the following code:
我刚开始用 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!");
}
}
Shouldn't an object be created for a class before a method on it is evoked (except for static methods)?
在调用类上的方法之前不应该为类创建对象吗(静态方法除外)?
When the button is clicked the actionPerformed
method is called, but how? Where is the call made? I've implemented the interface ActionListener
, but where is the code that knows that when an action occurs the 'ActionEvent' Object should be sent to the 'actionPerformed' method? Is it present in the Button class? Is the addActionListener
method present in the Button class?
当按钮被点击时,该actionPerformed
方法被调用,但是如何调用呢?呼叫在哪里?我已经实现了接口ActionListener
,但是知道当一个动作发生时'ActionEvent'对象应该被发送到'actionPerformed'方法的代码在哪里?它存在于 Button 类中吗?该addActionListener
方法是否存在于 Button 类中?
When I click the button, how is the system call action performed and where is the code that executes gui.actionPerformed()
?
当我单击按钮时,系统调用操作是如何执行的,执行的代码在gui.actionPerformed()
哪里?
I followed Java concepts of OO, static etc. until now but this whole event driven programming is confusing.
到目前为止,我一直遵循面向对象、静态等的 Java 概念,但整个事件驱动编程令人困惑。
采纳答案by Sagar D
Each event is represented by an object that gives information about the event and identifies the event source. Event sources are often components or models, but other kinds of objects can also be event sources.
每个事件都由一个对象表示,该对象提供有关事件的信息并标识事件源。事件源通常是组件或模型,但其他类型的对象也可以是事件源。
Here,the listener you registered, that is,
在这里,你注册的监听器,也就是,
button.addActionListener(this);
gets added to a list of listeners, and when the JVM receives an event (click in this case), it calls the appropriate methods on all the listeners in the list.
被添加到侦听器列表中,当 JVM 接收到事件(在本例中为单击)时,它会在列表中的所有侦听器上调用适当的方法。
How does this happen?Well, i think you should read about Callback
mechanism in java.
这是怎么发生的?好吧,我认为您应该阅读Callback
Java 中的机制。
You can also create your own listenersusing Callback mechanism. Consider the below code:
您还可以使用回调机制创建自己的侦听器。考虑以下代码:
The code is for a credit-card app simulation.In the below code, the pinChanged()
method gets called automaticallywhen the changePin()
method is called.
该代码是一个信用卡应用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();
}
}
}
To connect a callback/listener to the credit card you just need to implement the PinChangeListener method:
要将回调/侦听器连接到信用卡,您只需要实现 PinChangeListener 方法:
creditCard.pinChangeListener = new PinChangeListener() {
public void pinChanged() {
System.out.println("The pin has been changed");
}
};
Similarly, when you attach a listener to a button, the click is detected by JVM,(You probably don't want to go into how the click is detected!) and the actionPerformed()
of that listener which is attached is called by the JVM for you. Hope this clears.
类似地,当您将侦听器附加到按钮时,JVM 会检测到单击(您可能不想了解如何检测单击!)并且actionPerformed()
JVM 会为您调用附加的侦听器. 希望这清除。
回答by Hovercraft Full Of Eels
But there is a specific call to this method, only it's not occurring in your code but rather in the JVM. A button push instigates internal events that leads the JVM to tell the button to notify all of its listeners that it has been pushed. This will cause the actionPerformed methods of all attached ActionListeners to be called.
但是对这个方法有一个特定的调用,只是它没有发生在你的代码中,而是发生在 JVM 中。按钮按下会引发内部事件,这些事件会导致 JVM 告诉按钮通知它的所有侦听器它已被按下。这将导致调用所有附加的 ActionListener 的 actionPerformed 方法。
To see information on how this works, first look at the Java API for the AbstractButton classwhere you'll find the method
要查看有关其工作原理的信息,请首先查看AbstractButton 类的Java API,您将在其中找到该方法
protected void fireActionPerformed(ActionEvent event)
Where
在哪里
Notifies all listeners that have registered interest for notification on this event type. The event instance is lazily created using the event parameter.
通知所有已注册对此事件类型的通知感兴趣的侦听器。事件实例是使用 event 参数延迟创建的。
Then for further information, you will want to go beyond the Java API to the source code which can be found here. If you check out the Java 8.0 source code there, and look up javax then swing, then AbstractButton, you'll find a fireActionPerformed(ActionEvent event)
method:
然后,有关更多信息,您将希望超越 Java API 到可在此处找到的源代码。如果您在那里查看 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 }