art of writing a responsive swing app

T

Timasmith

Having played around with someones variant of Swingworker I have found
pleasing results with using a background thread for actions initiated
by a table, tree or menu. Clicking on the said item kicks off the
action while letting the gui items respond appropriately. In fact
rather than hardcoding it everywhere I extended an ActionListener to do
just that.

Now when it comes to buttons there is a different story. When you
press a button you want a good solid push but with the background
thread I get a bouncy button that immediately springs back to its
position - too quickly in my estimation. Since the action it is
performing may be quick or slow its difficult to guage the slow ones
only for background processing.

I guess I could introduce an artifical pause for the button but any
other ideas on that.

The other item that is a bit of a pain is setting the hourglass for
menu actions. Since the parent of the menu is not a component I cant
use that to flip the hourglass.

Is there a way to flip the hourglass regardless of the control you are
waving over? Gets a little complex perhaps as you might want to
hourglass one frame but not another.

Finally my other beef is that a modal form on one frame also blocks
another frame, perhaps 1.6 fixes that I will look into it when it is
released.

tia
 
A

Andrew Thompson

Timasmith wrote:
....
Finally my other beef ...

<musing>
Why is it, people say 'beef' when they have a problem?
Why not 'scarab beeetle' or 'chocolate crunchy frog'?

Personally, I prefer chicken, or anything that tastes like
chicken - I wonder if scarab beetles taste like chicken,
but crunchy?
....is that a modal form on one frame also blocks
another frame, perhaps 1.6 fixes that I will look into it when it is
released.

<http://download.java.net/jdk6/docs/api/java/awt/Dialog.ModalExclusionType.html>
? <-- noticed, but have not touched 1.6 yet..

Andrew T.
 
C

Chris Uppal

Andrew said:
Why is it, people say 'beef' when they have a problem?
Why not 'scarab beeetle' or 'chocolate crunchy frog'?

Personally, I prefer chicken, or anything that tastes like
chicken

Grouse, perhaps ?


- I wonder if scarab beetles taste like chicken,
but crunchy?

I find it faintly off-putting to consider the number of thoroughly revolting
foods that chicken tastes like...

-- chris
 
L

Luc The Perverse

Chris Uppal said:
Grouse, perhaps ?


- I wonder if scarab beetles taste like chicken,

I find it faintly off-putting to consider the number of thoroughly
revolting
foods that chicken tastes like...

Are you feeding the troll?
 
S

Steve W. Jackson

"Andrew Thompson said:
Timasmith wrote:
...

<musing>
Why is it, people say 'beef' when they have a problem?
Why not 'scarab beeetle' or 'chocolate crunchy frog'?

Personally, I prefer chicken, or anything that tastes like
chicken - I wonder if scarab beetles taste like chicken,
but crunchy?


<http://download.java.net/jdk6/docs/api/java/awt/Dialog.ModalExclusionType.htm
l>
? <-- noticed, but have not touched 1.6 yet..

Andrew T.

That refers to a way to "exclude" top-level containers from being
impacted by any dialog's modality. I think this is probably better:

<http://download.java.net/jdk6/docs/api/java/awt/Dialog.ModalityType.html
As a Mac user, I know it's long been an issue on my preferred platform.
Apple's GUI has long distinguished between application or document
modality, while Java hasn't offered that capability. This is likely to
provide exactly what Mac users (and doubtless others) have been awaiting.

= Steve =
 
W

Wesley Hall

Timasmith said:
Having played around with someones variant of Swingworker I have found
pleasing results with using a background thread for actions initiated
by a table, tree or menu. Clicking on the said item kicks off the
action while letting the gui items respond appropriately. In fact
rather than hardcoding it everywhere I extended an ActionListener to do
just that.

Just remember that Swing is NOT thread safe so any updates you do to
visual components should be done on the AWT thread. It is OK to use a
thread to go off and fetch data etc, but when the data returns and you
want to display it you must use SwingUtilities.invokeLater to update the
GUI as you will get occasional strange behaviour.
Now when it comes to buttons there is a different story. When you
press a button you want a good solid push but with the background
thread I get a bouncy button that immediately springs back to its
position - too quickly in my estimation. Since the action it is
performing may be quick or slow its difficult to guage the slow ones
only for background processing.

I guess I could introduce an artifical pause for the button but any
other ideas on that.

Not really, it has been a while since I did any swing but presumably the
button stays 'pressed' for as long as the action listener is running. If
you are making that run very short with threading, it is not suprising
that this is happening.

You would be better of forking a thread to go a fetch data from the
server and having the action listener prepare the GUI for when the data
comes back, so if you are hitting a button to display a dialog, build
the dialog in memory on the AWT thread while your worker goes of and
fetches the data. If your GUI builds before your data comes back use the
classes in java.util.concurrent to synchronize the threads, then use
invokeLater to pass the data to the dialog, display the dialog and
return from the action listener.

In doing this, you are finding a balance between single threading (where
the time delay is building gui time + collecting data time), and doing
everything in another thread (which, on the AWT thread is almost 0 time
and makes your button look like it isnt doing anything). What you have
instead is a button that remains depressed for however long the data
fetch takes (without gui building time which is happening concurrently).

You could also consider showing the dialog as soon as it is built and
have the fields populate when the data comes back. This will give your
application a very responsive real (with all clicks responding visually
in a fraction of a second) but you could end up with dialogs that look
empty for a few seconds if the dialog builds much before the data is
returned.

Is there a way to flip the hourglass regardless of the control you are
waving over? Gets a little complex perhaps as you might want to
hourglass one frame but not another.

I seem to remember hourglass cursors being a bit of a pain in the neck.
There was a nice java tip on javaworld that enabled you to push an
action handler on the event queue so that any event that took over x
amount of time would automatically flip the cursor. This was much nicer
than doing it manually for every button click... lets see if I can find
it...


Yup... here it is... its a bit old now (published in 2000) but should do
the job. There could be a more modern solution, but I am a little out of
the loop as everyone seems to want web apps these days...

http://www.javaworld.com/javaworld/javatips/jw-javatip87.html

Have fun.
 
T

Timasmith

Wesley said:
Just remember that Swing is NOT thread safe so any updates you do to
visual components should be done on the AWT thread. It is OK to use a
thread to go off and fetch data etc, but when the data returns and you
want to display it you must use SwingUtilities.invokeLater to update the
GUI as you will get occasional strange behaviour.


Not really, it has been a while since I did any swing but presumably the
button stays 'pressed' for as long as the action listener is running. If
you are making that run very short with threading, it is not suprising
that this is happening.

You would be better of forking a thread to go a fetch data from the
server and having the action listener prepare the GUI for when the data
comes back, so if you are hitting a button to display a dialog, build
the dialog in memory on the AWT thread while your worker goes of and
fetches the data. If your GUI builds before your data comes back use the
classes in java.util.concurrent to synchronize the threads, then use
invokeLater to pass the data to the dialog, display the dialog and
return from the action listener.

In doing this, you are finding a balance between single threading (where
the time delay is building gui time + collecting data time), and doing
everything in another thread (which, on the AWT thread is almost 0 time
and makes your button look like it isnt doing anything). What you have
instead is a button that remains depressed for however long the data
fetch takes (without gui building time which is happening concurrently).

You could also consider showing the dialog as soon as it is built and
have the fields populate when the data comes back. This will give your
application a very responsive real (with all clicks responding visually
in a fraction of a second) but you could end up with dialogs that look
empty for a few seconds if the dialog builds much before the data is
returned.



I seem to remember hourglass cursors being a bit of a pain in the neck.
There was a nice java tip on javaworld that enabled you to push an
action handler on the event queue so that any event that took over x
amount of time would automatically flip the cursor. This was much nicer
than doing it manually for every button click... lets see if I can find
it...


Yup... here it is... its a bit old now (published in 2000) but should do
the job. There could be a more modern solution, but I am a little out of
the loop as everyone seems to want web apps these days...

http://www.javaworld.com/javaworld/javatips/jw-javatip87.html

Have fun.

Thanks, great tips - I can't wait to do them.
 
C

Chris Uppal

Luc said:
Are you feeding the troll?

Do trolls like chicken ? The only references to their diet that I can recall
indicate that they subsist exclusively on diet of billy goat(s).

Unless you include Moomintrolls, of course: they enjoy a much more varied diet,
including (from memory) fish, pancakes, and porridge, plus a tummy-full of pine
needles for the long winter.

;-)

-- chris
 
L

Luc The Perverse

Chris Uppal said:
Do trolls like chicken ? The only references to their diet that I can
recall
indicate that they subsist exclusively on diet of billy goat(s).

Unless you include Moomintrolls, of course: they enjoy a much more varied
diet,
including (from memory) fish, pancakes, and porridge, plus a tummy-full of
pine
needles for the long winter.

They really don't care as long as it tastes like chicken
 
A

Andrew Thompson

Luc said:
They really don't care as long as it tastes like chicken

Not sure - can tell you that 'Olaf the Troll' (who's roar
was 'less than full throated') was preoccupied with..
virgins, ale, and 'plump, succulent babies'.

He was never quite clear on the species of the babies
he sought (nor the virgins, for that matter).

Perhaps he preferred baby chickens.. or maybe just
any baby with a bit of chicken salt (shrugs).

and.. at this stage I will point out that my original comment
was posted above an URL to a possible technical solution
to part of the OP's stated problem.

( Harumph! ;)

Andrew T.
 
F

Fred Kleinschmidt

Wesley Hall said:
Just remember that Swing is NOT thread safe so any updates you do to
visual components should be done on the AWT thread. It is OK to use a
thread to go off and fetch data etc, but when the data returns and you
want to display it you must use SwingUtilities.invokeLater to update the
GUI as you will get occasional strange behaviour.


Not really, it has been a while since I did any swing but presumably the
button stays 'pressed' for as long as the action listener is running. If
you are making that run very short with threading, it is not suprising
that this is happening.

Not necessarily. Usually, when the user presses down on the mouse
button, the PushButton gets a ButtonDown event, and draws itself as
"pushed" (or "Armed").
When the user releases the button (without leaving the PushButton),
the PushButton gets re-drawn as unpushed (unarmed), and it is only
now that the action event is delivered. Note that the order of these
last two things may be dependent on LAF and/or platform.

On the other hand, if the user uses the keyboard mnemonic or shortcut
to press the Button, the action takes place on the KeyPress event
rather than on the KeyRelease event, since many platforms do not
have the concept of KeyRelease.
 
L

Lew

This sure has been a meaty discussion.

I see nothing to grouse about. I for one should have quailed to join this
discussion, but I'm not chicken. Undoubtedly someone will now crow that I'm
off topic, but only because they find my jokes hard to swallow. Now you will
throw things at me and I will have to duck.

Just thought I'd goose this thread before its swan song.

- Lew
 
J

Julian Treadwell

Andrew said:
Timasmith wrote:
...

<musing>
Why is it, people say 'beef' when they have a problem?
Why not 'scarab beeetle' or 'chocolate crunchy frog'?

Personally, I prefer chicken, or anything that tastes like
chicken - I wonder if scarab beetles taste like chicken,
but crunchy?
</musing>

Don't expect you really wanted a serious answer to that question, and if
so that's lucky 'cause nobody knows.

http://www.word-detective.com/052301.html

has a guess.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top