AppletTalk.com Forum Index AppletTalk.com
Java discussions newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Swing Components Freeze During Other Actions Even With Threa

 
Post new topic   Reply to topic    AppletTalk.com Forum Index -> Java Help
View previous topic :: View next topic  
Author Message
Hal Vaughan
Guest





PostPosted: Thu Jan 19, 2006 2:05 am    Post subject: Swing Components Freeze During Other Actions Even With Threa Reply with quote



I'm having a variation on an old problem: After "Okay" is clicked in a
window, I need to run an external program and read the output. I have my
code to do this in a thread, which should help, right? No. It doesn't.

Here's the problem: I'm waiting for the output of the external process
before I can open a message window and say everything is okay or it won't
work. That means I have this:

emitNotification("Verifying");
verifyProgram.start();
while (!verifyProgram.isDone()) {
try {
Thread.sleep(10);
} catch (Exception e) {
System.err.println("Error: Interrupted while sleeping!");
}
}
if (verifyProgram.isValidated()) {
emitError("Invalid choice");
return false;
}
emitNotification("Verification worked");

Since I have to wait in the main thread until verifyProgram is done, I have
the same problem as if I were not using a thread: While the main thread is
sleeping, it does not update the Swing GUI.

So how do you wait on a thread and still allow the current thread to update
the GUI?

Thanks!

Hal
Back to top
Roedy Green
Guest





PostPosted: Thu Jan 19, 2006 3:14 am    Post subject: Re: Swing Components Freeze During Other Actions Even With T Reply with quote



On Wed, 18 Jan 2006 21:05:56 -0500, Hal Vaughan
<hal (AT) thresholddigital (DOT) com> wrote, quoted or indirectly quoted someone
who said :

Quote:
So how do you wait on a thread and still allow the current thread to update
the GUI?


you do the waiting for the exec to finish on a sub thread, not the
main thread.
--
Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Back to top
Hal Vaughan
Guest





PostPosted: Thu Jan 19, 2006 4:51 am    Post subject: Re: Swing Components Freeze During Other Actions Even With T Reply with quote



Roedy Green wrote:

Quote:
On Wed, 18 Jan 2006 21:05:56 -0500, Hal Vaughan
[email]hal (AT) thresholddigital (DOT) com[/email]> wrote, quoted or indirectly quoted someone
who said :

So how do you wait on a thread and still allow the current thread to
update the GUI?


you do the waiting for the exec to finish on a sub thread, not the
main thread.

I can see that, but I need the results of the sub thread. How do I let
Swing update (and possibly take other events) and still know when to get
the results without some kind of loop-sleep-check results-endloop
structure?

Hal

Back to top
Tony Morris
Guest





PostPosted: Thu Jan 19, 2006 5:12 am    Post subject: Re: Swing Components Freeze During Other Actions Even With T Reply with quote

"Hal Vaughan" <hal (AT) thresholddigital (DOT) com> wrote

Quote:
Roedy Green wrote:

On Wed, 18 Jan 2006 21:05:56 -0500, Hal Vaughan
[email]hal (AT) thresholddigital (DOT) com[/email]> wrote, quoted or indirectly quoted someone
who said :

So how do you wait on a thread and still allow the current thread to
update the GUI?


you do the waiting for the exec to finish on a sub thread, not the
main thread.

I can see that, but I need the results of the sub thread. How do I let
Swing update (and possibly take other events) and still know when to get
the results without some kind of loop-sleep-check results-endloop
structure?

Hal

"Register" a callback.
Pass something that is called back on when the results are available.

--
Tony Morris
http://tmorris.net/

Java Questions and Answers
http://jqa.tmorris.net/




Back to top
Hal Vaughan
Guest





PostPosted: Thu Jan 19, 2006 7:13 am    Post subject: Re: Swing Components Freeze During Other Actions Even With T Reply with quote

Tony Morris wrote:

Quote:
"Hal Vaughan" <hal (AT) thresholddigital (DOT) com> wrote in message
news:SfKdnf6tDIsvh1LeRVn-rA (AT) comcast (DOT) com...
Roedy Green wrote:

On Wed, 18 Jan 2006 21:05:56 -0500, Hal Vaughan
[email]hal (AT) thresholddigital (DOT) com[/email]> wrote, quoted or indirectly quoted someone
who said :

So how do you wait on a thread and still allow the current thread to
update the GUI?


you do the waiting for the exec to finish on a sub thread, not the
main thread.

I can see that, but I need the results of the sub thread. How do I let
Swing update (and possibly take other events) and still know when to get
the results without some kind of loop-sleep-check results-endloop
structure?

Hal

"Register" a callback.
Pass something that is called back on when the results are available.

You mean pass a method to it? Then don't I still have to wait on that
value? If not, what do I do? Just sleep and the callback will wake the
thread?

Hal

Back to top
Roedy Green
Guest





PostPosted: Thu Jan 19, 2006 7:31 am    Post subject: Re: Swing Components Freeze During Other Actions Even With T Reply with quote

On Wed, 18 Jan 2006 23:51:02 -0500, Hal Vaughan
<hal (AT) thresholddigital (DOT) com> wrote, quoted or indirectly quoted someone
who said :

Quote:
I can see that, but I need the results of the sub thread. How do I let
Swing update (and possibly take other events) and still know when to get
the results without some kind of loop-sleep-check results-endloop
structure?

The subthread gets the results and schedules whatever has to be done
with them. You might use Listeners for notification.

The main thread finds out simply by the presence of new data it
stumbles on in the course of its ordinary activities.

--
Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Back to top
Roedy Green
Guest





PostPosted: Thu Jan 19, 2006 7:32 am    Post subject: Re: Swing Components Freeze During Other Actions Even With T Reply with quote

On Thu, 19 Jan 2006 02:13:21 -0500, Hal Vaughan
<hal (AT) thresholddigital (DOT) com> wrote, quoted or indirectly quoted someone
who said :

Quote:
You mean pass a method to it? Then don't I still have to wait on that
value? If not, what do I do? Just sleep and the callback will wake the
thread?

Why bother with two threads then? Just have the subthread do whatever
it is needs be done when the information has arrived.
--
Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Back to top
Hal Vaughan
Guest





PostPosted: Thu Jan 19, 2006 8:08 am    Post subject: Re: Swing Components Freeze During Other Actions Even With T Reply with quote

Roedy Green wrote:

Quote:
On Thu, 19 Jan 2006 02:13:21 -0500, Hal Vaughan
[email]hal (AT) thresholddigital (DOT) com[/email]> wrote, quoted or indirectly quoted someone
who said :

You mean pass a method to it? Then don't I still have to wait on that
value? If not, what do I do? Just sleep and the callback will wake the
thread?

Why bother with two threads then? Just have the subthread do whatever
it is needs be done when the information has arrived.

The subthread is supplying the information.

I'm sure there are ways to do this, and maybe someone has pointed it out. I
just don't get it -- seriously. I'm trying to figure out how to do this.

This is on one in a series of panels for setting up a program. The user has
selected a path where the program should be, then clicks "Next". A message
dialogue opens, with a "We're verifying the location" message. Then I run
the program (if it is where it is supposed to be) with a "--version"
argument. I read the output and scan it for the version number. If the
version is acceptable, a new message window opens, saying it will work. If
it is an unacceptable version, a window opens saying it won't work.

On the first dialogue ("We're verifying..."), once I click "Okay", the
message dialogue window goes blank and the entire window goes blank with
it. Nothing happens while the program is being run, printing out the
version, and I'm scanning for the version number. Once that is done, Swing
catches up.

So basically, I need to let the user click "Okay", then, ideally, Swing
would update the window, THEN check the version. But that doesn't happen,
which I know is normal. So I dispatch a thread to check the version
number, but I can't do a thing on the main thread until I know if the
version is acceptable.

So, no matter what I do, I have to wait for the external program to run
before saying it works or won't work. The hard part is I can't get Swing
to update while waiting for the 2nd thread to run the program. I'm still
reading up on what some other responses have said. I know one time I
experimented with invokeLater() and invokeAndWait(), but I've never gotten
them to work properly either.

I have yet to see how I can get Swing to update, then wait for information
in its own thread or a subthread.

Since I am sure this is not the kind of thing the Java team would make this
difficult, I'm sure I'm missing something basic here.

Hal

Back to top
Thomas Weidenfeller
Guest





PostPosted: Thu Jan 19, 2006 8:22 am    Post subject: Re: Swing Components Freeze During Other Actions Even With T Reply with quote

Hal Vaughan wrote:
Quote:
Since I am sure this is not the kind of thing the Java team would make this
difficult, I'm sure I'm missing something basic here.

It's not difficult. It has been a done a thousand times. Time consuming
tasks have to be done on a separate thread. Period. Separate threads
which want to update the GUI need to use invokeLater() (invokeAndWait()
often doesn't make sense). That's it.

Five to ten lines of code. Explained in each and every AWT and Swing
tutorial, book, FAQ, reference, overview, etc.

/Thomas
--
The comp.lang.java.gui FAQ:
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/

Back to top
Roedy Green
Guest





PostPosted: Thu Jan 19, 2006 9:33 am    Post subject: Re: Swing Components Freeze During Other Actions Even With T Reply with quote

On Thu, 19 Jan 2006 03:08:23 -0500, Hal Vaughan
<hal (AT) thresholddigital (DOT) com> wrote, quoted or indirectly quoted someone
who said :

Quote:
The subthread is supplying the information.

I am don't follow what you are saying but I think the problem may come
from thinking that a thread belongs to a set of classes. Threads can
wander all over the place executing code from anywhere. That is not
particularly naughty. So the thread that notices data has arrived can
be the one to process it, using methods, objects and classes you might
normally think of as "belonging" to the main thread.
--
Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.

Back to top
Hal Vaughan
Guest





PostPosted: Thu Jan 19, 2006 8:38 pm    Post subject: Re: Swing Components Freeze During Other Actions Even With T Reply with quote

Thomas Weidenfeller wrote:

Quote:
Hal Vaughan wrote:
Since I am sure this is not the kind of thing the Java team would make
this difficult, I'm sure I'm missing something basic here.

It's not difficult. It has been a done a thousand times. Time consuming
tasks have to be done on a separate thread. Period. Separate threads
which want to update the GUI need to use invokeLater() (invokeAndWait()
often doesn't make sense). That's it.

Five to ten lines of code. Explained in each and every AWT and Swing
tutorial, book, FAQ, reference, overview, etc.


That's oversimplifying it.

I've checked a number or sources. I've found stuff on how to invoke a
thread, use invokeLater() and invokeWait(), but that doesn't answer the
whole question.

I have a series of events (if everything checks out):

A) "Next" is clicked to move to another panel
B) A "Verifying" message appears, asking the user to click "Okay"
C) An external program is run to get the version info (and checks it)
D) A few flags are set and a "Version okay" message window opens
E) The user clicks "Okay" on the message window and the method returns to
the caller, which displays the next panel.

I have no problem with A & B. To get C to work, I can use a thread, or
invokeLater(), but here is where the problem occurs, and this is what I
either don't understand, or have not fond an answer to: the main thread
NEEDS the results generated in the 2nd thread.

So what do I do in the main thread, that allows the display to be updated,
but still waits until the 2nd thread is done? (Or, when the 2nd thread is
done, can get the data from it?) I've tried a loop to sleep and check if
the 2nd thread is done, but even Thread.sleep, but even sleep keeps the
panel from updating itself.

So how can the main thread wait on the 2nd thread AND update the display
while waiting?

Hal

Back to top
Steve Horsley
Guest





PostPosted: Fri Jan 20, 2006 5:50 pm    Post subject: Re: Swing Components Freeze During Other Actions Even With T Reply with quote


Quote:
That's oversimplifying it.

I've checked a number or sources. I've found stuff on how to invoke a
thread, use invokeLater() and invokeWait(), but that doesn't answer the
whole question.

I have a series of events (if everything checks out):

A) "Next" is clicked to move to another panel
B) A "Verifying" message appears, asking the user to click "Okay"
C) An external program is run to get the version info (and checks it)
D) A few flags are set and a "Version okay" message window opens
E) The user clicks "Okay" on the message window and the method returns to
the caller, which displays the next panel.

I have no problem with A & B. To get C to work, I can use a thread, or

Since C takes significant time, you MUST use a thread, or the GUI
goes to sleep.

Quote:
invokeLater(), but here is where the problem occurs, and this is what I

No no NO. invokeLater asks the GUI event thread to do it. If you
do that, the GUI will go to sleep while the event thread is busy
doing C.

Quote:
either don't understand, or have not fond an answer to: the main thread
NEEDS the results generated in the 2nd thread.


Actually, the main thread (I presume you mean the GUI thread)
does NOT need the data. The GUI class needs the data. This is
important. Understand the difference.

The GUI class needs the data, and a Version-OK dialog needs
displaying. The easiest thing would be to get the sub-thread that
just did C to set the flags in the GUI class and then create the
dialog, but this is not thread safe - it is just possible that
the GUI event thread might be asked to do something to the GUI
state while the sub-thread is busy changing things - crash.

So the sub-thread bundles all the required data into a Runnable
who's run() method will update the GUI class and create the
Version-OK dialog, and use invokeLater() to pass the Runnable to
the event thread. The sub-thread can now die happy. The event
thread will in the fullness of time find the Runnable waiting to
be run. In this way, only the event thread actually ever updates
the GUI class state.

Note that in this case we DID need the event thread to have the
data, but only because we wanted to avoid concurrent modification
issues. If we implemented some thread-safe locking, we could have
don the update to the GUI state from the sub-thread. I am being
pedantic about this because it is important to know where data
lives. You mentioned setting a couple of flags. The flags are in
the GUI class, NOT in any particular thread. Any thread could in
principle set or read those flags by visiting the Gui class. I
really think it helps to see your application as a bunch of
static objects with values written on them and a bunch of worker
threads running round visiting those objects reading and setting
values. Like engineers visiting benches in a factory.

Quote:
So what do I do in the main thread, that allows the display to be updated,
but still waits until the 2nd thread is done? (Or, when the 2nd thread is
done, can get the data from it?) I've tried a loop to sleep and check if
the 2nd thread is done, but even Thread.sleep, but even sleep keeps the
panel from updating itself.

Before launching the thread, set a busy flag. Have the callback
clear the busy flag after setting the results.

When the user clicks the Go button, check the busy flag, and do
nothing if you're already busy.

Quote:

So how can the main thread wait on the 2nd thread AND update the display
while waiting?


The GUI thread doesn't wait for the sub-thread to finish. It
waits for an event on the event queue. That could be a repaint
request, or could be the arrival of and invokeLater() object that
carries the answer the user is waiting for. The main thing here
is that you have turned the arrival of the answer into an event.

Your GUI is event driven, it does not do polling.


HTH
Steve

Back to top
Hal Vaughan
Guest





PostPosted: Fri Jan 20, 2006 10:45 pm    Post subject: Re: Swing Components Freeze During Other Actions Even With T Reply with quote

Steve Horsley wrote:

Quote:

That's oversimplifying it.

I've checked a number or sources. I've found stuff on how to invoke a
thread, use invokeLater() and invokeWait(), but that doesn't answer the
whole question.

I have a series of events (if everything checks out):

A) "Next" is clicked to move to another panel
B) A "Verifying" message appears, asking the user to click "Okay"
C) An external program is run to get the version info (and checks it)
D) A few flags are set and a "Version okay" message window opens
E) The user clicks "Okay" on the message window and the method returns to
the caller, which displays the next panel.

I have no problem with A & B. To get C to work, I can use a thread, or

Since C takes significant time, you MUST use a thread, or the GUI
goes to sleep.

Okay, I know that, so I follow so far.

Quote:
invokeLater(), but here is where the problem occurs, and this is what I

No no NO. invokeLater asks the GUI event thread to do it. If you
do that, the GUI will go to sleep while the event thread is busy
doing C.

I didn't realize that when I posted. I found out this morning what you just
pointed out. That's frustrating, because I've tried to get help on this
before, and the info was NOT complete, and it was not spelled out in my
books I use. Now I see that. It's a major point, so thanks!

Quote:
either don't understand, or have not fond an answer to: the main thread
NEEDS the results generated in the 2nd thread.


Actually, the main thread (I presume you mean the GUI thread)
does NOT need the data. The GUI class needs the data. This is
important. Understand the difference.

I see what you mean. Thanks for putting it clearly. You're right, and I
had not seen that before.

Quote:
The GUI class needs the data, and a Version-OK dialog needs
displaying. The easiest thing would be to get the sub-thread that
just did C to set the flags in the GUI class and then create the
dialog, but this is not thread safe - it is just possible that
the GUI event thread might be asked to do something to the GUI
state while the sub-thread is busy changing things - crash.

So the sub-thread bundles all the required data into a Runnable
who's run() method will update the GUI class and create the
Version-OK dialog, and use invokeLater() to pass the Runnable to
the event thread. The sub-thread can now die happy. The event
thread will in the fullness of time find the Runnable waiting to
be run. In this way, only the event thread actually ever updates
the GUI class state.

Let me restate it, in my words, to make sure I understand it:
I can go on and update the GUI with settings and commands in the main thread
and take the runnable object, which will need all the data for all the
non-GUI stuff it does, and run it (Object.start()). Then, to keep it
thread safe, when the sub-thread is done, and needs to put up a message
saying, "Everything's working!", I do that with an invokeLater() -- within
the sub-thread and what it invokesLater is putting up the message window.
By now, unless the user has pressed other buttons, the main thread is idle.

Quote:
Note that in this case we DID need the event thread to have the
data, but only because we wanted to avoid concurrent modification
issues. If we implemented some thread-safe locking, we could have
don the update to the GUI state from the sub-thread. I am being
pedantic about this because it is important to know where data
lives. You mentioned setting a couple of flags. The flags are in
the GUI class, NOT in any particular thread. Any thread could in
principle set or read those flags by visiting the Gui class. I
really think it helps to see your application as a bunch of
static objects with values written on them and a bunch of worker
threads running round visiting those objects reading and setting
values. Like engineers visiting benches in a factory.

This helps a lot! It is much clearer than it was. I have a class that does
a recursive directory search and I'm combining that with the file/version
verifier and setting it up so it can be all together, in one Runnable
object. I'll just set all the variables ahead of time and run it as a
thread when it's time. It will use invokeLater() to pop up the message
window when it's done.

Quote:
So what do I do in the main thread, that allows the display to be
updated,
but still waits until the 2nd thread is done? (Or, when the 2nd thread
is
done, can get the data from it?) I've tried a loop to sleep and check if
the 2nd thread is done, but even Thread.sleep, but even sleep keeps the
panel from updating itself.

Before launching the thread, set a busy flag. Have the callback
clear the busy flag after setting the results.

When the user clicks the Go button, check the busy flag, and do
nothing if you're already busy.

That's a good idea. Thanks, again.

Quote:

So how can the main thread wait on the 2nd thread AND update the display
while waiting?


The GUI thread doesn't wait for the sub-thread to finish. It
waits for an event on the event queue. That could be a repaint
request, or could be the arrival of and invokeLater() object that
carries the answer the user is waiting for. The main thing here
is that you have turned the arrival of the answer into an event.

That's a major change in how I was thinking of how to do it. I'm self
taught, and had been programming for a few years before I started using a
GUI as a front end. Most of the coding I'm doing is in Perl, without any
GUI, so I don't always catch all the nuances of how the flow is dispatched
events as opposed to a linear progression of events in the order I pick.

Quote:
Your GUI is event driven, it does not do polling.


HTH
Steve

I don't want to gush, but I'll add that I used to be a teacher (especially
working with students with Learning Disabilities), and had done a lot of
work in focusing on how people learn and how I can present information to
them. I've been stuck on this issue, on and off, for a couple years. I've
always found a work around in how I set up the GUI. I have had various
people help me, but I do want to say that, as a former teacher, I wanted to
compliment you on your ability to put this clearly and with examples that
make it easy to understand what is going on.

I really do appreciate your patience and completeness in your answer.

I'll post the final result of what I'm doing.

Hal

Back to top
Hal Vaughan
Guest





PostPosted: Sat Jan 21, 2006 2:59 am    Post subject: Re: Swing Components Freeze During Other Actions Even With T Reply with quote

Steve Horsley wrote:
....
Quote:

The GUI thread doesn't wait for the sub-thread to finish. It
waits for an event on the event queue. That could be a repaint
request, or could be the arrival of and invokeLater() object that
carries the answer the user is waiting for. The main thing here
is that you have turned the arrival of the answer into an event.

I found a spot here I didn't understand (all the rest was a HUGE help, as
I've already posted in a reply).

I am not sure what I invokeLater() or how I can call back the original class
to alter data in it. I've just posted a new thread on this, since it is a
different problem, but any help in how to call back the calling class (to
update data) or any way to add a listener in the first class, attach it to
this class, and have this class force or trigger an event to call that
listener would be a big help!

Thanks!

Hal

Back to top
Display posts from previous:   
Post new topic   Reply to topic    AppletTalk.com Forum Index -> Java Help All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.