Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

invokeLater() - Any alternatives?

341 views
Skip to first unread message

Jason Teagle

unread,
Nov 15, 2002, 11:53:09 AM11/15/02
to
I know I can use invokeLater() to allow the event dispatching thread to
finish up, and then the code runs; but it requires a Runnable, and it seems
inefficient to create one of those just to allow the UI to update every time
I need to. This is not exactly just a simple repaint problem - I have a menu
item that calls some code which takes a little time, and I was hoping there
may be a way to encourage the menu system to finish (allow the popup menu to
disappear as normal and unhighlight) before I called the lengthy method. In
Windows I could probably use:

void OnMnuDoLengthyOp()
{
menuframe.UpdateWindow(); // All outstanding UI events will be
processed here.
LengthyOp(); // NOW I can call this.
}

(where 'menuframe' is the frame window to which the menu is attached) to
achieve this.

Any chance? It's no biggie to do the Runnable thing, I just would like to
investigate other possibilities.


--
--
Jason Teagle
ja...@teagster.co.uk
-----------------------------------------------------------
A list of programming resources I use:
ML: www.windev.org, www.codecipher.com, www.beginthread.com
MB: www.codeguru.com, www.codeproject.com
NG: comp.lang.java.*
OI: www.php.net
-----------------------------------------------------------


Jason Teagle

unread,
Nov 15, 2002, 12:09:33 PM11/15/02
to

"Jason Teagle" <ja...@teagster.co.uk> wrote in message
news:TD9B9.1265$ic7....@newsfep1-gui.server.ntli.net...

> I know I can use invokeLater() to allow the event dispatching thread to
> finish up, and then the code runs; but it requires a Runnable, and it
seems

Curious... why does this not work:

public void actionPerformed(ActionEvent e)
{
EventQueue.invokeLater(new Thread()
{
public void run()
{
// Do lengthy op...
}
}
);
}

? It compiles and runs and performs the lengthy op... it just doesn't allow
the (Swing) menu to hide before calling the lengthy op!

I also tried outside the handler (from a physical code position point of
view), in the routine called -by- the handler - no change.

Am I missing something?

Paul Brinkley

unread,
Nov 15, 2002, 1:53:29 PM11/15/02
to
On Fri, 15 Nov 2002 17:09:33 -0000, "Jason Teagle"
<ja...@teagster.co.uk> wrote:

>
>"Jason Teagle" <ja...@teagster.co.uk> wrote in message
>news:TD9B9.1265$ic7....@newsfep1-gui.server.ntli.net...
>
>> I know I can use invokeLater() to allow the event dispatching thread to
>> finish up, and then the code runs; but it requires a Runnable, and it
>seems
>
>Curious... why does this not work:
>
>public void actionPerformed(ActionEvent e)
>{
> EventQueue.invokeLater(new Thread()
> {
> public void run()
> {
> // Do lengthy op...
> }
> }
> );
>}
>
>? It compiles and runs and performs the lengthy op... it just doesn't allow
>the (Swing) menu to hide before calling the lengthy op!
>
>I also tried outside the handler (from a physical code position point of
>view), in the routine called -by- the handler - no change.
>
>Am I missing something?

First of all, call SwingUtilities.invokeLater rather than
EventQueue.invokeLater. Admittedly, all SwingUtilities does is call
EventQueue, but the docs always say to use SU, indicating that's the
Right Thing to Do. You never know when a future JDK will implement
SU.iL() to do something different.

Secondly, why create a Thread, when you can create a simple Runnable?
Maybe the effort of creating a Thread object is causing the behavior
you're seeing? (You'd still get the same end effect, and no extra
thread is actually started, since nothing ever calls start() on that
Thread object...)

Paul Brinkley
la...@starpower.net

Jason Teagle

unread,
Nov 15, 2002, 1:59:35 PM11/15/02
to

"Paul Brinkley" <la...@starpower.net> wrote in message
news:5cgatug2aar90m9mc...@4ax.com...

> >Curious... why does this not work:
> >

> First of all, call SwingUtilities.invokeLater rather than
> EventQueue.invokeLater. Admittedly, all SwingUtilities does is call
> EventQueue, but the docs always say to use SU, indicating that's the
> Right Thing to Do. You never know when a future JDK will implement
> SU.iL() to do something different.

OK, noted.

>
> Secondly, why create a Thread, when you can create a simple Runnable?
> Maybe the effort of creating a Thread object is causing the behavior
> you're seeing? (You'd still get the same end effect, and no extra
> thread is actually started, since nothing ever calls start() on that
> Thread object...)

I didn't realise I could create an instance of an interface? I thought I had
to create an instanceof a class that implemented the interface!

But surely even with a Thread it should still wait until AWT had emptied its
queue before doing it?

Jim Sculley

unread,
Nov 15, 2002, 2:31:36 PM11/15/02
to
Jason Teagle wrote:
> "Paul Brinkley" <la...@starpower.net> wrote in message
> news:5cgatug2aar90m9mc...@4ax.com...
>
>
>>>Curious... why does this not work:
>>>
>>
>>First of all, call SwingUtilities.invokeLater rather than
>>EventQueue.invokeLater. Admittedly, all SwingUtilities does is call
>>EventQueue, but the docs always say to use SU, indicating that's the
>>Right Thing to Do. You never know when a future JDK will implement
>>SU.iL() to do something different.
>
>
> OK, noted.
>
>
>>Secondly, why create a Thread, when you can create a simple Runnable?
>>Maybe the effort of creating a Thread object is causing the behavior
>>you're seeing? (You'd still get the same end effect, and no extra
>>thread is actually started, since nothing ever calls start() on that
>>Thread object...)
>
>
> I didn't realise I could create an instance of an interface? I thought I had
> to create an instanceof a class that implemented the interface!

You do. But you can do it on the fly:

SwingUtilities.invokeLater(new Runnable() {
public void run() {
//do stuff here
}
});


Jim S.

Paul Brinkley

unread,
Nov 15, 2002, 3:35:37 PM11/15/02
to
On Fri, 15 Nov 2002 18:59:35 -0000, "Jason Teagle"
<ja...@teagster.co.uk> wrote:

>
>"Paul Brinkley" <la...@starpower.net> wrote in message
>news:5cgatug2aar90m9mc...@4ax.com...
>

>> Secondly, why create a Thread, when you can create a simple Runnable?
>> Maybe the effort of creating a Thread object is causing the behavior
>> you're seeing? (You'd still get the same end effect, and no extra
>> thread is actually started, since nothing ever calls start() on that
>> Thread object...)
>

>But surely even with a Thread it should still wait until AWT had emptied its
>queue before doing it?

It should. That's kinda what I was trying to say; that Thread object
will be treated by the AWT event queue exactly as any other Runnable,
even though it's slightly more weighty than your typical
garden-variety Runnable.

Paul Brinkley
la...@starpower.net

Thomas Kellerer

unread,
Nov 15, 2002, 6:41:05 PM11/15/02
to
Jason Teagle

>
> "Jason Teagle" <ja...@teagster.co.uk> wrote in message
> news:TD9B9.1265$ic7....@newsfep1-gui.server.ntli.net...
>
> > I know I can use invokeLater() to allow the event dispatching thread to
> > finish up, and then the code runs; but it requires a Runnable, and it
> seems
>
> Curious... why does this not work:
>
> public void actionPerformed(ActionEvent e)
> {
> EventQueue.invokeLater(new Thread()
> {
> public void run()
> {
> // Do lengthy op...
> }
> }
> );
> }
>
> ? It compiles and runs and performs the lengthy op... it just doesn't allow
> the (Swing) menu to hide before calling the lengthy op!
>
> I also tried outside the handler (from a physical code position point of
> view), in the routine called -by- the handler - no change.
>
> Am I missing something?

invokeLater() will not execute the code in a separate thread. It will still
run inside the event dispatching thread. If you want to kick off a new thread
to do lengthy work, you need to do that on your own, or you could use
SwingWorker.java which can be downloaded from the Sun site

To create a new Thread and start it right away, you can use a similar
construct:

new Thread(new Runnable()
{
public void run()
{
// call lengthty procedure here
}
}).start();

Cheers
Thomas

Jason Teagle

unread,
Nov 16, 2002, 3:54:06 PM11/16/02
to

"Thomas Kellerer" <spam_...@gmx.net> wrote in message
news:MPG.183fa480b...@news.mnet-online.de...

> invokeLater() will not execute the code in a separate thread. It will
still
> run inside the event dispatching thread. If you want to kick off a new
thread
> to do lengthy work, you need to do that on your own, or you could use
> SwingWorker.java which can be downloaded from the Sun site

Well, I'm not really concerned about whether it will start a separate thread
or not; I'm concerned that it doesn't appear to do what the docs claim:

"If invokeLater is called from the event dispatching thread -- for example,
from a JButton's ActionListener -- the doRun.run() will still be deferred
until all pending events have been processed"

The only thing I can think of that would support what I'm seeing is if,
somehow, the code for hiding a menu item that has been selected is not
issued right away, and so the AWT considers its event queue empty and goes
ahead with the lengthy code, and only later does the event to hide the menu
get issued. But logic would dictate that as part of the overall handler for
the menu (of which the call to actionPerformed() is part), the menu would be
hidden - thus generating AWT events that should be cleared up before the
lengthy code gets run.

In fact, invokeLater() seems to be useless.

I'm not going to lose any sleep over this, but I would like to know if I've
done something wrong, or if there is a problem in the JVM here...

A. Bolmarcich

unread,
Nov 16, 2002, 11:31:41 PM11/16/02
to
In article <LfyB9.4683$C12....@newsfep1-gui.server.ntli.net>, Jason Teagle wrote:
>
> "Thomas Kellerer" <spam_...@gmx.net> wrote in message
> news:MPG.183fa480b...@news.mnet-online.de...
>
>> invokeLater() will not execute the code in a separate thread. It will
> still
>> run inside the event dispatching thread. If you want to kick off a new
> thread
>> to do lengthy work, you need to do that on your own, or you could use
>> SwingWorker.java which can be downloaded from the Sun site
>
> Well, I'm not really concerned about whether it will start a separate thread
> or not; I'm concerned that it doesn't appear to do what the docs claim:
>
> "If invokeLater is called from the event dispatching thread -- for example,
> from a JButton's ActionListener -- the doRun.run() will still be deferred
> until all pending events have been processed"
>
> The only thing I can think of that would support what I'm seeing is if,
> somehow, the code for hiding a menu item that has been selected is not
> issued right away, and so the AWT considers its event queue empty and goes
> ahead with the lengthy code, and only later does the event to hide the menu
> get issued. But logic would dictate that as part of the overall handler for
> the menu (of which the call to actionPerformed() is part), the menu would be
> hidden - thus generating AWT events that should be cleared up before the
> lengthy code gets run.

If the hiding of the menu occurs after the code run by invokeLater, it
indicates that the hiding of the menu is likely being done by an event
handler. That is, a hiding event is added to the event queue after all
the actionListeners for the menu event have returned. If an
actionListener invokes invokeLater, the invokeLater Runnable is processed
before the hiding event (because the invokeLater Runnable is in the event
queue ahead of the hiding event).

Paul Brinkley

unread,
Nov 18, 2002, 11:58:56 AM11/18/02
to

OK, I feel stupid. It didn't occur to me until today what you were
doing wrong in your original code:

public void actionPerformed(ActionEvent e)
{
EventQueue.invokeLater(new Thread()
{
public void run()
{
// Do lengthy op...
}
}
);
}

What you should do is more like this:

public void actionPerformed(ActionEvent e)
{


new Thread() {
public void run()
{
// Do lengthy op...
}

}.start();
}

And yes, invokeLater doesn't make an appearance, so yes, invokeLater
is useless, but only in this case. invokeLater is useful if your
lengthy operation involves invoking any methods on any realized GUI
components. For example:

public void actionPerformed(ActionEvent e)
{


new Thread() {
public void run()
{
// Do lengthy op...

SwingUtilities.invokeLater(new Runnable() {
statusBar.setText ("Done.");
});
}
}.start();
}

invokeLater isn't typically called from the AWT thread. It's
typically called from some other thread. It can also be safely called
from the AWT thread, and occasionally there's reason to.

The AWT event queue ideally is a pipeline of things to process. Each
thing should be doable virtually instantaneously (no massive image
processing, blocking on network I/O, etc.). There are three types of
things that can go in that queue:

1. GUI events (ActionEvent, MouseEvent, etc.)
2. repaint requests
3. Runnables (from invokeAndWait or invokeLater)

All invokeLater does is stick a Runnable in the pipe and move on.
invokeAndWait will stick a Runnable in the pipe and then block the
current thread until the AWT is done with that Runnable. That's why
you can't run invokeAndWait in the AWT thread; it would lock forever.

invokeLater's main purpose is to ensure thread safety. You could call
JLabel.setText("foo") from anywhere, but you really shouldn't, since
it can lead to kooky drawing behavior in the GUI.

Paul Brinkley
la...@starpower.net

Jason Teagle

unread,
Nov 18, 2002, 12:28:03 PM11/18/02
to

"Paul Brinkley" <la...@starpower.net> wrote in message
news:nt5itu4qhl2lmc4a1...@4ax.com...

> OK, I feel stupid. It didn't occur to me until today what you were
> doing wrong in your original code:

No no - you weren't wrong... I didn't -want- to use another thread
specifically.

I wanted to allow all pending AWT events (which I assumed would include
hiding the menu) to be completed before my length op started - I'm quite
happy for the lengthy op to pause the code while it works, it makes sense to
in a way in my project - I just didn't want it to stop the menu hiding
before it started.

> The AWT event queue ideally is a pipeline of things to process. Each
> thing should be doable virtually instantaneously (no massive image
> processing, blocking on network I/O, etc.). There are three types of
> things that can go in that queue:
>
> 1. GUI events (ActionEvent, MouseEvent, etc.)
> 2. repaint requests
> 3. Runnables (from invokeAndWait or invokeLater)

Yes, I understood this pipe (queue) concept (but thankyou). I had assumed
that hiding the menu would already be such an AWT event waiting in the
queue, and thus I could encourage AWT to clear its queue before starting on
my work... but it seems that assumption was wrong, the hiding doesn't occur
until after the action handler returns, which is useless to me...

Paul Brinkley

unread,
Nov 18, 2002, 3:03:04 PM11/18/02
to
On Mon, 18 Nov 2002 17:28:03 -0000, "Jason Teagle"
<ja...@teagster.co.uk> wrote:

>
>"Paul Brinkley" <la...@starpower.net> wrote in message
>news:nt5itu4qhl2lmc4a1...@4ax.com...
>
>> OK, I feel stupid. It didn't occur to me until today what you were
>> doing wrong in your original code:
>
>No no - you weren't wrong... I didn't -want- to use another thread
>specifically.
>
>I wanted to allow all pending AWT events (which I assumed would include
>hiding the menu) to be completed before my length op started - I'm quite
>happy for the lengthy op to pause the code while it works, it makes sense to
>in a way in my project - I just didn't want it to stop the menu hiding
>before it started.
>

>I had assumed
>that hiding the menu would already be such an AWT event waiting in the
>queue, and thus I could encourage AWT to clear its queue before starting on
>my work... but it seems that assumption was wrong, the hiding doesn't occur
>until after the action handler returns, which is useless to me...

The "right thing" for you to do is to run that lengthy op in a
separate thread anyway. In the meantime, I have a theory as to what
may be going on.

When the menu item is clicked (or the user presses Enter or whatever),
an ActionEvent is put on the AWT queue. (There's also 1-3 MouseEvents
or a KeyEvent or two, but they get processed without incident.) That
ActionEvent causes your actionPerformed() to be run in the AWT thread.

Your code, again:

public void actionPerformed(ActionEvent e)
{
EventQueue.invokeLater(new Thread()
{
public void run()

{ /* Do lengthy op... */ }
});
}

So, your code pops another task on the AWT queue, then ends
immediately.

Your actionPerformed() might not be the only actionPerformed(), of
course. There may be other ActionListeners, and as you probably know,
they may be invoked in any order. It's possible that the code that
causes the menu to hide is triggered by an ActionEvent on its
MenuItems, and that it's getting called after your actionPerformed().
Now, so far as you know, this is okay, since all actionPerformed()
methods will be invoked in the AWT thread before it's able to get to
that Runnable (Thread) you put in the queue.

However, it may be that that actionPerformed() hides the menu by
putting yet another repaint event on the queue. If so, that repaint
wouldn't happen until after your lengthy op is finished.

In general, while your lengthy op is running in the AWT thread, the
GUI will cease any and all repaints. This is easy to see by dragging
the GUI window partially offscreen, or hiding bits of it with windows
from other processes.

You said this apparent stasis of the GUI makes sense in a way for your
project. Maybe so. But given all the weirdness that happens as a
natural result of running lengthy tasks in the AWT thread, it might
make more sense for you to run the task in a side thread anyway, and
disable the GUI using a modal, non-dismissable "Please wait..."
dialog.

Paul Brinkley
la...@starpower.net

Babu Kalakrishnan

unread,
Nov 19, 2002, 3:26:08 AM11/19/02
to
On Mon, 18 Nov 2002 17:28:03 -0000, Jason Teagle <ja...@teagster.co.uk> wrote:
>
> "Paul Brinkley" <la...@starpower.net> wrote in message
> news:nt5itu4qhl2lmc4a1...@4ax.com...
>
>> OK, I feel stupid. It didn't occur to me until today what you were
>> doing wrong in your original code:
>
> No no - you weren't wrong... I didn't -want- to use another thread
> specifically.
>
> I wanted to allow all pending AWT events (which I assumed would include
> hiding the menu) to be completed before my length op started - I'm quite
> happy for the lengthy op to pause the code while it works, it makes sense to
> in a way in my project - I just didn't want it to stop the menu hiding
> before it started.

Actually if the "lengthy" task takes anything more than say 2 to 3
seconds, it is always better to use a thread. If you don't want to
handle any user events till the task is complete, it would be better to
use some other technique to block user events (like a modal dialog,
glasspane etc).

The difference between the two is that if you block the EDT itself,
paint operations are also blocked for that duration. So if the user
drags another window across yours during this time, remnants of that
window will show up within your Window, thus giving an appearance to the
user that your app has crashed.

> Yes, I understood this pipe (queue) concept (but thankyou). I had assumed
> that hiding the menu would already be such an AWT event waiting in the
> queue, and thus I could encourage AWT to clear its queue before starting on
> my work... but it seems that assumption was wrong, the hiding doesn't occur
> until after the action handler returns, which is useless to me...

If you must do this absolutely, you could do it in two ways. One is to
use a Timer to start your task after a small delay - another one (more
of a hack) is to jave an invokeLater runnable invoke another
invokeLater runnable that starts the task. This should delay the
processing by 2 EDT cycles which may be sufficient ?

BK

Jason Teagle

unread,
Nov 19, 2002, 4:35:42 AM11/19/02
to

"Babu Kalakrishnan" <ka...@sankya.com> wrote in message
news:slrnatjtd...@ganga.sankya.com...

> Actually if the "lengthy" task takes anything more than say 2 to 3
> seconds, it is always better to use a thread. If you don't want to
> handle any user events till the task is complete, it would be better to
> use some other technique to block user events (like a modal dialog,
> glasspane etc).

OK, you're both right, I should use another thread anyway. It certainly
won't do any harm, and if the user does decide to try and do something
during that time (about 5 seconds maximum), it will be noticeably sluggish /
frozen, so it won't look any better than a sticky menu item.

> If you must do this absolutely, you could do it in two ways. One is to
> use a Timer to start your task after a small delay - another one (more
> of a hack) is to jave an invokeLater runnable invoke another
> invokeLater runnable that starts the task. This should delay the
> processing by 2 EDT cycles which may be sufficient ?

I believe (haven't tried yet) that I can add a ComponentListener to the
container that houses the menu items, and that way I can use the
componentHidden() handler to know when the menu has gone. I will try this
technique.

Does that seem less of a hack?

Jon A. Cruz

unread,
Nov 19, 2002, 9:51:56 AM11/19/02
to
Babu Kalakrishnan wrote:
> Actually if the "lengthy" task takes anything more than say 2 to 3
> seconds, it is always better to use a thread.

Not quite. "Lengthy" is actually anything that might possibly take more
than 1/10th of a second. That's a well known metric in the UI design world.

Paul Brinkley

unread,
Nov 19, 2002, 11:07:56 AM11/19/02
to
On Tue, 19 Nov 2002 06:51:56 -0800, "Jon A. Cruz" <j...@joncruz.org>
wrote:

Really? I had heard 1/5 seconds. Not that I wouldn't be surprised.
This wouldn't be the first time I got conflicting bits of UI
guideline.

Just where -do- all the human factors experts hang out? It sure
doesn't seem to be comp.human-factors. Or Jakob Neilsen's site. Or
WebWord.

Paul Brinkley
la...@starpower.net

Paul Brinkley

unread,
Nov 19, 2002, 11:08:39 AM11/19/02
to
On Tue, 19 Nov 2002 09:35:42 -0000, "Jason Teagle"
<ja...@teagster.co.uk> wrote:
>
>I believe (haven't tried yet) that I can add a ComponentListener to the
>container that houses the menu items, and that way I can use the
>componentHidden() handler to know when the menu has gone. I will try this
>technique.
>
>Does that seem less of a hack?

Just put the long task in a side Thread, and everything else should
take care of itself.

Paul Brinkley
la...@starpower.net

Thomas Hawtin

unread,
Nov 19, 2002, 1:01:12 PM11/19/02
to
Paul Brinkley wrote:
>
> On Tue, 19 Nov 2002 06:51:56 -0800, "Jon A. Cruz" <j...@joncruz.org>
> wrote:
>
> >Not quite. "Lengthy" is actually anything that might possibly take more
> >than 1/10th of a second. That's a well known metric in the UI design world.
>
> Really? I had heard 1/5 seconds. Not that I wouldn't be surprised.
> This wouldn't be the first time I got conflicting bits of UI
> guideline.

The figures I see quoted around the place (perhaps they are just quoting
one another) say 1/10th of a second for a delay to be noticeable, 1/3rd
of a second until something seems to have gone wrong.

Of course that's the whole round-trip time. You still have to deliver
the event beforehand and redraw aftwerwards. GC may also kick in. And if
there is a wait for mouse up instead of mouse down, then you've probably
thrown the 1/10th away before you started.

> Just where -do- all the human factors experts hang out? It sure
> doesn't seem to be comp.human-factors. Or Jakob Neilsen's site. Or
> WebWord.

Probably with like *real* humans. :) Or hung up on something like this:
http://projects.interaction-ivrea.it/endofyear/en/research/faraway.asp

Tackline
--
http://www.tackline.demon.co.uk/
Unemployed Java Developer of Central London.

Chris Smith

unread,
Nov 19, 2002, 7:08:15 PM11/19/02
to
Paul Brinkley wrote ...

> On Tue, 19 Nov 2002 06:51:56 -0800, "Jon A. Cruz" <j...@joncruz.org>
> wrote:
>
> >Babu Kalakrishnan wrote:
> >> Actually if the "lengthy" task takes anything more than say 2 to 3
> >> seconds, it is always better to use a thread.
> >
> >Not quite. "Lengthy" is actually anything that might possibly take more
> >than 1/10th of a second. That's a well known metric in the UI design world.
>
> Really? I had heard 1/5 seconds. Not that I wouldn't be surprised.
> This wouldn't be the first time I got conflicting bits of UI
> guideline.

To throw in another figure, I have seen research papers indicating that
the smallest actual detectable delay for a human being is about 50
milliseconds, or 1/20th of a second. I've also seen papers on
implementing real-time garbage collection for interactive applications
which use that 50 ms number as a guideline.

The "right" number probably depends on what's happening. If the user is
doing something where they expect a big change, then longer delays are
probably fine. The strictest number, 50 ms, is probably not a practical
guide except in situations where the user isn't expecting a major change
(eg, it was used as a guide for randomly initiated GC delays as I
mentioned above). The 100 ms number that Jon gave is perhaps more
practical for "things are happening" sorts of operations, and your 200
ms number perhaps for opening new windows or the like, where there's
clearly something big going on.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation

Mikael Thorsson

unread,
Nov 20, 2002, 6:38:17 AM11/20/02
to
Hi!

This was an interesting discussion - I learned quit a bit! I do have
another question for you though.

What is the best way to "wait" for for a pending I/O receive
operation? Here'e what's happening.

* Right after showing a modal dialog box, the code sends
somehting to a host. This takes almost no time.
* It then needs to "wait" for the response. This may take
anywhere from, say, 0.2 to 3 seconds.

During the wait, I want the GUI to update itself (so that the JFrames
below the modal dialog gets repainted). I also want keyboard events to
be buffered. If this is not possible, I guess discarding them all
would be OK too.

I think that the "right thing to do" here would be to write a thread
that somehow disables input, then does the receive operation, then
enables input again. The problem is that I'm automatically converting
lagacy code into Java... so there is code right after the receive call
that needs to be called once the receive is done. Any ideas??

Thanks,

Micke

Chris Smith <cds...@twu.net> wrote in message news:<MPG.1844805a7...@news.altopia.com>...

Babu Kalakrishnan

unread,
Nov 20, 2002, 9:26:25 AM11/20/02
to
On 20 Nov 2002 03:38:17 -0800, Mikael Thorsson <thorsso...@hotmail.com> wrote:
>
> What is the best way to "wait" for for a pending I/O receive
> operation? Here'e what's happening.
>
> * Right after showing a modal dialog box, the code sends
> somehting to a host. This takes almost no time.
> * It then needs to "wait" for the response. This may take
> anywhere from, say, 0.2 to 3 seconds.
>
> During the wait, I want the GUI to update itself (so that the JFrames
> below the modal dialog gets repainted). I also want keyboard events to
> be buffered. If this is not possible, I guess discarding them all
> would be OK too.
>
> I think that the "right thing to do" here would be to write a thread
> that somehow disables input, then does the receive operation, then
> enables input again. The problem is that I'm automatically converting
> lagacy code into Java... so there is code right after the receive call
> that needs to be called once the receive is done. Any ideas??
>

It is not clear whether the modal dialog that you mention is one that
indicates something like a Status display. That is one of the typical
ways to block events from the underlying frame. (You start the thread
and immediately pop-up a status dialog. When the thread completes, the
dialog is disposed off - and the program flow continues at the statement
immediately after the modalDialog.show()).

Another alternative often used is to block events by using a GlassPane
which can prevent events from going through to the underlying
Frame/Dialog.

BK

Mikael Thorsson

unread,
Nov 21, 2002, 4:14:59 AM11/21/02
to
Sorry, I should have been more clear there...

The dialog is a "normal" dialog - it is run when the user selects a
menu item and he/she is supposed to fill it with data and then OK it.
But actually, the dialog was just an example of a situation where it's
important that the GUI repaints itself quickly (otherwise the dialog
won't hide properly).

But you're absolutely right - what I'm trying to achieve is almost
exactly what a modal dialog box does. In the show() method of
java.awt.Dialog, the code checks whether the calling thread is the
event dispatch thread. If it's not, it just blocks, since the events
will continue pumping anyway. If it is the EDT calling show(), like in
my case, then it must start pumping events _itself_ by calling
waitEvent and dispatchEvent in a loop. I tried yesterday to mimic what
it does in there, but I couldn't get it to work. It even says in the
class comment for Dialog how to do it, but you don't get to call any
of the methods in there directly.

Has anyone managed to do this, or is it impossible in Java?

I also tried your suggestion with actually showing a modal dialog box
while the worker thread is running and it works like a charm - if
nothing else works, I'll do that.

Thanks again,

Micke

Babu Kalakrishnan <ka...@sankya.com> wrote in message news:<slrnatn6s...@ganga.sankya.com>...

Babu Kalakrishnan

unread,
Nov 21, 2002, 7:42:25 AM11/21/02
to
On 21 Nov 2002 01:14:59 -0800, Mikael Thorsson <thorsso...@hotmail.com> wrote:
>
> But you're absolutely right - what I'm trying to achieve is almost
> exactly what a modal dialog box does. In the show() method of
> java.awt.Dialog, the code checks whether the calling thread is the
> event dispatch thread. If it's not, it just blocks, since the events
> will continue pumping anyway. If it is the EDT calling show(), like in
> my case, then it must start pumping events _itself_ by calling
> waitEvent and dispatchEvent in a loop. I tried yesterday to mimic what
> it does in there, but I couldn't get it to work. It even says in the
> class comment for Dialog how to do it, but you don't get to call any
> of the methods in there directly.
>
> Has anyone managed to do this, or is it impossible in Java?
>

If you want event processing to occur normally, all that is necessary
is to do your long task in a separate Thread. It is only when you want
to block InputEvents, but want to process other stuff such as paint /
resize etc that you need to resort to things such as a modal dialog /
glasspane.

If your only requirement is that the rest of your code (after starting
the thread) has to execute only after the thread has completed, you
could move such code to a method that is called at the end of the
run method in the thread (Or into a runnable that is invoked with
invokeLater at the end of the run method if the code has to run in the
EDT).

Manually invoking the EventDispatchThread methods is unlikely to be
succesful because it is a package private class in the java.awt
package.

BK

Mikael Thorsson

unread,
Nov 22, 2002, 11:15:41 AM11/22/02
to
Hello again!


> If your only requirement is that the rest of your code (after starting
> the thread) has to execute only after the thread has completed, you
> could move such code to a method that is called at the end of the
> run method in the thread (Or into a runnable that is invoked with
> invokeLater at the end of the run method if the code has to run in the
> EDT).

I could... except I'm _automatically_ translating legacy scripting
code to Java, so that kind of restructuring is virtually impossible.
But I agree, that would be the most obvious way to do it.

> Manually invoking the EventDispatchThread methods is unlikely to be
> succesful because it is a package private class in the java.awt
> package.

Yepp, looks like it. In the Windows world this is pretty common, so I
was just wondering. Also, even though EventDispatchThread itself is
not avalable, some of the functions that it calls are - in EventQueue
and Component for example. Anyways, I'll stick with the "please wait"
dialog. It's working fine.

Thanks,

Micke

0 new messages