• Post Reply Bookmark Topic Watch Topic
  • New Topic

What is the common structure for your ActionListeners?

 
Ren Shao
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Suppose you have a JPanel with a couple of components on that, and all of them need an ActionListener implementation, what's the common way to do that?

The current structure I use is create ActonListeners as inner classes. So my code is something like

class A extends JPanel{
JButton b1;
JButton b2;
...
...

class ActionListener1 implements ActionListener{
...
}

class ActionListener2 implements ActionListener{
}
}

and I don't think that's the proper way to do that.
can any one tell me which is the best solution for that, thanks
 
Warren Dew
blacksmith
Ranch Hand
Posts: 1332
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm lazy and I generally just have the panel - or even something at a higher level, like the frame - be the action listener and dispatch events based on the source of the event. I won't claim that's necessarily the "right" way to do it, but it works for me.
 
Pat Hays
Ranch Hand
Posts: 138
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Ren,
I think this way would be better.
 
Daniel Mayer
Ranch Hand
Posts: 103
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I prefer

 
Craig Wood
Ranch Hand
Posts: 1535
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
We have lots of options. Some criteria for deciding which options to use in different situations are:
1 - assign listeners by function or component type, eg, one listener for JButtons, another for JTextFields or JTextComponents. So a cast to obtain a reference to the event source is easy, eg,

which offers flexibility in handling the event and allows continuity in the code, ie, it is easier to understand and follow.

2 - organize listeners so your program flow is easy to understand and follow, especially if you or someone else will need to look at your code again in the future.

3 - listeners can be specialized according to different processes in your program.

Using named inner (nested) classes is an excellent way of dealing with listeners. There is no doubt about where their components (that they listen to) are located, the event code is neatly encapsulated inside the class making it easy too find and maintain, and the class name can say a lot about what it does or how it contributes to the program. Also they can easily hold state for processes in the program further contributing to ease in following program activity.
 
Ren Shao
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hi, the reason I don't use anonymous inner class it because the actionPerformed() method always need the reference of other components in that panel, and there is no way of using "this.button1" inside the inner class.

any idea of retrieve reference of other components in anonymouse inner class?
 
Ren Shao
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
ah.., sorrry, I think Pat Hays's code solve the problem I asked above. thanks.

However, got another question, the solution Warren Dew mentioned should be something like this:

class A extends JFrame implements ActionListener{
JButton b1;
JButton b2;

public void actionPerformed(ActionEvent e){
if (e.getSource() == b1){....}
else if(g.getSource() == b2) {....}
}
}

by doing that, we avoid creating multiple inner classes, and will we gain a big performance improve from it? and it this solution recommended?
[ September 18, 2004: Message edited by: Ren Shao ]
 
Craig Wood
Ranch Hand
Posts: 1535
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes this is a recommended way. You may experience some improvement in performance.
 
Daniel Mayer
Ranch Hand
Posts: 103
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Craig Wood:
Yes this is a recommended way. You may experience some improvement in performance.


Huh? I wholeheartedly disagree!

First, I don't think that it improves performance. How would it? After all, in contrast to using a new listener for each button, we need additional if statements that need to be executed every time some action is executed.

Second, who cares wether the action executed after you pressed a button takes a millisecond longer?

And most importantly, it makes it harder to see what is executed when a button is pressed - instead of just taking a look at the initialization of the button, you need to find the right then-block in a rather big method.
 
Daniel Mayer
Ranch Hand
Posts: 103
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ren Shao:
hi, the reason I don't use anonymous inner class it because the actionPerformed() method always need the reference of other components in that panel, and there is no way of using "this.button1" inside the inner class.

any idea of retrieve reference of other components in anonymouse inner class?


OuterClassName.this.button1
 
Don Kiddick
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Craig Wood:
Yes this is a recommended way. You may experience some improvement in performance.


I think may is the operative word... also by doing that you are violating the single responsibility principle.

Use anonymous classes or just inner classes if you really need to.
D.
 
Jez Nicholson
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
to further cloud the waters....

classes like HTMLEditorKit define actions that can be applied to a JEditorPane containing html. They neither belong to the JEditorPane nor to an html document, but the two combined. They are written as static classes which get hold of the components from the ActionEvent that has been passed in....

e.g.
 
Don Kiddick
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't see how that clouds the waters....Actions are not the same as ActionListeners.
 
Jez Nicholson
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hmmm...where do they get that actionPerformed method from then?
 
Don Kiddick
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
From ActionListener, but they're not the same thing. Actions also allow you to define, in a single place, certain properties, such as the description and whether it's enabled or disabled. As such you generally wouldn't define anonymous Actions.
D.
 
Warren Dew
blacksmith
Ranch Hand
Posts: 1332
2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Craig Wood:

Yes this is a recommended way. You may experience some improvement in performance.

Just to clarify for anyone who is interested, I don't do it that way for performance; I do it for clarity. I think any improvement from performance would be microscopic.

Don Kiddick:

I think may is the operative word... also by doing that you are violating the single responsibility principle.

Use anonymous classes or just inner classes if you really need to.


Using inner classes would violate the single responsibility principle just as much, since the outer class would still be responsible for handling all the different events.

For me, having all the events for a panel or frame dispatched in a single function makes the code clearer, because I can look in one place and see all the actions the object may expect. I think that for a well defined Swing application, that won't be more than half a dozen actions, and the function won't be "rather big" at all - in fact, it will generally be rather small.

I do agree that a large Swing application should not try to put force all the actions into a single, application wide dispatch function.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!