in which thread shoud I use dialogs?

204 views
Skip to first unread message

Marcin Rodzik

unread,
Dec 23, 2009, 5:43:37 AM12/23/09
to
Hello,
An old Swing's rule says that all the UI operations should be carried
out in the event-dispatching thread, and other operations should be
done in other threads. I have written a GUI application which uses
multiple threads. Among them, there is a SwingWorker thread which can
inform user about an error, using a dialog for this purpose. Following
the aforementioned rule, I don't create the dialog in the SwingWorker
thread, but I put a new Runnable object in the Events' Queue.

In such context, I'm facing a great doubt: what if the dialog waited
for user's input? (some dialogs can do this, e.g. file chosers).
Wouldn't they blocked the event-dispatching thread?

regards,
Marcin

RedGrittyBrick

unread,
Dec 23, 2009, 6:20:40 AM12/23/09
to

No. Swing dialogs (JDialog) are event driven, they don't block the event
dispatch thread (EDT) whilst waiting for user input.

--
RGB

Marcin Rodzik

unread,
Dec 23, 2009, 6:36:01 AM12/23/09
to
On Dec 23, 12:20 pm, RedGrittyBrick <RedGrittyBr...@spamweary.invalid>
wrote:

> No. Swing dialogs (JDialog) are event driven, they don't block the event
> dispatch thread (EDT) whilst waiting for user input.

Is it the same for different (eg. colour, file...) choosers?
--
MR

RedGrittyBrick

unread,
Dec 23, 2009, 7:30:11 AM12/23/09
to

If you are using Swing then the general rule is that any code that
updates the GUI must be run on the EDT. You should expect that *all*
Swing classes provided by Sun should work well when this rule is followed.

There are probably exceptions, but I'm sure most Swing programmers never
need be concerned about them.

Another way to think of this is to do everything on the EDT except for
time consuming operations that are not to do with GUI updating - for
example file or database I/O or time consuming mathematical
calculations. I think of the EDT as a foreground user-interface thread
and use SwingWorker to do other stuff in the background.

When constructing you JDialogs and other widgets, make sure that the
constructor only constructs. Do time-consuming initialisation in another
thread.

By following these simple rules you need never worry about blocking the
EDT. My advice is to follow these rules and only spend time worrying
when actual problems arise (which will be when you forgot to apply the
rules).

See
http://mindprod.com/jgloss/swingthreads.html

--
RGB

neun...@yahoo.fr

unread,
Dec 23, 2009, 7:32:31 AM12/23/09
to

Well, if you're concerned about blocking the rest of your
app, then probably that you don't want to display , say, a
modal color chooser...

Modal windows done the way they usually are a retarded
Microsoftism :( If only all the other windows of your
app (the one you can't use anymore while the modal window
is there) became grayed out or something... But, no, modal
windows shall continues to confuse clueless users for ages.

Personally I display transient windows to my users :)

RedGrittyBrick

unread,
Dec 23, 2009, 8:08:26 AM12/23/09
to

neun...@yahoo.fr wrote:
> On Dec 23, 12:36 pm, Marcin Rodzik <marteno_ro...@o2.pl> wrote:
>> On Dec 23, 12:20 pm, RedGrittyBrick <RedGrittyBr...@spamweary.invalid>
>> wrote:
>>
>>> No. Swing dialogs (JDialog) are event driven, they don't block the event
>>> dispatch thread (EDT) whilst waiting for user input.
>> Is it the same for different (eg. colour, file...) choosers?
>
> Well, if you're concerned about blocking the rest of your
> app, then probably that you don't want to display , say, a
> modal color chooser...

Modal dialogs don't block the EDT (which is what the OP said they were
concerned about).

Neither do they block execution in other threads of the application.
Other parts of the application can continue to update other parts of the
GUI.

AFAIK the only thing modal dialogs block is user input to other windows
of the same application.

--
RGB

Alessio Stalla

unread,
Dec 23, 2009, 8:53:49 AM12/23/09
to
On Dec 23, 2:08 pm, RedGrittyBrick <RedGrittyBr...@spamweary.invalid>
wrote:

> neune...@yahoo.fr wrote:
> > On Dec 23, 12:36 pm, Marcin Rodzik <marteno_ro...@o2.pl> wrote:
> >> On Dec 23, 12:20 pm, RedGrittyBrick <RedGrittyBr...@spamweary.invalid>
> >> wrote:
>
> >>> No. Swing dialogs (JDialog) are event driven, they don't block the event
> >>> dispatch thread (EDT) whilst waiting for user input.
> >> Is it the same for different (eg. colour, file...) choosers?
>
> > Well, if you're concerned about blocking the rest of your
> > app, then probably that you don't want to display , say, a
> > modal color chooser...
>
> Modal dialogs don't block the EDT (which is what the OP said they were
> concerned about).
>
> Neither do they block execution in other threads of the application.

Modal dialogs do block the current thread when they are made visible,
so the OP's concern is sensible.

> Other parts of the application can continue to update other parts of the
> GUI.

But not on the same thread that made the dialog visible, until the
dialog is closed, afaik. It seems to me there's a contradiction: every
GUI operation should be done on the EDT, but JDialog.setVisible is
meant to be used on an application thread when the dialog is modal, to
simulate a "function call" that returns when the dialog is closed.

Lew

unread,
Dec 23, 2009, 10:00:03 AM12/23/09
to
Marcin Rodzik wrote:
> An old Swing's rule says that all the UI operations should be carried

Please do not multipost.

--
Lew

Peter Duniho

unread,
Dec 23, 2009, 2:16:32 PM12/23/09
to
Alessio Stalla wrote:
>> [...]

>> Modal dialogs don't block the EDT (which is what the OP said they were
>> concerned about).
>>
>> Neither do they block execution in other threads of the application.
>
> Modal dialogs do block the current thread when they are made visible,
> so the OP's concern is sensible.

They only block the current thread in a completely uninteresting way.
At worst, they block the method showing the dialog from returning. But
if the thread on which they are shown is not the EDT, then presumably
the developer had a good reason for blocking that thread until the
dialog is dismissed.

And if the thread on which they are shown is the EDT (which should most
often be the case), then the only thing they are blocking is the
specific chain of methods that showed it, a chain that itself was
invoked by the message loop in the EDT. The modal dialog creates a
whole new message loop for processing events while the modal dialog is
shown, meaning that the behavior of the EDT isn't being blocked in any
appreciable or important way.

>> Other parts of the application can continue to update other parts of the
>> GUI.
>
> But not on the same thread that made the dialog visible, until the

> dialog is closed, afaik. [...]

You are incorrect. The modal dialog's own message loop takes over for
the previously running EDT message loop while that message loop is being
blocked. Event dispatching continues to happen normally.

Try it. You'll see that showing a modal dialog on the EDT does not
prevent the other EDT messages (other than user input to components
other than the dialog and its contents, which of course is the whole
point of the modal dialog) from being dispatched. All your components
will continue to receive their events, and a method like invokeLater()
will still work fine.

Pete

John B. Matthews

unread,
Dec 24, 2009, 8:11:06 PM12/24/09
to
In article <CNmdnVV2GZYN8a_W...@posted.palinacquisition>,
Peter Duniho <NpOeS...@NnOwSlPiAnMk.com> wrote:

> Try it.

I couldn't resist. Happy Holidays!

package xmas;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;

public class DialogTest extends JPanel implements ActionListener {

private static final int MAX = 64;
private static final String title = "Baubles";
private static final Random rnd = new Random();
private static final AlphaComposite ac =
AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.75f);
private final Timer timer = new Timer(100, this);
private final Queue<Bauble> queue = new LinkedList<Bauble>();

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame f = new JFrame(title);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DialogTest dt = new DialogTest();
f.add(dt);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
JOptionPane.showMessageDialog(dt, title);
}
});
}

public DialogTest() {
this.setPreferredSize(new Dimension(8 * MAX, 8 * MAX));
timer.start();
}

@Override
public void actionPerformed(ActionEvent e) {
if (queue.isEmpty()) {
for (int i = 0; i < MAX; i++) {
queue.add(randomBauble());
}
}
queue.add(randomBauble());
queue.remove();
this.repaint();
}

@Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.black);
g2d.fillRect(0, 0, this.getWidth(), this.getHeight());
g2d.setComposite(ac);
for (Bauble b : queue) {
g2d.setColor(b.c);
g2d.fillOval(b.x, b.y, b.d, b.d);
}
}

private Bauble randomBauble() {
int x = rnd.nextInt(this.getWidth());
int y = rnd.nextInt(this.getHeight());
int r = rnd.nextInt(MAX) + MAX / 2;
Color c = new Color(rnd.nextInt());
return new Bauble(x, y, r, c);
}

private static class Bauble {
private int x, y, d;
private Color c;

public Bauble(int x, int y, int r, Color c) {
this.x = x - r;
this.y = y - r;
this.d = 2 * r;
this.c = c;
}
}
}

--
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

Reply all
Reply to author
Forward
0 new messages