I did make some attempts to search for this problem but was not sure exactly what to search for and being after 1AM my eyes wouldn't take reading through the 11+ pages of unrelated search results, so I will just ask the question...

New to Java, want to use one listener for multiple JButtons so I make a class that implements ActionListener.

For testing I want to add a JLabel to a JPanel with the text name I have given the button that triggered the event.

I pass a reference to the JPanel I want to add the JLabel to to the constructor of my new class implementing the ActionListener and assign it to a JPanel variable "j".

In the actionPerformed() method I want to get the name of the JButton which is the source of the event, and put it in a JLabel, and add it to the JPanel, here is my code for the actionPerformed() method:

public void actionPerformed( ActionEvent e ){
        
        JButton t = (JButton)e.getSource();
        //t.setText( String.format( "%s!", t.getText() ) );
        String name = t.getName();
        j.add( new JLabel( name ) );
        
    }

Here is the part that is either strange, or I am just strange and it is normal.
The code the way you see it, with that line that alters the text of the JButton commented out, DOES NOT WORK.
If I uncomment that line and alter the text property of the JButton, then everything works fine except that I have altered the Text of the JButton triggering the event.
I have tried so many ways to write this method and it did not matter what or how, I HAD TO CHANGE A PROPERTY OF THE JBUTTON in order for the JLabel to be added to the the JPanel(j).
I even tried to set the name without changing it, ie.

t.setText( t.getText() ); // and many variations of the same thing

Don't work, I actually have to make a real change of one of JButton's properties for the rest of the code to work.

Again, I am new to Java, perhaps I am going about this the wrong way, maybe I am on target, either way I am stumped trying to understand this behavior, even if changing a property didn't affect the application, doing so just to get it to work would really bother me that I had to hack it to make it work.

Recommended Answers

All 11 Replies

after j.add add j.validate() and j.repaint(), and then try again.

Why are you using getName? The internal name isn't usually a user-meaningful thing.
Try using getText().

Wow, thank you masijade, now it makes sense why it was behaving the way it was, think I shall stick a post-it note on my monitor with those two statements, I am sure I will need them again.. :)

Why are you using getName? The internal name isn't usually a user-meaningful thing.
Try using getText().

The application I am working on is a personal project involving a calendar, the buttons in question are twelve buttons for selecting a month, they run across the top of the display and contain abbreviated month names "JAN", "FEB", etc. in the text property.

Clicking on any one of those twelve should cause the appropriate month to be displayed in the panel below the buttons, so my idea was a single listener for all twelve buttons instead of a separate listener+handler for each( 12x the code? ).

Instead of just automatically trying to use getText() and turn the string "JAN", "FEB", etc. into an integer 1 thru 12, I see that JButton objects have a name property that did not appear to be set unless I set it, so I decided to set the name for each of the month select buttons to "1" thru "12" and plan to use

int selectedMonthNumber = Integer.parseInt( ((JButton)e.getSource()).getName() );

to get the integer value of the month selected based on the button pressed.

Does this seem like bad use of the name property of the JButton objects?

I have never taken a programming class, everything I know is self taught from books and places like this, I program mostly for fun and personal projects, some C for ARM micro-controller, and do some web development for myself and cash on the side, and this is my first desktop app, was going to make this project a web app, but decided to give Java a try, so I am wide open to suggestions and critique as I would much prefer to learn how to do things the correct way.

It's not, necessarily, bad. There is a small (but it is small) chance that there will be name conflict doing so, but with numbers that small I doubt it.

It is a bit of mixing GUI code with business logic which is not what you want to be doing, but I don't know how you are doing the rest of the app, or even what it is doing, so I can't even really judge that.

Does this seem like bad use of the name property of the JButton objects?

Yup, that's not good.
There is a proper way to associate a arbitrary values (eg month number) with a swing component. See these methods in JComponent:
putClientProperty(java.lang.Object, java.lang.Object)
Object getClientProperty(Object key)
eg

buttonJan.putClientProperty("month number", new Integer(1));

int n = (Integer) selectedButton.getClientProperty("month number");

Ah, yes, I forgot all about that. ;-) (Even though it is prominently presented in the beginning remarks of the API docs for JComponent, whoever looks at the API docs JComponent. ;-) )

..., whoever looks at the API docs JComponent

I agree. You look for a method in JButton, but the one you need is totally buried in a huge paragraph of unformatted text for AbstractButton or JComponent. I only discovered ClientProperty because Eclipse prompts you with with a list of ALL the methods that can be called in the current context.
Wouldn't it be useful if you could see all the methods (including inherited ones) for a class in proper JavaDoc format in the same place?

Well, there is at least a link to the methods from the "derived" classes (the "methods inherited from ..." blocks, but it is such a pain to read those blocks, at times. Especially with Swing elements where there seem to be hundreds of inherited methods. If they were at least formatted better, it might not be so onerous. ;-)

Aha :)

I did not think of the name property conflicting with something else, it makes total sense and was shortsightedness on my part, if I was building a web app I would never have used obscure names like "1", "2", "3", etc. =)

Thank you all very much for your input, I had not made it up to JComponent yet but I do frequently consult the API docs for the classes I use, sounds like that client property might be the best thing for me to use.

The names "1" thru "12" were only the shortest path to determining which month button was pressed, it would not be used anywhere else for any other logic.

At the time I had been up very late and didn't want to write a function that turned the string "JAN" into int 1, etc., so I was looking for a shortcut.

From the amount of example code I find on the internet it seems that extending component classes is a very popular method, I suppose I could have made my own button component class extending JButton and added an INT property to do just what I wanted, but some of my reading has suggested that you can get into trouble extending classes if your derived class has methods that depend on the implementation of it's super, where a change in the super's implementation in the future may break your derived class method.

I probably would not get into trouble with a simple added property but I am really trying to avoid using "extends", it seems like it could easily be abused.

Have I got the right idea there, or is that the intended programming methods in Java, and the real trap is writing methods that rely on the super's implementation never changing?

Yes, extending classes and depending on their implementation (as opposed to their public interface) is dangerous. The whole reason for ClientProperty is to avoid extending JComponents just to add another data member or two. You absolutely should use ClientProperty to associate additional data with a JButton.

Cool, I was really curious about that since it seemed to me that extending EVERYTHING into custom classes was more like a crutch but it also seems like 99% of Java code examples I find through Google searches extend everything, so much so that I was starting to think there was a law against using JFrame, JPanel, JButton, etc. directly.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.