Java 如何在没有内部类的情况下实现多个操作侦听器?

Java 如何在没有内部类的情况下实现多个操作侦听器?,java,swing,awt,Java,Swing,Awt,我对Java非常陌生,我想知道是否可以在同一个类中使用多个动作侦听器(例如,当使用多个JButton对象时),而不使用内部类。提前谢谢你。是的。这是可能的。您可以只使用类路径上的外部类或Java8中的lambdas实现ActionListener public class MyListener implements ActionListener { // .. } 然后像 btn.addActionListener(new MyListener()); 或者(使用Java8+)一个类似l

我对Java非常陌生,我想知道是否可以在同一个类中使用多个动作侦听器(例如,当使用多个JButton对象时),而不使用内部类。提前谢谢你。

是的。这是可能的。您可以只使用类路径上的外部类或Java8中的lambdas实现
ActionListener

public class MyListener implements ActionListener {
  // ..
}
然后像

btn.addActionListener(new MyListener());
或者(使用Java8+)一个类似lambda的

btn.addActionListener(ae -> { System.out.println("Button Clicked"); });

是的,您可以创建自己的
MyButton
对象,该对象扩展
JButton
并实现
ActionListener
,然后使用它代替简单的
JButton

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;


public class MyButton extends JButton implements ActionListener
{
    public MyButton() {
        super();
        addActionListener(this);
    }

    @Override public void actionPerformed(ActionEvent e) {
        // do something
    }
}

现在,
MyButton
有了一个自定义行为。

使用Java 8,您可以使用lambda表达式实现如下侦听器:

import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JTextField;

public class ActionListenerExample {
    ActionListenerExample() {
        JTextField tf=new JTextField();
        tf.addActionListener(ev -> textAction(tf));
        JButton b=new JButton();
        b.addActionListener(this::buttonClicked);
    }

    private void textAction(JTextField tf) {

    }
    private void buttonClicked(ActionEvent ev) {

    }
}
但即使在Java 8之前,也有一个动态生成侦听器的选项:

import static java.beans.EventHandler.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JTextField;

public class ActionListenerExample1 {
    ActionListenerExample1() {
        JTextField tf=new JTextField();
        tf.addActionListener(create(ActionListener.class,this,"textAction","source"));
        JButton b=new JButton();
        b.addActionListener(create(ActionListener.class, this, "buttonClicked", ""));
    }

    public void textAction(JTextField tf) {
        System.out.println(tf);
    }
    public void buttonClicked(ActionEvent ev) {
        System.out.println(ev);
    }
}

它具有更高的开销,并且缺乏编译时安全性,但另一方面,它可以使用多个侦听方法生成侦听器,而lambda expression只支持一个侦听器方法。

欢迎使用堆栈溢出!你的问题相当广泛,表面上可以简单地回答“是”。你需要为你的问题提供一点背景(你想达到什么目的)和一些细节来展示你迄今为止的尝试以及你的问题发生的地方。请看一看一个很好的问题:“JRichardSnape,谢谢你,我现在会考虑这个问题的答案,然后再回来提供更多的信息。好吧,还有其他的方法,但是内部类是最有效的方法吗?”或者它只是消耗了更多的内存,这就是我问这个问题的真正原因,我觉得内部类消耗了很多内存,我想知道是否还有另一种更少的内存消耗方法。内部类消耗的内存量与非内部类完全相同。什么让你感觉不一样?我不是说类,我是说一般来说,使用动作监听器的最有效方式是什么,这样它们就不会消耗那么多内存?@user4442652 Java使用动态内存模型,您无法显式管理它。一般来说,不消耗太多内存的最有效方法是不消耗太多内存。侦听器的内存消耗在实际应用程序中是不相关的。您可以使用分析工具来分析正在运行的应用程序,很快您就会发现侦听器的内存消耗是多么微不足道。好吧,还有其他方法,但是内部类是最有效的方法吗?或者它只是消耗了更多的内存,这就是为什么我问这个问题,我觉得内部类消耗了很多内存,我想知道是否还有另一种消耗更少内存的方法,这取决于你如何定义效率。在大多数情况下,使用lambda表达式是最有效的方法,但正如前面所说,它需要Java 8,并且只适用于单一方法接口,如
ActionListener
。对于其他情况,通过
java.beans.EventHandler
生成侦听器将减少应用程序的代码大小,并可能减少初始化时间,但在运行时成本较高。还可以选择使用顶级类而不是内部类。这将增加源代码的数量,但与内部类相比,会产生更小的类文件。实现侦听器
接口
,而不在源代码上注册侦听器是没有效果的。让源组件实现监听器
接口
需要将组件本身注册为监听器,这是一种糟糕的编码实践。是的,你说得对,我忘了将按钮注册到监听器。刚刚编辑。