aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes Can i put all of my action listeners(i will have hundreds) in a seperate class file and then use it? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Can i put all of my action listeners(i will have hundreds) in a seperate class file and then use it?" Watch "Can i put all of my action listeners(i will have hundreds) in a seperate class file and then use it?" New topic
Author

Can i put all of my action listeners(i will have hundreds) in a seperate class file and then use it?

Cody Long
Ranch Hand

Joined: Jan 01, 2009
Posts: 95
I am writing a Bible program and i wil have hundreds of listeners. can i put the in a seperate classs file and then call them form a diferent class? and if so could you please show me how. thanks in advance!!!


Duct tape is like the Force. It has a dark side, a light side, and it binds the whole universe together.
David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

This would be better asked in the Swing forum.
sean van buggenum
Greenhorn

Joined: May 16, 2008
Posts: 7
As anything can be a listener for something, the answer would be yes.
You can have your listeners anywhere. They would just need to be registered with the notifyer via the function 'addXXXListener' depending on what you are listening for, and the class which listens would have to implement the appropriate interface to be a such and such listener.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Correct me if I'm wrong, but are we really talking about hundreds of listeners? or are we really talking about hundreds of Action Handlers, one for each object that has an an Action Listener attached? Since all this is in one class, my guess is, there might only be one Action Listener, an instance of said class which extends ActionListener.



Cody Long
Ranch Hand

Joined: Jan 01, 2009
Posts: 95
Correct me if I'm wrong, but are we really talking about hundreds of listeners? or are we really talking about hundreds of Action Handlers, one for each object that has an an Action Listener attached? Since all this is in one class, my guess is, there might only be one Action Listener, an instance of said class which extends ActionListener.


I need to have a bunch of listeners for JMenu items and a bunch for JButtons and clickable JLists. could you help me with a way to improve the way i do this? i would rather not spend months writing hundreds of inner action listener classes. thanks.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
Cody Long wrote:
Correct me if I'm wrong, but are we really talking about hundreds of listeners? or are we really talking about hundreds of Action Handlers, one for each object that has an an Action Listener attached? Since all this is in one class, my guess is, there might only be one Action Listener, an instance of said class which extends ActionListener.


I need to have a bunch of listeners for JMenu items and a bunch for JButtons and clickable JLists. could you help me with a way to improve the way i do this? i would rather not spend months writing hundreds of inner action listener classes. thanks.


Well, honestly, My way is fine, but I haven't used a lot of different methods, so I can't really say my way is better than yours, but I think it might be a little less work.

Usually what I do for my applications is write a main GUI class that extends JPanel and implements whatever listener interfaces I need.

In my constructor for this main GUI class, or in a buildGUI method, I register this as the ActionListener for all of my components that need one. Each object so registered will have its own action command.

Then in the same class I will have one actionPerformed method. This method will have as its first line

String cmd = e.getActionCommand();

then I will have a series of code blocks of the form


As a result, my main GUI class is usually kind of lengthy, but as long as I keep it neat and well documented, it isn't a problem.
I think from a technical perspective this approach is fine. From a readability perspective, I suppose you could have a separate class that extends ActionListener, and have a single long ActionPerformed method with all the code blocks. Then in the main GUI you would declare an instance of this class to act as the action listener, and register to the object name.

Six of one, half a dozen of the other. Like I said, that's the way I do it. There maybe limitations to my approach if you want to re-use some of your listeners for other projects, other than that I don't see a big difference. And probably less work for this project. But I'm not a swing expert, so some of the guys might not like this approach, I don't know.

IN closing, I think there are probably advantages and disadvantages to my approach that we could discuss more. There is always at least a couple of decent ways to get the job done.

p.s. minore edits for clarity.

p.s. I suppose that my approach my be less typing in the devlopment stage, but probably a little more effort to maintain.
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10386
    
    8

I cannot possibly imagine why you need hundreds of listeners

If you have different controls acting as triggers for the same action (JMenu, context menu and say a button), check out AbstractAction.
You would generally subclass AbstractAction, and share the same action with the triggers.


[How to ask questions] [Donate a pint, save a life!] [Onff-turn it on!]
Cody Long
Ranch Hand

Joined: Jan 01, 2009
Posts: 95
Thank you for all of your help and i am going to try to use Fred's way to make the listeners. again thanks
pete stein
Bartender

Joined: Feb 23, 2007
Posts: 1561
Fred Hamilton wrote:Usually what I do for my applications is write a main GUI class that extends JPanel and implements whatever listener interfaces I need.
In my constructor for this main GUI class, or in a buildGUI method, I register this as the ActionListener for all of my components that need one. Each object so registered will have its own action command.
Then in the same class I will have one actionPerformed method. This method will have as its first line

As a result, my main GUI class is usually kind of lengthy, but as long as I keep it neat and well documented, it isn't a problem.
I think from a technical perspective this approach is fine. From a readability perspective, I suppose you could have a separate class that extends ActionListener, and have a single long ActionPerformed method with all the code blocks. Then in the main GUI you would declare an instance of this class to act as the action listener, and register to the object name.


I would argue strongly against this approach as it leads to the classic "switchboard" anti-pattern that does not scale well and can be difficult to debug. I would suggest that you create a different ActionListener for different actions. For instance, say you had a simple GUI Calculator with number buttons and operations buttons, then I'd recommend two action listeners, one for the numbers (and perhaps the decimal point), and one for the operations. Trying to combine the two just seems artificial and a set up for later disaster. Also I think you'll rarely find addActionListener(this) in production code but will see it frequently in very small demo code, which is probably the only place it belongs.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
pete stein wrote:
Fred Hamilton wrote:Usually what I do for my applications is write a main GUI class that extends JPanel and implements whatever listener interfaces I need.
In my constructor for this main GUI class, or in a buildGUI method, I register this as the ActionListener for all of my components that need one. Each object so registered will have its own action command.
Then in the same class I will have one actionPerformed method. This method will have as its first line

As a result, my main GUI class is usually kind of lengthy, but as long as I keep it neat and well documented, it isn't a problem.
I think from a technical perspective this approach is fine. From a readability perspective, I suppose you could have a separate class that extends ActionListener, and have a single long ActionPerformed method with all the code blocks. Then in the main GUI you would declare an instance of this class to act as the action listener, and register to the object name.


I would argue strongly against this approach as it leads to the classic "switchboard" anti-pattern that does not scale well and can be difficult to debug. I would suggest that you create a different ActionListener for different actions. For instance, say you had a simple GUI Calculator with number buttons and operations buttons, then I'd recommend two action listeners, one for the numbers (and perhaps the decimal point), and one for the operations. Trying to combine the two just seems artificial and a set up for later disaster. Also I think you'll rarely find addActionListener(this) in production code but will see it frequently in very small demo code, which is probably the only place it belongs.


Don't see any issues with dubugging, if you are careful with the implementation, but yeah, I agree there are probably plenty of situations where you wouldn't want to go whole hog with this approach. Anyways, I didn't mean to give a general recommendation of one listener for all the actions, just one example, perhaps a little extreme, of the concept of more than one action for a listener. Anyways I liked your suggestion which was halfway between the OP's original approach of a different listener for each action, and my example.

Never heard of a classic switchboard anti-pattern though. What do you mean by that?
pete stein
Bartender

Joined: Feb 23, 2007
Posts: 1561
Fred Hamilton wrote:Never heard of a classic switchboard anti-pattern though. What do you mean by that?


for instance,


ref: JosAH Switchboard listener
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
pete stein wrote:
Fred Hamilton wrote:Never heard of a classic switchboard anti-pattern though. What do you mean by that?


for instance,


ref: JosAH Switchboard listener


ok, well, do you differentiate between that example and the following...



I do it the second way, but it seems like the exact same thing.

Anyways, perhaps I misunderstand the semantics here. When I think of having more than one action for a single listener, doesn't it imply this kind of design, one if block for every action associated with the listener? So I guess I am still saying that I don't see this approach as being inherently bad, as long as it is properly managed and not taken to extremes. And as far as I can tell, based on your calculator example, you are not saying it is inherently bad either. agreed?
pete stein
Bartender

Joined: Feb 23, 2007
Posts: 1561
Fred Hamilton wrote:
ok, well, do you differentiate between that example and the following...

I do it the second way, but it seems like the exact same thing.

What matters most is are the actions performed within the actionPerformed method similar? Do they belong together? My calculator example is a case in point as the actions for all the number buttons are similar and all the operations buttons (if a simple calculator) again are similar and thus belong to two groups.


Anyways, perhaps I misunderstand the semantics here. When I think of having more than one action for a single listener, doesn't it imply this kind of design, one if block for every action associated with the listener? So I guess I am still saying that I don't see this approach as being inherently bad, as long as it is properly managed and not taken to extremes. And as far as I can tell, based on your calculator example, you are not saying it is inherently bad either. agreed?

Correct, again as long as the actions belong together.

And I'm not saying that my point here is gospel, but I am certainly not its originator nor its only adherent.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
pete stein wrote:
Fred Hamilton wrote:
ok, well, do you differentiate between that example and the following...

I do it the second way, but it seems like the exact same thing.

What matters most is are the actions performed within the actionPerformed method similar? Do they belong together? My calculator example is a case in point as the actions for all the number buttons are similar and all the operations buttons (if a simple calculator) again are similar and thus belong to two groups.


Anyways, perhaps I misunderstand the semantics here. When I think of having more than one action for a single listener, doesn't it imply this kind of design, one if block for every action associated with the listener? So I guess I am still saying that I don't see this approach as being inherently bad, as long as it is properly managed and not taken to extremes. And as far as I can tell, based on your calculator example, you are not saying it is inherently bad either. agreed?

Correct, again as long as the actions belong together.

And I'm not saying that my point here is gospel, but I am certainly not its originator nor its only adherent.


ok, point taken, if it means that the code is easier to read and maintain by *not* having all your eggs in one basket so to speak, then yes I see what you're saying that it is better if you have lots of actions to group actions according to function among two or more different listeners.

In which case I would like to comment to the original poster that my example should not be taken too literally if there are going to be hundreds of different actions, then a better option might be having several listeners, means several classes that implement the listener interface, each with its own action performed method.

David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

Fred wrote: I do it the second way, but it seems like the exact same thing.

From a logical standpoint, yes--but IMO using String literals as decision points isn't a great idea for at least the two obvious reasons.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
David Newton wrote:
Fred wrote: I do it the second way, but it seems like the exact same thing.

From a logical standpoint, yes--but IMO using String literals as decision points isn't a great idea for at least the two obvious reasons.


Well, I thought about it for a while, and the only thing that came to mind is that with e.getActionCommand() typos in the string literals wouldn't get picked up at compile time, which is a valid reason I hadn't considered, although with due care and testing it shouldn't be a big problem. What's the other reason?

p.s. I suppose it is being able to change the text on the MenuItem without having to change the if conditions?
David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

At the *very* least the strings should be coded as constants--that way at least the automated test code doesn't share the same risk.

The other was that you lose the help provided by IDEs.
Cody Long
Ranch Hand

Joined: Jan 01, 2009
Posts: 95
Thank you all for your help and i think i sort of understand pete stien's way of doing the action listeners and i will try it that way. I am also going to try to write a version in c++ because i have a bunch of extra time and i like c++. Thanks again!!!
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
David Newton wrote:At the *very* least the strings should be coded as constants--that way at least the automated test code doesn't share the same risk.

The other was that you lose the help provided by IDEs.


Can't argue with the 2nd one. The first one makes sense too, except it requires extra work, which would to a certain extent counterbalance the work saved in debugging, but ok yeah, point taken. Hadn't thought of any of that stuff. thanks for the tips.
David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

Fred Hamilton wrote: except it requires extra work,

Pay now or pay later--and it's invariably more expensive when you pay later. Technical debt can be hard to recover.
Fred Hamilton
Ranch Hand

Joined: May 13, 2009
Posts: 679
David Newton wrote:
Fred Hamilton wrote: except it requires extra work,

Pay now or pay later--and it's invariably more expensive when you pay later. Technical debt can be hard to recover.


kinda like buying insurance :)
salvin francis
Ranch Hand

Joined: Jan 12, 2009
Posts: 928

I Confess i have not gone thro the entire posts here,

here is my suggested solution:




This is my Approach, i may be wrong too give me better solutions if possible


My Website: [Salvin.in] Cool your mind:[Salvin.in/painting] My Sally:[Salvin.in/sally]
salvin francis
Ranch Hand

Joined: Jan 12, 2009
Posts: 928

Of course multiple classes can use the MyActionHandler as:

salvin francis
Ranch Hand

Joined: Jan 12, 2009
Posts: 928

Honestly i really really prefer string literals declared as final in an interface

They make coding easier to read and maintain:


You can be 100% sure they are constant throughout the program.

If i am not wrong, you dont even need to define them as final, they already are since they are a part of an interface.
David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

Isn't defining constants in an interface generally frowned upon these days (after Bloch)?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38896
    
  23
Sort of. The problem is that implementing an interface to get at its constants adds them to your public interface. Often this enlargement of the public interface is a bad idea, so that is why we use static import instead. Static import sort of allows us to pretend the fields are private fields of our class . . .
salvin francis
Ranch Hand

Joined: Jan 12, 2009
Posts: 928

hey i just researched on static imports and this is what i have found:

So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Readers of your code (including you, a few months after you wrote it) will not know which class a static member comes from. Importing all of the static members from a class can be particularly harmful to readability; if you need only one or two members, import them individually. Used appropriately, static import can make your program more readable, by removing the boilerplate of repetition of class names.


quoted from www.java.sun.com

But in my humble opinion, its not a bad idea,
By the way, is there a penalty to implement an Interface having 1000 variables to use just 2 of them
as opposed to just 2 static imports ???

I am very curious to know the answer to that.

i gotta check whether static imports work on interfaces or only for classes
Cody Long
Ranch Hand

Joined: Jan 01, 2009
Posts: 95
here is the link to download my program that i wrote in c++. it took a while but this is what i want my menus to be like. any help would be apreciated on how to make this work in java.
Michael Dunn
Ranch Hand

Joined: Jun 09, 2003
Posts: 4632
> here is the link to download my program that i wrote in c++

you may be better off posting a screenshot - most won't download/install/run a program just to see the equivalent of a screenshot.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Can i put all of my action listeners(i will have hundreds) in a seperate class file and then use it?