aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes the only way to make it worse is to use action commands... Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "the only way to make it worse is to use action commands..." Watch "the only way to make it worse is to use action commands..." New topic
Author

the only way to make it worse is to use action commands...

Simone Cittadini
Greenhorn

Joined: Apr 28, 2006
Posts: 13
From "frame listeners vs. button listeners"

the only way to make it worse is to use action commands...


Doh! what's wrong with action commands now !? Maybe my next post should be "where I have to look to learn the right way to do a gui ?"

Meanwhile, in my app there are two columns of buttons, like this :

[Afghanistan][do stuff]
[Algeria][do stuff]
...
[Zimbabwe][do stuff]

You know the exact number of lines only when you start the app, clicking on the right button you do the stuff for all the nation (this phrase sounds funny, doesn't it ?). Clicking on the right pops up another frame with more detail, like :

[Italy proper][do stuff]
[Italy TIM][do stuff]
[Italy H3G][do stuff]
etc..

when clicking on [Italy]

my code is like :

for (int i = 0; i < nations.length; i++) {
create a left JButton(nations[i])
create a right JButton("do stuff")

set right's button action command to "nations[i]"

add the listeners ...
}

then ...

RightButtonActionAdapter(ActionEvent e){
actionPerformed(e){
call some facade.doStuff(e.getActionCommand()) method
}

}


Is it wrong for some reason I'll see only when it's too late ?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38865
    
  23
You would have done better to add this query to the original thread about ActionListeners.

The original posting was about what happens if you use your JFrame (etc) as an ActionListener;
The reason it is wrong is that you will get a nasty block of if statements rather like this:-


You have a situation where you have duplicated code (in fact I wrote that fictitious example with copy-and-paste), which does the same thing several times. Whoever wrote that would have no end of difficulty whenever they needed to alter or maintain the code, and each instruction would involve the risk of an error.

What you are suggesting is rather better, because you don't have the daft repetitions, but you are still making life complicated for yourself.

Be careful about Adapters; it only takes a tiny spelling error to produce a class which compiles nicely and won't run.
There isn't an ActionAdapter anyway; they only wrote Adapters when the Listener has two or more methods. So you will have to implement the ActionListener interface, and you call whatever class you get next a SomethingListener.

What you ought to be writing is something like this (which won't work in J1.4):-
As an alternative to the private inner class, you can put the constructor method and the actionPerformed method into an anonymous inner class in the addActionListener() call.
You can call your second pop-up box in the actionPerformed method rather than what I wrote.

CR
[ April 29, 2006: Message edited by: Campbell Ritchie ]
Simone Cittadini
Greenhorn

Joined: Apr 28, 2006
Posts: 13
That's nice, also now I've understood why JBuilder was calling the class an 'adapter', (and why I usually won't need an adapter).
Only one last fast question (which will be automatically answered when I'll refactor my code, but I'm asking anyway)

This way you have one listener for every Nation, and there are something like 300 nations, 770 if we consider the more detailed panels popping up when you click the left button, but you tipically want to do detailed stuff only for two or three nations a day, so let's say 350 listeners instantiated in the average life of the app. How much a listener "weights" ? will this change impact on the speed of the overall system ?
My first version of this app loaded all the Nation classes at start, I happily coded it with a 20 nations db as backend and less happily thrashed it 10 minutes after switching to the real db (which was the time needed to finally see the GUI)
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Simone Cittadini:
This way you have one listener for every Nation, and there are something like 300 nations, 770 if we consider the more detailed panels popping up when you click the left button, but you tipically want to do detailed stuff only for two or three nations a day, so let's say 350 listeners instantiated in the average life of the app. How much a listener "weights" ?


A few bytes, I'd think. That is, a few bytes for the general object information, and a few bytes for the reference variable.

will this change impact on the speed of the overall system?


I would be very surprised if it did.

In fact it could be argued that it should be *faster*, because you don't have to decode the action command. But that will be at an order of magnitude a user won't be able to notice.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38865
    
  23
As for speed, try it. Try the program you had originally, with this sort of code at the beginning and end of your actionPerformed() method:-
Try the same for your method which has 300 instances (as Ilja Preuss has suggested, 350 objects is not a lot), and try the timing message with the other code in the method //commented out. See which is quickest, and then tell us.

BTW: If you have 300 countries, why not try an enumerated type to store their details rather than an array?
Look in the Java tutorial, find the bit about classes, and look for enumerated types. You would end up with something like this:

To use the data in the enum, you can call
Simone Cittadini
Greenhorn

Joined: Apr 28, 2006
Posts: 13

I would be very surprised if it did.

In fact it could be argued that it should be *faster*, because you don't have to decode the action command. But that will be at an order of magnitude a user won't be able to notice.


I can't say if it's faster or slower, anyway it's true that as a user you don't see the difference.

That's what I've done :

with the JPanel implementing ActionListener,



Time difference in actionPerformed (with all the JFrame listening, leftButton): 100000
Time difference in actionPerformed (with all the JFrame listening, leftButton): 4000
Time difference in actionPerformed (with all the JFrame listening, leftButton): 3000
Time difference in actionPerformed (with all the JFrame listening, leftButton): 3000
etc..

Time difference in actionPerformed (with all the JFrame listening, rightButton): 116000
Time difference in actionPerformed (with all the JFrame listening, rightButton): 5000
Time difference in actionPerformed (with all the JFrame listening, rightButton): 5000
Time difference in actionPerformed (with all the JFrame listening, rightButton): 5000
etc..

right buttons action comes always a little more lately, I suppose because it's "turn" comes after the if (eventCommand == "NATION") comparison (another good reason not to use a single listener when you have a lot of different actions to perform)

But I don't know how to measure the time between "user clicked the button" and "we are in actionPerformed method" (the action is to popup a JDialog chooser, so measuring the time inside the method as no sense, it only measures how much I quickly make my choice)

Anyway it's not really important, I tried it in production and it is fast, thanks to all.

PS: as for the enum stuff, the example I did gave the wrong impression about what the app does, there's no Nation object, there's a single Line object with a String[] attribute containing nation names, taken for a db when the object is first used, then from the gui you choose a
Line - nation -> Termination, but I'll probably explain it better in the design forums when if the app starts to grow
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38865
    
  23
That's all right. I didn't realise you had a database. BTW: I think I made a mistake in the enum: you should set the constructor access to private rather than public.

I don't know whether there is a "User clicked the mouse" timing method. Try adding a MouseListener to your enclosing class and picking up the System.nanoTime() in that. You would have to have a clickTime field. And I notice you are getting faster; obviously the JIT compiler leanrs how the method works and second time round can compile it more quickly.

Must be off now. Bye.

CR
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38865
    
  23
Databases. So why don't you use the database to set your Strings?
I know little about databases, but go onto the JDBC forum if you need help.
Get a list of country names from your database, put them into an array and pass the array to the constructor of a JComboBox. That way you can have one component for the country names, and one box to "go."

CR
Simone Cittadini
Greenhorn

Joined: Apr 28, 2006
Posts: 13
Mh, looking in the combobox and cliking "go" would be too slow (it's a 300 entry combobox, quite user-unfriendly). I can assure you that big buttons with [Egypt] written on them is the way to go, changing the stuff you need to change must be the faster possible.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: the only way to make it worse is to use action commands...