Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the common way to program action listeners?

I just started to learn how to use action listeners. To my understanding it works in the following way:

  1. There are some classes which contains "addActionListener" method by default (for example classes for buttons).

  2. Using this method we add an action listener to an object. For example: listenedObject.addActionListener(listeningObject).

  3. When an action with the "listenedObject" is performed, the "actionPerformed" method of the "listeningObject" will be called. So, it means that when we program a class for the listeningObject, we need to put there "actionPerformed" method.

What is not clear to me, should we create a new class for every object that we want to listen. It does not seem to me as an elegant solution. On the other hand, if we have one action listener class for all (or at least many) object, than we have a problem since a instance of this class will not know which object is calling the "actionPerformed" method (and we need to know that since actions performed by the actionPerformed differs depending on who is called for this method).

In my opinion, for every listened object we need to create are "personal" action listener and we can do it by setting a specific value to the corresponding field of the action listener. But I am not sure that it is a standard way to go? How do usually people do it?

like image 696
Roman Avatar asked Mar 12 '10 16:03

Roman


3 Answers

The most common way to handle this - judging from my own personal experience - is to simply create an anonymous inline class. Like this:

listenedObject.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent evt) {
        // Your action handling code in here
    }
});

And often I've seen people place a call out to a method of the object containing the listenedObject. For example, in a Dialog that has a button:

myOkayButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent evt) {
        okayButtonPressed();
    }
});

Then later in the dialog class:

private void okayButtonPressed() {
    // Do what we need to do
}
like image 164
Daniel Bingham Avatar answered Nov 05 '22 06:11

Daniel Bingham


Personnaly, when possible, i prefer to use an Action class (as an example a subclass of AbstractAction) instead of simply relying on an action listener. This way, I can provide the originating widget a name, an icon, a tooltip, and so on ...

like image 41
Riduidel Avatar answered Nov 05 '22 07:11

Riduidel


The way I have always found useful (for navigation purposes) is to create an anonymous inner class which then delegates to the outer class:

listenedObject.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent evt) {
        listenedObject_actionPerformed(evt);
    }
});


private void listenedObject_actionPerformed(ActionEvent evt) {
    //Your handling goes here
}

It is then much easier to get to your handling code in an IDE using a structural lookup (CTRL+F12 in IDEA, CTRL+O in Eclipse).

The problem of using a single class (like a GUI MyCoolPanel) as the common listener to a bunch of its components (buttons etc) is that the actionPerformed method then has a lot of ugly if-else comparisons to figure out which button has actually been pressed - not very OO at all!

You certainly should not get overly worried about the performance aspects of this kind of thing - they are likely to be negligible in the extreme! Premature optimization is famously a bad thing

like image 31
oxbow_lakes Avatar answered Nov 05 '22 06:11

oxbow_lakes