【问题标题】:How to create Action Listener inside anonymous class?如何在匿名类中创建动作监听器?
【发布时间】:2014-04-05 06:25:12
【问题描述】:

我目前有一个 Frame 类,它创建一个框架、添加按钮和标签。我目前在我的 Frame 类中有动作侦听器的代码,我需要移动它以便从匿名类调用动作侦听器。这是我目前拥有的。

 public static void main(String[] args)
 {
   Frame grid = new Frame();
    grid.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    grid.setVisible(true);
    grid.pack();
    grid.setTitle("Frame");
}

public class Frame extends JFrame
{
ImageIcon green = new ImageIcon("green.png");
JLabel label;
public JButton button1,button2;

public Frame()
{

    setLayout(new GridLayout(4,4));

  /**create buttons*/
    button1 = new JButton("");
    add(button1);
    button2 = new JButton("");
    add(button2);
    label = new JLabel(green);
    add(label);



/**Add action listener to buttons, I need these 2 liseners in a anonymous class */
button1.addActionListener(new ActionListener() 
{
        public void actionPerformed(ActionEvent arg0) 
        {
           button1.setText("X");                       
}

});
button2.addActionListener(new ActionListener() 
{
public void actionPerformed(ActionEvent arg0) 
{
           button2.setText("X");    

}

});

谁能告诉我如何移动这个 actionlistener 以便从匿名类中调用它?我假设我在创建框架时主要执行此操作?大概是这样的吧?

Frame grid = new Frame(){
       //Code might go here?
}

我不确定,我是匿名课程的新手。谁能告诉我如何在匿名类中实现动作监听器?

【问题讨论】:

  • 您需要提供一些方法来将ActionListener 注册到按钮上,可能是通过getter 或setter

标签: java user-interface jframe actionlistener anonymous-class


【解决方案1】:

你的意思可能是这样的:

class Frame 
{
    private JButton button1;

    // Here it is:
    private ActionListener firstActionListener = new ActionListener()
    {
        public void actionPerformed(ActionEvent arg0) 
        {
            button1.setText("X");
        }
    };

    public Frame()
    {
        ....
        button1.addActionListener(firstActionListener);
    }
}

虽然我想知道你需要这个做什么。你可能想看看http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html

【讨论】:

  • 谢谢你这是完美的。你能告诉我为什么你在 Frame 类中而不是在 main 中这样做吗?这是唯一的方法吗?
  • 您可以在main 中以相同的方式声明firstActionListener。但是,更不清楚您为什么要这样做。 (如果它是在类中声明而不是在 main 中,例如,您可以稍后从按钮中 remove 这个 ActionListener。但是当它仅在 main 中声明时,这基本上是和你已经用过的button1.addActionListener(new ActionListener() { ... }一样...
【解决方案2】:

您不能简单地将侦听器添加到既不支持您尝试附加的侦听器的组件,也不能添加到您没有引用的组件。

也就是说,JFrame 不支持ActionListener,并且您没有对要添加操作的按钮的引用。

我知道您已经制作了按钮public,但对我来说,这是一个坏主意,因为您将组件暴露给外部修改。没有什么能阻止代码改变按钮的状态,从 Frame 类中夺走控制权。

相反,您应该让相关方能够注册以了解按钮何时被激活,例如...

public static class Frame extends JFrame {

    ImageIcon green = new ImageIcon("green.png");
    JLabel label;
    private JButton button1, button2;

    public Frame() {
        //...
    }

    public void addButton1ActionListener(ActionListener listener) {
        button1.addActionListener(listener);
    }

    public void addButton2ActionListener(ActionListener listener) {
        button2.addActionListener(listener);
    }

    public void removeButton1ActionListener(ActionListener listener) {
        button1.removeActionListener(listener);
    }

    public void removeButton2ActionListener(ActionListener listener) {
        button2.removeActionListener(listener);
    }

然后,您只需将ActionListener 添加到您想要的任何按钮,例如...

public static void main(String[] args) {
    Frame grid = new Frame();
    grid.addButton1ActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            // Do stuff
        }
    });
    grid.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    grid.setVisible(true);
    grid.pack();
    grid.setTitle("Frame");
}

现在,这引发了一些问题,因为现在您已经提供了对底层按钮的访问权限,而您可能不想这样做。

现在,超越问题,我可能会建议使用某种模型。这将应用于Frame,这将允许它根据需要修改其状态,然后将事件通知返回给相关方,说明某些状态或其他状态已更改并且他们应该采取适当的措施,例如更新视图。

MVC 模式最好地描述了这一点

【讨论】:

    猜你喜欢
    • 2023-03-12
    • 2014-04-03
    • 1970-01-01
    • 2021-07-02
    • 2014-10-13
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多