wood burning stoves 2.0*
The moose likes Swing / AWT / SWT and the fly likes Can I distinguish JButtons? 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 distinguish JButtons?" Watch "Can I distinguish JButtons?" New topic
Author

Can I distinguish JButtons?

Maduranga Liyanage
Ranch Hand

Joined: May 25, 2005
Posts: 124
Hello,

I am wondering if there is a way to distinguish between several JButtons. I checked API but JButton doesnt have such a method.

For example;

JButton button1 = new JButton("Button 1");
JButton button2 = new JButton("Button 2");
JButton button3 = new JButton("Button 3");

button1.addActionListener(this);
button2.addActionListener(this);
button3.addActionListener(this);

I want to have only one ActionPerformed method (without defining inner classes), and inside the method I want to differentiate them.

For example, is there anything like;

public void ActionPerformed(ActionEvent ev) {
String = ev.getName();
}

So it will return "Button 1" or "Button 2"..?

Thank you.
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10268
    
    8

Originally posted by Maduranga Liyanage:

I want to have only one ActionPerformed method (without defining inner classes), and inside the method I want to differentiate them.


Sure you can do that.
Extend JButton to have a custom button called say MyButton.
Make MyButton implement ActionListener (since you dont want an inner class for some reason). In the constructor identify and register MyButton as the source.
On the UI, instead of adding JButtons add MyButtons.

In the actionPerformed you can write the identification code and process it accordingly.
getActionCommand() and getText() might be used for identification.

In case you do not want to extend JButton, you can extend AbstractAction and use it. JButton has a constructor which accepts an Action interface.
In this case, on the UI, you will have to add new JButton(new MyCustomAction("Some Text"));
[ July 24, 2008: Message edited by: Maneesh Godbole ]

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

Joined: May 25, 2005
Posts: 124
Thank you Maneesh.

So you are saying:

public class MyButton extends JButton implements ActionListener {

MyButton(String s) {..}

}

But how can I register MyButton with string 's' so that I can retrieve it later?

Thanks.
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10268
    
    8

Originally posted by Maduranga Liyanage:

But how can I register MyButton with string 's' so that I can retrieve it later?


You dont register MyButton with string 's' but you register the button as the event source.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38481
    
  23
Surely you are not using ActionCommands, Maneesh?

All those if-elses are dreadful.

All you have to do is add an output field to the class; set the output in the constructor and then your actionPerformed() method looks like thisMuch better object-orientation

CR
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10268
    
    8

Originally posted by Campbell Ritchie:

All those if-elses are dreadful.


Absolutely.
But the OP wants to
I want to have only one ActionPerformed method (without defining inner classes), and inside the method I want to differentiate them.


I imagine after differentiating them, there will be some further processing based on the parameters. In that case I dont see how the if else loops can be avoided. Or am I missing something here?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38481
    
  23
No, it's not you missing anything; the "in the method I want to distinguish . . ." bit is the actual bad design. I hadn't noticed that bit at first. That explains it; I was thinking it's not like Maneesh to write such clunky code.

Maduranga, you don't "differentiate" instances of a class by their methods; you distinguish them by having different values in their fields.
Maduranga Liyanage
Ranch Hand

Joined: May 25, 2005
Posts: 124
Campbell, Maneesh, thank you very much for the input.

I am new to GUI stuff so please excuse if this is not the correct design.
The thing is I have about 10 buttons and if I am going to have 10 inner classes, I thought that would be messy.

So I thought maybe I can pick up the event and send it to a seperate class (one actionPerformed() method ), and in that class I can do all the processing by something like a case/switch.

Is there a better way to handle a bigger number of buttons efficiently?

Thank you heaps.
[ July 24, 2008: Message edited by: Maduranga Liyanage ]
Brian Cole
Author
Ranch Hand

Joined: Sep 20, 2005
Posts: 862
Originally posted by Maduranga Liyanage:

For example, is there anything like;

public void ActionPerformed(ActionEvent ev) {
String = ev.getName();
}

So it will return "Button 1" or "Button 2"..?


The two general ways to do this are.
1.

or 2.

As you have heard, some consider these if-else approaches to be "dreadful."

Personally, I don't mind the if-else so much as making the actionPerformed() method part of your API. In that sense, using nested classes (anonymous or not) is cleaner. (Of course you could do the if-else thing within a nested class for, from some points of view, a worst-of-both-worlds result.)

The thing is I have about 10 buttons and if I am going to have 10 inner classes, I thought that would be messy.


It makes the output directory messy, in that it now has 11 classes, but
I don't think it makes the code messy.

Is there a better way to handle a bigger number of buttons efficiently?


For efficiency (time efficiency, anyway) it's best to register a separate listener for each button.


bitguru blog
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10268
    
    8

Originally posted by Maduranga Liyanage:

So I thought maybe I can pick up the event and send it to a seperate class (one actionPerformed() method ), and in that class I can do all the processing by something like a case/switch.
[ July 24, 2008: Message edited by: Maduranga Liyanage ]


I dont think you can escape having a checkScenario-respondAccordingly type of code anyhow which might involve switch/if else type code. The optimal thing you can do is abstract as many things as possible (the MyButton or the MyCustomAction approach). I think you were effectively going in the correct direction (one actionPerformed() method)

What exactly are your buttons supposed to do? If you can share it, we can think of something better if possible.
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10268
    
    8

Originally posted by Brian Cole:


For efficiency (time efficiency, anyway) it's best to register a separate listener for each button.


I didnt get this part.
Doesnt the custom button implementing the action listener become a self contained unit? Agreed the implementation of the actionPerformed will contain switc-case/if-else loops, but then from debugging point of view doesnt it make life easier for the developer. Also, on the UI, you need to add instances of MyBytton instead of button.
Maduranga Liyanage
Ranch Hand

Joined: May 25, 2005
Posts: 124
Thanks a million guys.

Actually I don't have a solid implementation in my mind. What I do have in mind is that, I have quite a few things that I usually do very frequently, for example, check apache access/error logs, check if my ssh is running or not, sync files with my iPod...

I want to put these into buttons.. actually nothing difficult.. I'm learning Java as a hobby and I wanted to do something that could be useful to me and at the same time I can better understand Java..

Learned getActionCommand() and getSource() for the first time...

Thank you for all the help guys.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38481
    
  23
You get yourself another class, which might be private to the whole app. A private class could be an inner class. The private class has to implement the ActionListener interface, and being private doesn't contribute to the public API of your application (at least I don't think it does).
Brian Cole
Author
Ranch Hand

Joined: Sep 20, 2005
Posts: 862
Originally posted by Maneesh Godbole:

Originally posted by Brian Cole: For efficiency (time efficiency, anyway) it's best to register a separate listener for each button.

I didnt get this part.
Doesnt the custom button implementing the action listener become a self contained unit? Agreed the implementation of the actionPerformed will contain switc-case/if-else


If you have a separate listener for each button, then there is no need for
the listeners to have switch or if-else. Each listener can just do whatever
needs to be done for the one button on which it has been registered.

Btw, one way to do this is with Actions:

This can be overkill when the listeners are doing something simple, such as
the single println here, but the technique can be handy.

[edit: restructured the code a bit. See also a similar example from my book.]
[ July 24, 2008: Message edited by: Brian Cole ]
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10268
    
    8

After having debugged and fixed some else's (no design, horrible naming conventions like objTextField1,objTextField2..on a UI with 13 input fields, and worst of all no code comments at all) quiet recently, I would rather have the checkCondition-takeAction code in one place.

But then of course it is a matter of personal opinion. No offense intended.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38481
    
  23
It all goes to show how much opinions can differ . . .
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Can I distinguish JButtons?