Java:使用动作监听器在该类的对象上调用另一个类中的函数

Posted

技术标签:

【中文标题】Java:使用动作监听器在该类的对象上调用另一个类中的函数【英文标题】:Java: Using an actionlistener to call a function in another class on an object from that class 【发布时间】:2010-11-23 17:39:56 【问题描述】:

基本上我想要做的是获得一个开始按钮来启动在另一个类中运行并作用于另一个对象的方法。

我的监听器代码:

button1a.addActionListener(new ActionListener() 
    public void actionPerformed (ActionEvent event) 
        // Figure out how to make this work
        //sim.runCastleCrash(); 
    
 );

其他类的代码:

public static void main(String[] args) 
    CastleCrash sim;
    sim = new CastleCrash();

public void runCastleCrash() 
    System.out.println("Castle Crash is beginning...");
    //Other method parts here to be added

我觉得这不会太难,但我错过了一块。

【问题讨论】:

您遇到了什么错误?当您尝试将 actionListener 添加到按钮时,sim 变量是否还在范围内?一个典型的陷阱是变量必须是 final 才能从匿名内部类(例如 ActionListener)访问。 我收到错误:线程“main”中的异常 java.lang.Error:未解决的编译问题:无法解决 sim 我认为您是对的,因为 sim 不在范围内,但我不知道如何使它成为最终的...... 请看 McDowell 的回答,这就是我要回答的。 【参考方案1】:

我遇到了和你一样的问题,我就是这样解决的。

您可以使您的对象成为最终对象(final CastleCrash sim = new CastleCrash();),但我不想这样做,或者您可以制作类似 setter 方法的东西来在其他类中运行该方法:

我的监听类代码:

button1a.addActionListener(new ActionListener()


    public void actionPerformed (ActionEvent event)
    
    //How to make this work ?
    //Like this:
    runCC();
    
);

public void runCC()

    CastleCrash sim = new CastleCrash();
    sim.runCastleCrash();

其他类的代码:

public void runCastleCrash()
   
    System.out.println("Castle Crash is beginning...");
    //Other method parts here to be added

希望对您有所帮助,祝您好运! :)

【讨论】:

【参考方案2】:

McDowell 已经通过很好的示例实际回答了如何从事件侦听器(或一般的匿名内部类)访问变量。但是,a more general Sun resource on Event Listeners in Swing 是规范的,并且很好地概述了编写它们时要考虑的所有注意事项。

【讨论】:

【参考方案3】:

在匿名类中引用事物的一种方法是使用 final 关键字:

  public static void main(String[] args) 
    final Object thingIWantToUse = "Hello";

    JButton button = new JButton("Click");
    button.addActionListener(new ActionListener() 
      @Override public void actionPerformed(ActionEvent e) 
        System.out.println(thingIWantToUse);
      
    );

    JFrame frame = new JFrame();
    frame.setLayout(new FlowLayout());
    frame.add(button);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  

或者,您可以访问封闭类型的成员(变量或方法):

public class ActionListenerDemo2 
  private final JFrame frame = new JFrame();
  private Object thingIWantToUse = "Hello";

  public ActionListenerDemo2() 
    JButton button = new JButton("Click");
    button.addActionListener(new ActionListener() 
      @Override public void actionPerformed(ActionEvent e) 
        thingIWantToUse = "Goodbye";
        System.out.println(thingIWantToUse);
      
    );
    frame.setLayout(new FlowLayout());
    frame.add(button);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  

  public static void main(String[] args) 
    new ActionListenerDemo2().frame.setVisible(true);
  

【讨论】:

我不太明白你描述的第二个选项。如何访问封闭类型的方法? 如果您将方法doFoo() 添加到AnctionListenerDemo2,那么您可以从actionPerformed 内部调用它。 actionPerformed 属于接口ActionListener 的匿名内部类实现。此处介绍嵌套类:java.sun.com/docs/books/tutorial/java/javaOO/nested.html【参考方案4】:

不知何故,您需要一个对可从您的 actionListener 调用的 CastleCrash 对象的引用。

您可能想要继承 JFrame 或包含您的 JButton 的任何东西,以便它同时拥有您的 main 方法和 CastleCrash 属性,然后可以从您的匿名内部类 Actionlistener 中引用该属性。

但是 - 请注意,您看起来正在从 GUI 事件线程(将调用动作侦听器)中调用一个长时间运行的方法。这通常是个坏主意,您的 GUI 会变得无响应。

请参阅http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html,尤其是 SwingWorker 类中有关如何避免该问题的想法。

【讨论】:

以上是关于Java:使用动作监听器在该类的对象上调用另一个类中的函数的主要内容,如果未能解决你的问题,请参考以下文章

Servlet监听器笔记总结

监听器

监听器入门看这篇就够了

java在动作监听器中引用类

来自另一个类的 JButton 动作侦听器

如何监听另一个页面上发生的动作?