What is the general way to program action listeners?

I was just starting to learn how to use action listeners. As far as I understand, it works as follows:

  • By default, classes are used that contain the addActionListener method (for example, classes for buttons).

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

  • When an action is executed with "listenedObject", the "actionPerformed" method is called for "listenObject". So this means that when we program the class for the listenObject, we need to put the actionPerformed method there.

What I don’t understand is whether we should create a new class for each object that we want to listen to. This does not seem to me an elegant solution. On the other hand, if we have one class of action listener for all (or at least many) objects, then we have a problem, because an instance of this class will not know which object calls the actionPerformed method (and we need that the actions performed by actionPerformed vary depending on who is called for this method).

In my opinion, for each object we listen to, we need to create a "personal" action performer, and we can do this by setting a certain value in the corresponding field of the action listener. But I'm not sure if this is the standard way to go? How do people usually do this?

+4
source share
6 answers

The most common way to deal with this β€” judging by personal experience β€” is simply to 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 saw people access the method of an object containing listenedObject. For example, in a dialog with a button:

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

Then in the dialog class:

 private void okayButtonPressed() { // Do what we need to do } 
+7
source

Personnaly, when possible, I prefer to use the Action class (as an example, a subclass of AbstractAction ) instead of just relying on the action listener. Thus, I can provide the widget recipient with a name, icon, tooltip, etc. ...

+2
source

The way I always found it 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 } 

Then it is much easier to get the processing code in the IDE using the structural search (CTRL + F12 in IDEA, CTRL + O in Eclipse).

The problem of using one class (for example, the MyCoolPanel GUI) as a common listener for a group of its components (buttons, etc.) is that the actionPerformed method has many ugly if-else comparisons with figuring out which button is pressed is not very OO at all!

Of course, you should not worry too much about the performance aspects of these kinds of things - they are likely to be negligible as a last resort! Premature optimization is a bad thing.

+2
source

The way I have always found it useful is to create a separate class that implements the ActionListener interface and all the other methods needed to complete the action. Thus, the action is not tied to a specific object and can be launched using a button, menu, etc. A bit like the Team Template I think. It keeps the code simple.

Anonymous classes cannot be reused.

Redirecting the object containing listenedObject results in gigantic classes that are difficult to maintain.

+1
source

Beware that removeActionListener methods exist for any reason. You can skip listeners if the objects you are listening to die with the object that processes the events. But if your component is listening on a model supplied from an external source, you must add your listeners to addNotify and remove them in the removeNotify methods. Otherwise, you may have a memory leak.

0
source

Perhaps this is not actually the case at the moment, but I believe that in the near future (after the release of Java 7) something like this will be the usual way:

 listenedObject.addActionListener ( #{doSmth();} ); 
0
source

Source: https://habr.com/ru/post/1303957/


All Articles