Java 将“this”作为方法参数传递-澄清
在完成了我的第一套Java课程后,我目前正在学习Java Swing课程。在本课中,我们将研究我们一直在研究的不同组件、按钮、工具栏等之间的通信。问题是,这是作为addActionListener方法的方法参数传递的。这是可行的,但是,我不完全理解它在做什么。我对此做了一些研究,发现this关键字最常用的用法是在具有相同名称变量的构造函数中。我找不到一个适合我的例子。通过查看下面的代码,我将解释我理解的部分代码Java 将“this”作为方法参数传递-澄清,java,swing,methods,this,actionlistener,Java,Swing,Methods,This,Actionlistener,在完成了我的第一套Java课程后,我目前正在学习Java Swing课程。在本课中,我们将研究我们一直在研究的不同组件、按钮、工具栏等之间的通信。问题是,这是作为addActionListener方法的方法参数传递的。这是可行的,但是,我不完全理解它在做什么。我对此做了一些研究,发现this关键字最常用的用法是在具有相同名称变量的构造函数中。我找不到一个适合我的例子。通过查看下面的代码,我将解释我理解的部分代码 import java.awt.FlowLayout; Implements Flo
import java.awt.FlowLayout; Implements FlowLayout class
import java.awt.event.ActionEvent; //Imports ActionEvent Class
import java.awt.event.ActionListener; //Imports ActionListener Interface
import javax.swing.JButton; //Imports JButton class
import javax.swing.JPanel; //Imports JPanel class
public class Toolbar extends JPanel implements ActionListener {
// ^ Inherits JPanel & Implements ActionListener Interface
private JButton helloButton; //Creating variable of JButton type
private JButton goodbyeButton; //Creating variable of JButton type
public Toolbar() { //Constructor
helloButton = new JButton("Hello"); //Creates new JButton
goodbyeButton = new JButton("Goodbye"); //Creates new JButton
helloButton.addActionListener(this); //Question 1
goodbyeButton.addActionListener(this); //Question 1
setLayout(new FlowLayout(FlowLayout.LEFT)); //Sets Layout Type to Left
add(helloButton); //Adds button to FlowLayout (Layout Manager) Interface
add(goodbyeButton); //Adds button to FlowLayout (Layout Manager) Interface
}
public void setTextPanel(TextPanel textPanel) {
//No Usage Yet!
}
public void actionPerformed(ActionEvent arg0) { //Unimplemented Method from ActionListener
System.out.println("A button was clicked"); //Prints after button is clicked.
}
}
问题1:正如您所看到的,在创建了两个JButton之后,我们添加了一个addActionListener方法,以查看是否已单击该按钮。如果已单击它,则它将执行在actionPerformed中键入的、从ActionListener接口实现的任何代码。在前面的课程中,我们有一种不同的方法使按钮响应单击。它做了同样的事情,但看起来是这样的:
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
textPanel.appendText("Hello\n");
}
});
在本例中,我们没有打印到控制台以测试actionListener是否工作,而是将文本从自定义组件附加到文本区域。在本文正上方的代码中,我们使用的是一个匿名类
所以。。。问题是,当它作为addActionListener中的方法参数传递时,它到底在做什么?我知道它正在打印一个被点击到控制台的按钮,但我不理解这是怎么做的,以发送按钮被点击到actionPerformed的逻辑
这就是应用程序的外观:
这是正在运行的应用程序,按钮在单击后已打印到控制台。我想这可能会让你更好地了解我在做什么。我希望有人能对此有所了解,并解释这在这种情况下是如何工作的。谢谢大家! 通过实现ActionListener,然后将其传递给addActionListener方法,您要求通过调用actionPerformed方法来通知执行的任何操作
或者,更简单地说,你给按钮你的电话号码,并要求它打电话给你,每当发生什么事
在前面的课程中,您说明了应该发生什么-打印此文本或向textPanel添加一些文本。要做到这一点,你需要在飞行中制作一个ActionListener。现在您自己实现了ActionListener,您可以请求回调,而不是动态创建一个侦听器。swing组件的addActionListener方法采用ActionListener类型的参数。实现ActionListener的类包含指定当有人与swing组件交互时应执行的操作的代码
当您将其传递给addActionListener方法时,您正在传递对正在实例化的当前对象的引用。事实上,正在实例化的当前对象也是ActionListener,因为它实现了ActionListener,因此可以传递给addActionListener方法
当您在GUI中与JButton交互时,将调用Toolbar类的actionPerformed方法,因为它是您注册JButton的ActionListener。这只是Toolbar类的一个实例。它在实例方法中用于表示当前实例。本质上,您可以想象您的类有另一个名为this的私有成员变量,它指向工具栏对象
由于Toolbar实现了ActionListener,您正在将新实例化的Toolbar对象指定为按钮的侦听器,这意味着单击按钮时将调用Toolbar.actionPerformed方法。这表示类的当前实例
工具栏类实现ActionListener接口,这意味着它提供actionPerformed方法的实现
因此,helloButton.addActionListenerthis;如果尝试从类声明中删除实现ActionListener,代码将无法编译
这样一来,工具栏实例可以被视为ActionListener对象,并可以传递给button.addActionListener
使用时
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
}
}
您可以动态创建ActionListener接口的新实现。这种实现称为匿名
这两种解决方案都是有效的。如果actionPerformed中的代码无法从其他地方使用,则首选匿名解决方案。假设所有导入都在那里,并且大写字母正确,则这两个示例也可以执行相同的操作:
public static void main(String args[]){
myFrame frame = new myFrame();
myFrame.addActionListener(new myListener);
}
public myFrame extends JFrame{
public myFrame(){
super("myFrame");
}
}
public myListener implements ActionListener{
public void ActionPerformed(ActionEvent e){
//Do Stuff
}
}
及
拥有ActionListener的优点是,如果您想将方法上的修饰符设置为私有,那么它可以更直接地访问字段和方法。
但是,如果您想避免处理多个b的if/else if异常
我建议您使用单独的ActionListener并提供一种方法来更改需要更改的内容,或者查看匿名类和lambda表达式。通常使用面向对象的编码,在您正在编码的类中扮演对象的角色是值得的。如果你那样做,这意味着我 因为Java是通过引用传递的,所以这是一个指向我的箭头
public class Foo implements ActionListener {
public void actionPerformed(ActionEvent e) {
// do something useful with e
}
}
这里我们写了一个类Foo。因为我们已经说过它实现了ActionListener,所以它必须有一个actionPerformed方法。任何东西都可以称之为:
ActionListener listener = new Foo(...);
ActionEvent event = ...;
foo.actionPerformed(event);
我们可以创建一个Foo并将其提供给生成事件的对象:
ActionListener listener = new Foo(...);
button.addListener(listener);
如果我们扮演这个对象,你可以把最后一行想象成“嘿”按钮!无论何时发生动作,都要告诉听众
现在,如果我们想让听者自己控制谁在说什么呢?嘿,巴顿,无论什么时候有行动都告诉我
public class Foo implements ActionListener {
public attachToButton(JButton button) {
button.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
// do something useful with e
}
}
想象一下按钮的addActionListener代码可能是什么样子可能会有所帮助:
public class JButton { // not the real JButton code, but it will be similar
private List<ActionListener> actionListeners = new ArrayList<ActionListener>();
public void addActionListener(ActionListener a) {
actionListeners.add(a);
}
// called internally when an event happens
private void onEvent(ActionEvent e) {
for(ActionListener listener : actionListeners) {
listener.actionPerformed(e);
}
}
}
因此,如果您是名为addActionListenerthis的侦听器,则该列表包含一个指向您的引用,每次发生动作时,按钮都会使用该引用轻拍您的肩膀。谢谢!你的回答很清楚。
public class JButton { // not the real JButton code, but it will be similar
private List<ActionListener> actionListeners = new ArrayList<ActionListener>();
public void addActionListener(ActionListener a) {
actionListeners.add(a);
}
// called internally when an event happens
private void onEvent(ActionEvent e) {
for(ActionListener listener : actionListeners) {
listener.actionPerformed(e);
}
}
}