Skip to main content

awt.EventDispatchThread & modal dialogs.

4 replies [Last post]
zander
Offline
Joined: 2003-06-13
Points: 0

From the documentation as well as from the sources I gather that locking a EventDispatchThread is done per AppContext.
Problem is that creating a new AppContext (and thus a new EventDispatchThread) still locks my all Frames.

Anyone with some more knowledge on this stuff can tell me if I am doing something wrong? Or if this is a bug in AWT?

Consider the following application.
It starts two threads in two ThreadGroups, each ThreadGroup has a AppContext associated with it.
Some print code I removed from this example indeed prints a thread hierarchy and 2 AWT-EventQueue threads.
The question is simple; when I press one of the buttons on those two Frames, why is the other frame unaccessable. (note that the 2 frames are positioned on top of each other)

<br />
import java.awt.*;<br />
import java.awt.event.*;</p>
<p>public class TstAppContext {<br />
    public static void main (String [] args) {<br />
        class Run implements Runnable {<br />
            Frame f;<br />
            public void run() {<br />
                sun.awt.SunToolkit.createNewAppContext();<br />
                f = new Frame();<br />
                Button button = new Button("Click me");<br />
                button.addActionListener( new ActionListener() {<br />
                    public void actionPerformed(ActionEvent e) {<br />
                        buttonPressed();<br />
                    }<br />
                });<br />
                f.add(button);<br />
                f.pack();<br />
                f.show();<br />
            }</p>
<p>            public void buttonPressed() {<br />
                System.out.println("buttonPressed in: "+ sun.awt.AppContext.getAppContext());<br />
                System.out.println("      eventQueue: "+ sun.awt.AppContext.getAppContext().get(sun.awt.AppContext.EVENT_QUEUE_KEY));<br />
                final Dialog diag = new Dialog(f, true);<br />
                Button button = new Button("Click 2 close");<br />
                button.addActionListener( new ActionListener() {<br />
                    public void actionPerformed(ActionEvent e) {<br />
                        diag.dispose();<br />
                    }<br />
                });<br />
                diag.add(button);<br />
                diag.show();<br />
            }<br />
        };</p>
<p>        ThreadGroup group1 = new ThreadGroup("group1");<br />
        Thread t1 = new Thread(group1, new Run());<br />
        ThreadGroup group2 = new ThreadGroup("group2");<br />
        Thread t2 = new Thread(group2, new Run());</p>
<p>        t1.start();<br />
        t2.start();<br />
    }<br />
}<br />

Any pointers are appreciated!
ps. I noticed bug 4080029, but this is different since that talks about frames in the same context being unaccessable; this is about frames in different contexts.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
denis_m
Offline
Joined: 2003-08-12
Points: 0

I think this is both a bug in AWT and the limitation of the platform.

On Windows, it might be possible to implement appcontext-wide modality, and therefore on Windows the observed behavior is the bug in AWT.

On Solaris or Linux, the behavior heavily depends on desktop system used. On some systems it just works, for example, on RH9/GNOME, on other it might not.

There is no way right now to implement this API to work consistently (as specified) on all platforms.

zander
Offline
Joined: 2003-06-13
Points: 0

> I think this is both a bug in AWT and the limitation
> of the platform.
>
> On Windows, it might be possible to implement
> appcontext-wide modality, and therefore on Windows
> the observed behavior is the bug in AWT.

This is not about missing modality appcontext wide.
This is about the fact that modality is not only app-context wide; its JVM wide.

> On Solaris or Linux, the behavior heavily depends on
> desktop system used. On some systems it just works,
> for example, on RH9/GNOME, on other it might not.
I'd like to hear your reasoning behind such a statement; since modality in AWT is implemented above the native widgetset.
In practise it is nothing more then ignoring the events for all windows except the dialog and children of the dialog.
This is done in a java class, nothing native about that, so nothing that makes it less portable.
If I am missing something here, please let me know!

> There is no way right now to implement this API to
> work consistently (as specified) on all platforms.

I fail to see what the platform has to do with this, so an explenation on why would be appreciated!

oleg.sukhodolsky
Offline
Joined: 2006-02-17
Points: 0

>> On Solaris or Linux, the behavior heavily depends on
>> desktop system used. On some systems it just works,
>> for example, on RH9/GNOME, on other it might not.
>I'd like to hear your reasoning behind such a statement; since modality in AWT
>is implemented above the native widgetset.
>In practise it is nothing more then ignoring the events for all windows except
>the dialog and children of the dialog.
>This is done in a java class, nothing native about that, so nothing that makes
>it less portable.
>If I am missing something here, please let me know!

The main problem with modality implemenation on X is that modality is not only
filtering events which are targeted to out widgets, but also special handling
for events which are targeted to decoaration of our top-levels (e.g. we should
deny resizing, changeing z-order, opening system menu). But decoration is
Window Manager's widgets and we need such support from WMs. And they do not
provide becuase there is no protocols which require such support.

JamaxVT
Offline
Joined: 2006-02-17
Points: 0

One problem is that some Window events are not received at the Java AWT level because of modality in the operating system. On Windows you can disable the modality with:
[pre]
import sun.awt.windows.*;

final WToolkit wt = WToolkit.getWToolkit();
wt.addModalityListener(new ModalityListener() {
public void modalityPopped(ModalityEvent event) {}
public void modalityPushed(ModalityEvent event) {
wt.popModality();
}
});
[/pre]
This allows other windows to receive input events (for the decoration and all), but it also means that the window won't behave exactly like a dialog. For instance, you click in the parent window and it doesn't blink / call attention to the dialog. You'll want to write code to make the dialog come to the front and 'blink' when the user clicks in the owner.

Of course the code should use reflection so that it works if the sun classes are not present for whatever reason, and also it should activate the right code for the OS type (above works on Windows XP).