我刚刚开始使用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概念,直到现在,但这整个事件驱动的编程令人困惑。
答案 0 :(得分:11)
每个事件都由一个对象表示,该对象提供有关事件的信息并标识事件源。事件源通常是组件或模型,但其他类型的对象也可以是事件源。
在这里,您注册的听众, 就是这样,
button.addActionListener(this);
被添加到侦听器列表中,当JVM收到事件(在这种情况下单击)时,它会在列表中的所有侦听器上调用相应的方法。
这是怎么发生的?好吧,我认为你应该阅读java中的Callback
机制。
您还可以使用回调机制创建自己的侦听器。 请考虑以下代码:
该代码适用于信用卡应用模拟。在以下代码中,调用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为您调用。希望这清楚。
答案 1 :(得分:4)
但是对这种方法有一个特定的调用,只是它没有出现在你的代码中,而是出现在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 }