如何在匿名类中创建Action Listener?

时间:2014-03-03 23:25:35

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

我目前有一个类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以便从匿名类中调用它吗?我假设我在创建框架时在main中执行此操作?这样的事可能吗?

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

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

2 个答案:

答案 0 :(得分:0)

你可能意思是这样的:

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

答案 1 :(得分:0)

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

也就是说,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模式

来描述