3

i am trying to learn more about event handling but everywhere i read about it, it's mainly about how to use it so something happens but not how it works.

So far i know about 2 ways to make something happen when a button is clicked.

ActionListener:

myButton.addActionListener(new ActionListener() { @override actionPerformed... });

and AbstractAction:

public class MyAction extends AbstractAction {
    public MyAction(String text, ImageIcon icon, String desc, Integer mnemonic) {
        super(text, icon);
        putValue(SHORT_DESCRIPTION, desc);
        putValue(MNEMONIC_KEY, mnemonic);
    }
    public void actionPerformed(ActionEvent e) {
        System.out.println("Action", e);
    }
}

MyAction myAction = new MyAction(...);
myButton.setAction(myAction);

I know that i can write everything i want to happen into the actionPerfomed() method.

But since i do not know, what exactly happens in the background I can not tell if one has any advantage over the other or which one i should use in which situation?

Flikk
  • 520
  • 3
  • 10

1 Answers1

2

if you extend AbstractAction, you can't extend any other classes. In any case, you might want to avoid subclasses whenever you can. I would personally recommend implementing the interface ActionListener and then adding an action Listener to your swing object (or whatever you listen on) while using the "this" keyword.

public class ClassName implements ActionListener {
    private JButton button = new JButton("click me");
    public ClassName() {
        button.addActionListener(this);
    }
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == button) {
            //perform action
        }
    }
}

Of course, you also add the ActionListenerdirectly (by using .addActionListener(new ActionListener() {});, but by using this,you can group all actions together.

//edit: Another way would be using MouseListener, which can listen to any clicks on your object, therefore enabling you to also use swing objects like JLabel as "buttons" - however, if you use JButtons, this would be unnecessary effort, considering that ActionListener is way easier to use, and you don't have to create lots of classes (such as mousePressed, mouseClicked, mouseReleased, etc.). However, if you anyway need MouseListener somewhere, you might want to think about using them so all events are grouped together. Note: I do NOT know if ActionListener and MouseListener are equally fast, or if one of these methods are better! If your program requires a lot of power already, you might want to use ActionListener, which i guess is the faster way, if any of the two solutions is the faster one.

PixelMaster
  • 895
  • 10
  • 28
  • Then would there ever be a situation someone would use a class that extends AbstractAction instead of implementing ActionListener? – Flikk Feb 20 '16 at 14:18
  • @Flikk i don't think it makes a lot of sense to extend `AbstractAction` instead of implementing `ActionListener` - however, you *could* extend `AbstractAction` if you want to define your own subclass of it. For example, I once created a class that extends abstractAction because I wanted to create key bindings, and at some point a certain method required an "Action" as a parameter (`ActionMap.put(Object key, Action action`). I'm not too familar with the `Action` class, though, so maybe I wouldn't have needed it there either. – PixelMaster Feb 20 '16 at 15:07
  • "but by using `this`, you can group all actions together." - This is not ideal in some cases, for example when the class implements an action for a lot of events: the `#actionPerformed()` method will be full of `if(e.getSource == thisbutton) {...} else if (e.getSource() == thatButton) {} else if (...)` that you can avoid by just using anonymous implementations of ActionListener or AbstractAction that do the single bit they are meant for and nothing else. It keeps different functionalities separated. – klaar Sep 06 '16 at 07:04