Java anonymous class that implements ActionListener?

血红的双手。 提交于 2019-11-29 04:46:40

I usually go something like this:

JPanel panel = new JPanel();
panel.add(new JButton(new AbstractAction("name of button") {
    public void actionPerformed(ActionEvent e) {
        //do stuff here
    }
}));

AbstractAction implements ActionListener so this should satisfy the task.

It can be bad practice to squish so many lines of code together, but if you're used to reading it then it can be quite elegant.

It's quite ugly, but you could do the following using the ActionListener method and an anonymous class:

  f.getContentPane().add(new JButton(new AbstractAction("name of button") {
      private int counter = 0;

      public void actionPerformed(ActionEvent e) {
          ((JButton) e.getSource()).setText(Integer.toString(counter--));
      }
  }) {
      {
          setText("1");
      }
  });

To make it easier to access the counter you could move it out to the top level of your class and access it from both places where setText is called.

Implementing multiple types is generally a bad idea.

It is rarely necessary to extend JComponent classes, although a lot of bad software and tutorials do it. An idiom/hack that has been gaining ground recently is Double Brace - a class is only subclasses in order to give it an instance initialiser which acts like a with statement from other languages.

In this case, the relevant code can be written as:

JButton button = new JButton();
button.addActionListener(new ActionListener() {
    int counter = 1;
    {
        updateText();
    }
    public void actionPerformed(ActionEvent arg0) {
        --counter;
        updateText();
    }
    private void updateText()
        setText(Integer.toString(counter));
    }
});
f.getContentPane(button);

If it gets more complex, then you'll probably want to make an outer class (that does not implement ActionListener or extend JButton) to handle the data.

Also note, you should be using the EventQueue.invokeLater boilerplate to ensure that Swing components are only ever used on the AWT EDT.

I would not do something like that in a real-world program, but given the requirements in your assignment, you can hardly do better.

Well there is a much more elegant way to do it.

Unfortunately, it's not a Core Java/Swing approach.

You can use SwingBuilder in Groovy to achieve the same result, using slightly more terse syntax, e.g. psuedo code:

button(text: '' + counter,
         actionPerformed: {counter--; text = '' + counter + ''},
         constraints:BL.SOUTH)

[http://groovy.codehaus.org/Swing+Builder][1]

I wouldn't use this in your assignment though, I've seen students really deviate from the norm and get marked down for it, but at least you can include it as a possible avenue to investigate further.

I think what you have at present is absolutely fine though.

This is one of bad-practice tasks forced to do in homework only ;-) Bad things:

  • usage of ActionListener instead of Action which is bad in itself
  • as a consequence, scoping problems bubble up
    • counter's scope wider than necessary
    • need access to button inside the actionPerformed (via type-cast or accessing surrounding object's api)
  • unreadable (aka: unmaintainable) code

But, then .. we cannot resist, can we ;-) Here's a version using Action which is clean (or so I think) as to the first two issue, unreadable as all other examples (and I cheated, of course: first implemented the anonymous classes, then let the IDE do the inline

    f.add(new JButton(new AbstractAction() {

        int counter = 1;
        { // constructor block of action
            updateName();
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            counter--;
            updateName();
        }

        private void updateName() {
            putValue(Action.NAME, "" + counter);
        }

    })  { // subclass button 
          {  // constructor block button
            setBackground(Color.PINK);
        }}
    );
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!