File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Threads and Synchronization and the fly likes Threads/ActionListeners Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Threads/ActionListeners" Watch "Threads/ActionListeners" New topic
Author

Threads/ActionListeners

Vanessa Astle
Ranch Hand

Joined: May 08, 2007
Posts: 37
Hey! I've created a method that initializes a class. In this class, the constructor creates an popup with a series of text fields to fill out and then has a "Finished" button with an action listener attached. When the finished button is clicked, a number of variables are set from null to the values in the text fields. Then, the method that initialized the class calls getter methods from the class for those variables.

My problem is that the getter methods are being called after the constructor for the class has executed, but not before the action performed method for my action listener has been executed. I'm having issues threading it because of the action listener.

Here's some tidbits of code that are the focus of my problem:



Any suggestions would be greatly appreciated! I hope I explained my problem clearly/thoroughly!

Thanks for your time!
Nicholas Jordan
Ranch Hand

Joined: Sep 17, 2006
Posts: 1282
Where is : ...the method that initialized the class ?
also: In this class, the constructor creates an popup with a series of text fields

Are you talking about the posted code ?
[ June 18, 2007: Message edited by: Nicholas Jordan ]

"The differential equations that describe dynamic interactions of power generators are similar to that of the gravitational interplay among celestial bodies, which is chaotic in nature."
Vanessa Astle
Ranch Hand

Joined: May 08, 2007
Posts: 37
Yes I am. The javadoc I posted in front of the samples of code point out what I was describing in my problem. I only posted the relevant code.

This is a section of the code from "the method that initialized the class":
GraphSetupPopup graphSetupPopup = new GraphSetupPopup(frame,popupGenerator,nodeList,transitionList);
graphWidth = graphSetupPopup.getGraphWidth();
graphHeight = graphSetupPopup.getGraphHeight();
nodeWidth = graphSetupPopup.getNodeWidth();
nodeHeight = graphSetupPopup.getNodeHeight();

And this is part of the constructor that creates the popup. I just took out the popup stuff, but left the text fields that my reference variables are being set from:
public GraphSetupPopup(AutomataFrame frame,PopupGenerator popupGenerator,ArrayList<Node> nodeList,
ArrayList<Transition> transitionList)
{graphWidthField = new JTextField(6);
graphHeightField = new JTextField(6);
nodeWidthField = new JTextField(6);
nodeHeightField = new JTextField(6);

JButton finishedButton = new JButton("Finished");
finishedButton.addActionListener(new FinishedButtonListener());
Nicholas Jordan
Ranch Hand

Joined: Sep 17, 2006
Posts: 1282
A search for AutomataFrame, at Search Results across Sun sites - did not match any documents on the Documentation

I see only ArrayList, which is not synchronized, but that really does not provide any reason to suspect Threading issues that I can spot.

I have tested the waters and no one seems to mind large chunks of code being posted, there is no perceptable reason that the getter methods would be called arbitrarily by GUI components ..... except that a common design flaw is to put the whole thing in GUI classes.

More code may help, as well as knowing your editor or I.D.E. ~ short of seeing that try moving data into data classes and separate that out from drawing classes .... and see if there are any model-view-controller practitioners who may spot something for you.

Without further information, I would think this camp may have something to offer you.

Vanessa Astle
Ranch Hand

Joined: May 08, 2007
Posts: 37
AutomataFrame is a class which I've created. I do follow the MVC pattern in my code, which was the purpose of the getter methods. I'm trying to get my controller to retrieve user input from my GUI, and then hand that information on to my model. This is where I'm coming in to problems.

On the GUI, the user clicks a button. The button is called "Graph Setup". This JDialog box has 4 JTextFields (accompanied by labels), a "Finished" button and a "Cancel" button. A user places the appropriate information in the text fields. If they click "Cancel", none of the information is retained and the JDialog is closed. The user goes back to a default frame. If the user clicks the "Finished" button, the information is to be retained and sent back to the controller which will then send that information to the model classes.

Well, that's how I want the flow of control to work. However, the getter methods that are being called get their information after the Graph Setup Dialog pops up, instead of waiting until the user types information into the textfields. This way, the getter methods are always returning default values (or null, if that be the case).

I'm using Eclipse, and the program thus far is over 20 classes long. That is why I tried to restrict what I posted to be only the relevant code.

Regardless, I am not worried about solving this particular problem. I know that there is more than one way to do things, so I'm sure if I approached the problem from a different angle, I'd be able to work things out. But this is something I deem worth finding out about, regardless. I'm not as thread savvy as I would like to be, so I thought I would inquire about the problem brought up from my particular situation. Is it possible to create a Thread from an object of a class that implements ActionListener instead of Runnable?



The questions I wanted to get through with my extensive explanation was simply:

My IDE, and several reference books, tell me that a class has to implement Runnable in order to create a Thread from an instance of that class.

Thread aThread = new Thread(new AClassThatImplementsRunnable());

So that you can call start() on the thread.

But what if I don't want to call start() on the thread. I want the thread to run on its own when, say, a button is clicked. That way, I wouldnt' have to worry about knowing when to initialize and start the thread. But I could control when it would run after it had been started. Since the thread runs when the button is clicked, it would work from an actionPerformed() method as opposed to a run() method.

Is there any way of doing this?
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

You call start() when the button is clicked. Put the code that you want executed in response to a button click into a Runnable's run() method, then in the actionPerformed() method just create and start a thread. This is a very common idiom. There are other related things you can do, like for instance using SwingUtilities.invokeLater() , which also takes a Runnable as an argument and runs your code on the event thread when it's convenient.


[Jess in Action][AskingGoodQuestions]
Vanessa Astle
Ranch Hand

Joined: May 08, 2007
Posts: 37
I think that this invokeLater() method is exactly what I've been looking for, and I just didn't know it!

"This method should be used when an application thread needs to update the GUI." (from the Java API Method Summary) - has been the issue I've been dealing with all along.

Thanks so much! I'm so excited to edit my code, and hopefully I can get the GUI running like I want it to!
Nicholas Jordan
Ranch Hand

Joined: Sep 17, 2006
Posts: 1282
[Vanessa Astle:] AutomataFrame is a class which I've created. I do follow the MVC pattern in my code, which was the purpose of the getter methods. I'm trying to get my controller to retrieve user input from my GUI, and then hand that information on to my model. This is where I'm coming in to problems.

How does your controller know when to retrieve user input from my GUI ?

[Vanessa Astle:] On the GUI, the user clicks a button. The button is called "Graph Setup". This JDialog box has 4 JTextFields (accompanied by labels), a "Finished" button and a "Cancel" button. A user places the appropriate information in the text fields. If they click "Cancel", none of the information is retained and the JDialog is closed. The user goes back to a default frame. If the user clicks the "Finished" button, the information is to be retained and sent back to the controller which will then send that information to the model classes.

How do the controller classes and the GUI classes communicate ?

{This may seem an obvious issue, and obvious answer. It is not as simple as common sense would suggest. Incorrectly synchronized programs exhibit surprising behaviors.}


[Vanessa Astle:] Well, that's how I want the flow of control to work. However, the getter methods that are being called get their information after the Graph Setup Dialog pops up, instead of waiting until the user types information into the textfields. This way, the getter methods are always returning default values (or null, if that be the case).

There are other ways of doing this, likely the approach EFH suggests will produce more stable code, your approach here is a good place to hang a program. Generally, from the wording here, default values are placed in the constructor ... and that's why I asked what editor/IDE you are using. These techniques tend to get obliterated in full-scale IDE's which are extremely useful for some people, but of limited utility when in time-domain malestroms.

Just remember ROP (Reality Oriented Programming): Do not try to do too much in the constructor. Usually just provide default values and get on with it.

[Vanessa Astle:] I'm using Eclipse, and the program thus far is over 20 classes long. That is why I tried to restrict what I posted to be only the relevant code.
Okay.

[Vanessa Astle:] Is it possible to create a Thread from an object of a class that implements ActionListener instead of Runnable?
I would like to hear Ernest's comments on this.

[Vanessa Astle:]  ...my extensive explanation was simply...
Doesn't look extensive after one has worked on threading issues awhile.

[Vanessa Astle:] But what if I don't want to call start() on the thread. I want the thread to run on its own when, say, a button is clicked. That way, I wouldnt' have to worry about knowing when to initialize and start the thread. But I could control when it would run after it had been started. Since the thread runs when the button is clicked, it would work from an actionPerformed() method as opposed to a run() method.

There are ways of juggling a Thread, from your user code, but the problem is - as I understand it right this moment trying to write my own program - is that a Thread Object (in other words, an instance) cannot be re-run.If you work on this problem, you end up trying to do memory management ~ and shortly the heavyweight World Class Masters Association sends one or two busloads of Captain Doctrinare over two thwart in the nascent moments a classic computer science problem that is best left alone unless you enjoy computer science for it's own sake.

Additionally, the semantics of the Java programming language allow compilers and microprocessors to perform optimizations that can interact with incorrectly synchronized code in ways that can produce behaviors that seem paradoxical. Stick with Ernest's suggestions for now, then let us know how it comes out. actionPerformed() should be better than trying to do your own thread juggling, but there are threads generated by the screen drawing classes and is what I was talking about earler, and as well there are - as best as I can tell - copies made ( I haven't got it all figured out yet ) that have to do with Thread and instance creation and unless you explicitly tell a method to return something, it probably is a devastaion waiting for an important moment.

Synchronize on anything you intend to be modified in any way, and do a great deal of testing before showing your boss.



[Message edit by: Nicholas Jordan ]
Vanessa, I saw this in the tutorials while working on my own project:

This, coupled with default init() vals for your controller classes, would be a good design paradigm, I think.
[ June 23, 2007: Message edited by: Nicholas Jordan ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Threads/ActionListeners