传递“这个”作为方法论证 - 澄清

时间:2015-06-18 15:53:33

标签: java swing methods this actionlistener

我目前正在完成Java第一套课程后的Java Swing课程。在本课程中,我们正在研究我们一直在研究的不同组件(按钮,工具栏等)之间的通信。问题是,“this”作为addActionListener()方法的方法参数传递。然而,这是有效的,我并不完全理解它在做什么。我做了一些关于“this”的研究,发现“this”关键字最常用的用法是在具有相同名称变量的构造函数中。我找不到适合我案例的例子。通过查看下面的代码,我将解释我理解的代码部分。

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()的背后的逻辑。

这就是应用程序的样子:

The application running, and printing to console!

这是运动中的应用程序,点击后按钮已经打印到控制台。我想它可能会让你更好地了解我在做什么。我希望有人可以对此有所了解,并解释“这个”在这方面是如何起作用的。谢谢!

6 个答案:

答案 0 :(得分:2)

this只是您Toolbar课程的一个实例。它在实例方法中用于表示当前实例。基本上你可以想象你的类有另一个名为this的私有成员变量,它指向一个Toolbar对象。

由于Toolbar实现ActionListener,您将新实例化的Toolbar对象指定为按钮的侦听器(意味着当单击按钮时将调用Toolbar.actionPerformed()方法。)

答案 1 :(得分:2)

代表您班级的当前实例。

Toolbar类实现了ActionListener接口,这意味着它提供了方法 actionPerformed 的实现。

因此,helloButton.addActionListener(this);成为可能(尝试从类声明中删除实现ActionListener,代码将无法编译)。

这样说,工具栏实例可以被视为ActionListener对象,可以传递给button.addActionListener。

使用时

btn.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent event) {
        }
}

您在动态中创建ActionListener接口的新实现。这种实现名为匿名

这两种解决方案都有效。如果无法在其他地方使用actionPerformed中的代码,请选择匿名解决方案。

答案 2 :(得分:1)

通过实施ActionListener然后将this传递给addActionListener方法,您要求通知您通过调用actionPerformed方法执行的所有操作。< / p>

或者,更简单地说,您正在给按钮提供电话号码,并要求它在发生任何事情时给您打电话。

在之前的课程中,您说明应该发生什么 - 打印此文本或向textPanel添加一些文本。要做到这一点,你就是在飞行中ActionListener。现在您自己实施ActionListener,您可以请求回复,而不是在运行中制作一个监听器。

答案 3 :(得分:1)

addActionListener组件的swing方法采用ActionListener类型的参数。实现ActionListener的类包含的代码指定当某人与swing组件交互时应该执行的操作。

当您将this传递给addActionListener方法时,您将传递对正在实例化的当前对象的引用。碰巧的是,实例化的当前对象也是ActionListener(因为它实现了ActionListener),因此可以传递给addActionListener方法。

当您与GUI中的JButton进行交互时,将调用actionPerformed类的Toolbar方法,因为那是您注册ActionListener的{​​{1}}与。

答案 4 :(得分:1)

这两个例子会做同样的事情(假设所有的进口都存在,并且大写是正确的):

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
    }
}

public static void main(String args[]){
    myFrame frame = new myFrame();       
}

public myFrame extends JFrame implements ActionListener{
    public myFrame(){
        super("myFrame");
        this.add(this);
    }

    public void ActionPerformed(ActionEvent e){
        //Do Stuff
    }
}

如果要在方法ActionListener上创建修饰符,则thisprivate的优点是可以更直接地访问字段和方法。 但是,如果你想避免if / else if monstrosities处理多个按钮,我建议使用一个单独的ActionListener(并提供一种方法来更改需要更改的内容),或者查看匿名类和lambda表达式。 / p>

答案 5 :(得分:1)

通常使用面向对象的编码,值得角色扮演你正在编码的类的对象的一部分。如果你这样做,&#34;这个&#34;意味着&#34;我&#34;。

因为Java是通过引用传递的,&#34;这个&#34;是指向&#34; me&#34;。

的箭头
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);

如果我们角色扮演对象,你可以把这最后一行想象成&#34;嘿button!每当动作发生时,请告诉listener。&#34;。

现在,如果我们希望听众能够控制谁自己告诉它什么呢? &#34;嘿button,只要行动发生就告诉&#34;。

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);
        }
    }
}

因此,如果您是调用addActionListener(this)的侦听器,那么该List包含一个指向您的引用,每次操作发生时该按钮用于敲击您的肩膀。