diff options
Diffstat (limited to 'libjava/classpath/javax/swing/JOptionPane.java')
-rw-r--r-- | libjava/classpath/javax/swing/JOptionPane.java | 112 |
1 files changed, 75 insertions, 37 deletions
diff --git a/libjava/classpath/javax/swing/JOptionPane.java b/libjava/classpath/javax/swing/JOptionPane.java index 0bef12b61fc..f9490553834 100644 --- a/libjava/classpath/javax/swing/JOptionPane.java +++ b/libjava/classpath/javax/swing/JOptionPane.java @@ -1,5 +1,5 @@ /* JOptionPane.java - Copyright (C) 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,14 +38,20 @@ exception statement from your version. */ package javax.swing; +import java.awt.AWTEvent; +import java.awt.ActiveEvent; import java.awt.Component; +import java.awt.Container; +import java.awt.EventQueue; import java.awt.Frame; +import java.awt.MenuComponent; +import java.awt.Toolkit; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseMotionAdapter; import javax.accessibility.Accessible; import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleRole; -import javax.swing.event.InternalFrameAdapter; -import javax.swing.event.InternalFrameEvent; import javax.swing.plaf.OptionPaneUI; /** @@ -57,17 +63,15 @@ import javax.swing.plaf.OptionPaneUI; public class JOptionPane extends JComponent implements Accessible { /** - * DOCUMENT ME! + * Provides the accessibility features for the <code>JOptionPane</code> + * component. */ - // FIXME: This inner class is a complete stub and needs to be implemented - // properly. protected class AccessibleJOptionPane extends JComponent.AccessibleJComponent { - /** DOCUMENT ME! */ private static final long serialVersionUID = 686071432213084821L; /** - * Creates a new AccessibleJOptionPane object. + * Creates a new <code>AccessibleJOptionPane</code> instance. */ protected AccessibleJOptionPane() { @@ -86,7 +90,6 @@ public class JOptionPane extends JComponent implements Accessible } } - /** DOCUMENT ME! */ private static final long serialVersionUID = 5231143276678566796L; /** The value returned when cancel option is selected. */ @@ -431,9 +434,11 @@ public class JOptionPane extends JComponent implements Accessible } /** - * DOCUMENT ME! + * Returns the object that provides accessibility features for this + * <code>JOptionPane</code> component. * - * @return DOCUMENT ME! + * @return The accessible context (an instance of + * {@link AccessibleJOptionPane}). */ public AccessibleContext getAccessibleContext() { @@ -1529,31 +1534,64 @@ public class JOptionPane extends JComponent implements Accessible */ private static void startModal(JInternalFrame f) { - synchronized (f) - { - final JInternalFrame tmp = f; - tmp.toFront(); - - f.addInternalFrameListener(new InternalFrameAdapter() - { - public void internalFrameClosed(InternalFrameEvent e) - { - synchronized (tmp) - { - tmp.removeInternalFrameListener(this); - tmp.notifyAll(); - } - } - }); - try - { - while (! f.isClosed()) - f.wait(); - } - catch (InterruptedException ignored) - { - // Ignore this Exception. - } - } + // We need to add an additional glasspane-like component directly + // below the frame, which intercepts all mouse events that are not + // directed at the frame itself. + JPanel modalInterceptor = new JPanel(); + modalInterceptor.setOpaque(false); + JLayeredPane lp = JLayeredPane.getLayeredPaneAbove(f); + lp.setLayer(modalInterceptor, JLayeredPane.MODAL_LAYER.intValue()); + modalInterceptor.setBounds(0, 0, lp.getWidth(), lp.getHeight()); + modalInterceptor.addMouseListener(new MouseAdapter(){}); + modalInterceptor.addMouseMotionListener(new MouseMotionAdapter(){}); + lp.add(modalInterceptor); + f.toFront(); + + // We need to explicitly dispatch events when we are blocking the event + // dispatch thread. + EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue(); + try + { + while (! f.isClosed()) + { + if (EventQueue.isDispatchThread()) + { + // The getNextEventMethod() issues wait() when no + // event is available, so we don't need do explicitly wait(). + AWTEvent ev = queue.getNextEvent(); + // This mimics EventQueue.dispatchEvent(). We can't use + // EventQueue.dispatchEvent() directly, because it is + // protected, unfortunately. + if (ev instanceof ActiveEvent) + ((ActiveEvent) ev).dispatch(); + else if (ev.getSource() instanceof Component) + ((Component) ev.getSource()).dispatchEvent(ev); + else if (ev.getSource() instanceof MenuComponent) + ((MenuComponent) ev.getSource()).dispatchEvent(ev); + // Other events are ignored as per spec in + // EventQueue.dispatchEvent + } + else + { + // Give other threads a chance to become active. + Thread.yield(); + } + } + } + catch (InterruptedException ex) + { + // If we get interrupted, then leave the modal state. + } + finally + { + // Clean up the modal interceptor. + lp.remove(modalInterceptor); + + // Remove the internal frame from its parent, so it is no longer + // lurking around and clogging memory. + Container parent = f.getParent(); + if (parent != null) + parent.remove(f); + } } } |