Re: Coping with slow construction of GUI elements
- From: Knute Johnson <nospam@xxxxxxxxxxxxxxxxxxxxxxx>
- Date: Tue, 13 Nov 2007 16:20:14 -0800
bcr666 wrote:
On Nov 13, 11:24 am, RedGrittyBrick <RedGrittyBr...@xxxxxxxxxxxxx>
wrote:
Qs:
* How best to prevent blocking of EDT by slow GUI stuff?!
* How best to set and reset GUI cursor shapes?
In an ActionListener associated with a JMenuItem I had
actionPerformed(actionEvent e) {
switchPanel(new ComplexPanel());
}
However ComplexPanel was taking a couple of seconds to build. During
this time the user is faced with an opened menu with an option selected
and nothing happening onscreen. This is undesirable!
This had me puzzled for a while. Since I'm used to moving non-GUI work
out of the EDT, it seemed like I needed to move some GUI work out of the
EDT! Catch 22. I decided to postpone it instead, so the
actionperformed() could return and the menu could then erase itself
immediately.
actionPerformed(actionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
switchPanel(new ComplexPanel());
}
});
}
* Is this a normal idiom?
Anyway, the result is better but in order to let the user know the app
was busy I wanted to set an hourglass cursor
actionPerformed(actionEvent e) {
//final Cursor oldCursor = frame.getCursor();
//frame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Cursor oldCursor = frame.getCursor();
frame.setCursor(new Cursor(Cursor.WAIT_CURSOR));
switchPanel(new ComplexPanel());
frame.setCursor(oldCursor);
}
});
}
Originally I set the cursor ASAP, but I dislike having set and reset
separated in different methods so I changed it as shown. It seems OK
* Any gotchas I've missed?
One thing I'm not entirely happy with in a multithreaded application is
that some other thread might conceivably change the cursor after I've
stashed oldCursor. In which case restoring it might be inappropriate.
I'm pretty sure that my app wont do this (I'll disable other menu items
so that other threads can't be changing the cursor concurrently)
* Is there a better design for managing cursor state?
How about having a class instance variable for "new ComplexPanel()",
and during the constructor, offload the actual call to "new
ComplexPanel()" to a thread. This way the complex panel is created
behind the scenes while the user is doing something else, and won't
have to wait at all (unless they immediately jump to the menu as soon
as your screen comes up, possible, but I think unlikely).
Moving the GUI creation to another thread won't work. The problem is that the GUI needs to be created on the EDT which you don't want to block.
I actually have a similar problem that I wasn't really able to solve. It is a form basically that has thousands of JTextField components in it. Creating it took a long time so I put that in the constructor for the class, even though I wasn't going to use it for a while. It gets done on the EDT and you never notice the time because it is during program startup. The real problem was populating the form. That still takes too long if it is in fact full of data. Your solution to use invokeLater() and finish the actionPerfomed() method I think is a pretty good solution. I put up a non-modal dialog while gathering data and populating the form. Appearance is 90% of the problem anyway.
--
Knute Johnson
email s/nospam/knute/
.
- References:
- Coping with slow construction of GUI elements
- From: RedGrittyBrick
- Re: Coping with slow construction of GUI elements
- From: bcr666
- Coping with slow construction of GUI elements
- Prev by Date: Re: Coping with slow construction of GUI elements
- Next by Date: Problem with overlapping custom componets
- Previous by thread: Re: Coping with slow construction of GUI elements
- Next by thread: Problem with overlapping custom componets
- Index(es):
Relevant Pages
|
|