aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes General question about ActionListeners accessing other GUI elements Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "General question about ActionListeners accessing other GUI elements " Watch "General question about ActionListeners accessing other GUI elements " New topic
Author

General question about ActionListeners accessing other GUI elements

Jeff Berman
Greenhorn

Joined: Jan 03, 2008
Posts: 7
Hi there, I'm pretty new to Java and also Swing. I'm writing a simple test program that has a JTextArea and also a JButton. When the button is pressed, some code will process the text that was entered. The way I've implemented it, the button has an anonymous class that implements ActionPerformed(). The problem is that the code inside this anonymous class can't reach the JTextArea. I know that I can declare the JTextArea as an instance variable to expose it to the inner class. Alternatively, I could get rid of the inner class and instead implement ActionPerformed() in my main class. But I want to do it the "right" way. What is the proper way to structure this code so that the ActionPerformed() method can access the text area?

Thank you!
john price
Ranch Hand

Joined: Feb 24, 2011
Posts: 495

Here is what I'm working on. I am using two files, Risk.java and RiskApp.java. If you need a simplified version (bare minimum of what you require), I'll be happy to shave it to what you need. I am new in Java too. This program has taken me close to 50 hours to build, and you might learn something useful.
Risk.java:

RiskApp.java:

Have fun and good luck,
cc11rocks


“Don’t worry if it doesn’t work right. If everything did, you’d be out of a job.” (Mosher's Law of Software Engineering)
“If debugging is the process of removing bugs, then programming must be the process of putting them in.” (Edsger Dijkstra)
David Byron
Rancher

Joined: Jan 20, 2009
Posts: 172

Jeff Berman wrote:Hi there, I'm pretty new to Java and also Swing. I'm writing a simple test program that has a JTextArea and also a JButton. When the button is pressed, some code will process the text that was entered. The way I've implemented it, the button has an anonymous class that implements ActionPerformed(). The problem is that the code inside this anonymous class can't reach the JTextArea. I know that I can declare the JTextArea as an instance variable to expose it to the inner class. Alternatively, I could get rid of the inner class and instead implement ActionPerformed() in my main class. But I want to do it the "right" way. What is the proper way to structure this code so that the ActionPerformed() method can access the text area?
Thank you!

Hi Jeff,

There are several ways to do it, as you rightly note.

Declaring the JTextArea as a private instance variable would be perfectly normal. Implementing actionPerformed (and then doing .addActionListener(this)) on the class itself occurs often in tutorials and illustrations. In practice, however, you'll often find that ActionListeners fall into two categories. On the one hand, you'll have some so simple that using an inline anon class is the obvious way to go. On the other hand, you'll have heavier responsive functionality perhaps shared by two or more widgets. (For example, a response that should answer stimuli from either a button or a menu item or a hotkey....) In that case, a full-fledged Action is more appropriate.

The middle ground in which it makes sense for the class itself to be the listener occurs but is less common. It's less common because implementing actionPerformed in the class restricts you to either (a) responding to only a single stimulus, or (b) using ifs or a switch to figure out which widgets generated the ActionEvent. Yuck. So it's a good fit for simple programs (such as tutorial examples) in which only one interesting event is likely to happen.

When using an Action, you'll still have to decide whether to make it an inner class or to make it a separate class and pass it a reference to the main class that it serves. This is a stylistic preference.


SCJD 6, OCPJP7, Baroque Potion, G+
Jeff Berman
Greenhorn

Joined: Jan 03, 2008
Posts: 7
John, thank you for taking the time to share your code. I see what you're doing, it's similar to what I initially did to get my code working: you declared the Swing widgets as instance variables so that the inner class could access them.

David, I think I understand everything you said except one thing. If I make the ActionListener a separate class, how do I pass it a reference to the main class? Are you saying that the ActionListener's constructor would take one parameter, and you'd do something like this?



And then inside ButtonListener's actionPerformed() method it would access the object that was passed into the constructor? It seems if you used this method you'd still have to declare the relevant GUI widgets as public instance variables so the ActionListener class could see them. Or write getter methods or something.

Thanks!
David Byron
Rancher

Joined: Jan 20, 2009
Posts: 172

Jeff Berman wrote:David, I think I understand everything you said except one thing. If I make the ActionListener a separate class, how do I pass it a reference to the main class? Are you saying that the ActionListener's constructor would take one parameter, and you'd do something like this?And then inside ButtonListener's actionPerformed() method it would access the object that was passed into the constructor?
On Actions, see this and this. The arrangement I had in mind was more along the lines of the following pseudocode:

That said, it would also be reasonable (if you have no need to share functionality among interface elements) simply to create a ButtonListener that implements ActionListener, as you suggest, and pass it a reference to the container where gettable widgets reside.
It seems if you used this method you'd still have to declare the relevant GUI widgets as public instance variables so the ActionListener class could see them. Or write getter methods or something.
Yep. Via accessors rather than public members....
Jeff Berman
Greenhorn

Joined: Jan 03, 2008
Posts: 7
Ohh, "Action". I get it, I hadn't heard of Actions before so I thought you meant ActionListeners. I will read up on Action classes now -- thanks!

Before I saw your reply I had asked a Java guy at work how he structured these things, and he does something very different. For the ActionListener, he creates an anonymous inner class that merely calls a method in his main class. Then that called method has access to all the widgets, and he doesn't need to declare them as public members. I don't know if that is considered good style or not, though.

At any rate, you have given me lots of good info to solve my problem.

Thanks again for all your help!
 
jQuery in Action, 2nd edition
 
subject: General question about ActionListeners accessing other GUI elements