source: trunk/gli/src/org/greenstone/gatherer/gui/ModalDialog.java@ 8480

Last change on this file since 8480 was 8480, checked in by mdewsnip, 19 years ago

Fixed the ModalDialog so it works with Java 1.5.0.

  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 KB
Line 
1/*#########################################################################
2 *
3 * A component of the Gatherer application, part of the Greenstone digital
4 * library suite from the New Zealand Digital Library Project at the
5 * University of Waikato, New Zealand.
6 *
7 * Author: John Thompson, Greenstone Digital Library, University of Waikato
8 *
9 * Copyright (C) 1999 New Zealand Digital Library Project
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *########################################################################
25 */
26package org.greenstone.gatherer.gui;
27
28import java.awt.*;
29import java.awt.event.*;
30import javax.swing.*;
31import org.greenstone.gatherer.DebugStream;
32
33
34/** An extension of the JDialog that overrides the JVM's typical modal behaviour. This typical behaviour is that when a modal dialog is opened, all other windows cease to respond to user events until the modal dialog is disposed. However this prevents us opening the help documents property whenever a modal dialog is open. Thus we override the modal behaviour so that only the owner frame or dialog is blocked.
35 * Note that because we always call the super constructor with modal set to false, this should be made visible with setVisible(true) rather than show() which will return straight away. */
36// feedback note: veronika had changed all the super constructor calls to
37// use modal instead of false - not sure if this is needed so I have not
38// put that in. --kjdon
39public class ModalDialog
40 extends JDialog {
41
42 /** The current modal dialog being shown on screen, if any. */
43 static public ModalDialog current_modal = null;
44
45 /** true if this dialog should be modal, ie block user actions to its owner window, false otherwise. */
46 protected boolean modal = false;
47 /** true if this dialog is currently waiting some thread. */
48 protected boolean waiting = false;
49
50 /** Constructor.
51 */
52 public ModalDialog() {
53 super((Frame)null, "", false);
54 }
55
56 /** Constructor.
57 * @param parent the Dialog which is the owener of this dialog.
58 */
59 public ModalDialog(Dialog parent) {
60 super(parent, "", false);
61 }
62
63 /** Constructor.
64 * @param parent the Dialog which is the owener of this dialog.
65 * @param modal true if this dialog should be modal, ie block user actions to its owner window, false otherwise.
66 */
67 public ModalDialog(Dialog parent, boolean modal) {
68 super(parent, "", false);
69 this.modal = modal;
70 }
71
72 /** Constructor.
73 * @param parent the Dialog which is the owner of this dialog.
74 * @param title the String to use as the title for this dialog.
75 */
76 public ModalDialog(Dialog parent, String title) {
77 super (parent, title, false);
78 this.modal = false;
79 }
80
81 /** Constructor.
82 * @param parent the Dialog which is the owener of this dialog.
83 * @param title the String to use as the title for this dialog.
84 * @param modal true if this dialog should be modal, ie block user actions to its owner window, false otherwise.
85 */
86 public ModalDialog(Dialog parent, String title, boolean modal) {
87 super (parent, title, false);
88 this.modal = modal;
89 }
90
91 /** Constructor.
92 * @param parent the Frame which is the owener of this dialog.
93 */
94 public ModalDialog(Frame parent) {
95 super(parent, "", false);
96 }
97
98 /** Constructor.
99 * @param parent the Frame which is the owener of this dialog.
100 * @param modal whether this dialog is modal or not
101 */
102 public ModalDialog(Frame parent, boolean modal) {
103 super(parent, "", false);
104 this.modal = modal;
105 }
106
107 /** Constructor.
108 * @param parent the Frame which is the owner of this dialog.
109 * @param title the String to use as the title for this dialog.
110 */
111 public ModalDialog(Frame parent, String title) {
112 super (parent, title, false);
113 }
114
115 /** Constructor.
116 * @param parent the Frame which is the owener of this dialog.
117 * @param title the String to use as the title for this dialog.
118 * @param modal true if this dialog should be modal, ie block user actions to its owner window, false otherwise.
119 */
120 public ModalDialog(Frame parent, String title, boolean modal) {
121 super (parent, title, false);
122 this.modal = modal;
123 }
124
125 public void dispose() {
126 super.dispose();
127 }
128
129 /** Ensures the current dialog is visible. */
130 public void makeVisible() {
131 super.setVisible(true);
132 }
133
134 /** The set visible method is overriden to provide modal functionality. It essentially hijacks control of the event dispatch thread while the dialog is open, only allowing non-user events to be passed to the parent dialog. Furthermore it only has this effect within the current AWT component tree by utilitizing the TreeLock.
135 * @param visible true if this dialog should be painted on-screen, false otherwise.
136 */
137 public void setVisible(boolean visible)
138 {
139 if (visible) {
140 current_modal = this;
141 }
142 else {
143 current_modal = null;
144 }
145
146 // If we are in the AWT Dispatch thread then it is all good.
147 if (SwingUtilities.isEventDispatchThread()) {
148 super.setVisible(visible);
149 if (modal && visible) {
150 EventQueue theQueue = getToolkit().getSystemEventQueue();
151 while (isVisible()) {
152 try {
153 AWTEvent event = theQueue.getNextEvent();
154 Object src = event.getSource();
155
156 // Block all keyboard and mouse events to the parent component
157 if (src.equals(getParent())) {
158 if (event instanceof KeyEvent || event instanceof MouseEvent) {
159 // System.err.println("Event to parent component blocked.");
160 continue;
161 }
162 }
163
164 // Re-dispatch other events
165 if (event instanceof ActiveEvent) {
166 ((ActiveEvent) event).dispatch();
167 }
168 else if (src instanceof Component) {
169 ((Component) src).dispatchEvent(event);
170 }
171 }
172 catch (Exception exception) {
173 DebugStream.printStackTrace(exception);
174 }
175 }
176 }
177 }
178 else {
179 try {
180 SwingUtilities.invokeAndWait(new MakeDialogVisibleTask(this, visible));
181 }
182 catch (Exception exception) {
183 DebugStream.printStackTrace(exception);
184 }
185 }
186 }
187
188 private class MakeDialogVisibleTask
189 implements Runnable {
190 private boolean make_visible;
191 private ModalDialog dialog;
192 public MakeDialogVisibleTask(ModalDialog dialog, boolean make_visible) {
193 this.dialog = dialog;
194 this.make_visible = make_visible;
195 }
196 public void run() {
197 // Blocks until the user dismisses the dialog
198 dialog.setVisible(make_visible);
199 }
200 }
201
202 /** Overridden method so we can control modality and not rely on the Dialog default.
203 * @param modal true if this dialog should be modal, ie block user actions to its owner window, false otherwise.
204 */
205 public void setModal (boolean modal) {
206 this.modal = modal;
207 }
208}
Note: See TracBrowser for help on using the repository browser.