Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extTopology / src / org / gvsig / gui / ModalDialog.java @ 21273

History | View | Annotate | Download (7.29 KB)

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
 */
26
package org.gvsig.gui;
27

    
28
import java.awt.*;
29
import java.awt.event.*;
30
import javax.swing.*;
31

    
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
39
public class ModalDialog
40
    extends JDialog {
41

    
42
    /**
43
         * 
44
         */
45
        private static final long serialVersionUID = 6966218812722673601L;
46

    
47
        /** The current modal dialog being shown on screen, if any. */
48
    static public ModalDialog current_modal = null;
49

    
50
    /** true if this dialog should be modal, ie block user actions to its owner window, false otherwise. */
51
    protected boolean modal = false;
52
    /** true if this dialog is currently waiting some thread. */
53
    protected boolean waiting = false;
54

    
55
    /** Constructor.
56
     */
57
    public ModalDialog() {
58
        super((Frame)null, "", false);
59
    }
60

    
61
    /** Constructor.
62
     * @param parent the Dialog which is the owener of this dialog.
63
    */
64
    public ModalDialog(Dialog parent) {
65
        super(parent, "", false);
66
    }
67

    
68
    /** Constructor.
69
     * @param parent the Dialog which is the owener of this dialog.
70
     * @param modal true if this dialog should be modal, ie block user actions to its owner window, false otherwise.
71
     */
72
    public ModalDialog(Dialog parent, boolean modal) {
73
        super(parent, "", false);
74
        this.modal = modal;
75
    }
76
    
77
    /** Constructor.
78
     * @param parent the Dialog which is the owner of this dialog.
79
     * @param title the String to use as the title for this dialog.
80
     */
81
    public ModalDialog(Dialog parent, String title) {
82
        super (parent, title, false);
83
        this.modal = false;
84
    }
85

    
86
    /** Constructor.
87
     * @param parent the Dialog which is the owener of this dialog.
88
     * @param title the String to use as the title for this dialog.
89
     * @param modal true if this dialog should be modal, ie block user actions to its owner window, false otherwise.
90
     */
91
    public ModalDialog(Dialog parent, String title, boolean modal) {
92
        super (parent, title, false);
93
        this.modal = modal;
94
    }
95

    
96
   /** Constructor.
97
     * @param parent the Frame which is the owener of this dialog.
98
     */
99
    public ModalDialog(Frame parent) {
100
        super(parent, "", false);
101
    }
102

    
103
    /** Constructor.
104
     * @param parent the Frame which is the owener of this dialog.
105
     * @param modal whether this dialog is modal or not
106
     */
107
    public ModalDialog(Frame parent, boolean modal) {
108
        super(parent, "", false);
109
        this.modal = modal;
110
    }
111
    
112
    /** Constructor.
113
     * @param parent the Frame which is the owner of this dialog.
114
     * @param title the String to use as the title for this dialog.
115
     */
116
    public ModalDialog(Frame parent, String title) {
117
        super (parent, title, false);
118
    }
119

    
120
    /** Constructor.
121
     * @param parent the Frame which is the owener of this dialog.
122
     * @param title the String to use as the title for this dialog.
123
     * @param modal true if this dialog should be modal, ie block user actions to its owner window, false otherwise.
124
     */
125
    public ModalDialog(Frame parent, String title, boolean modal) {
126
        super (parent, title, false);
127
        this.modal = modal;
128
    }
129

    
130
    public void dispose() {
131
        super.dispose();
132
    }
133

    
134
    /** Ensures the current dialog is visible. */
135
    public void makeVisible() {
136
        super.setVisible(true);
137
    }
138

    
139
    /** 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.
140
     * @param visible true if this dialog should be painted on-screen, false otherwise.
141
     */
142
    public void setVisible(boolean visible)
143
    {
144
        if (visible) {
145
            current_modal = this;
146
        }
147
        else {
148
            current_modal = null;
149
        }
150

    
151
        // If we are in the AWT Dispatch thread then it is all good.
152
         if (SwingUtilities.isEventDispatchThread()) {
153
             super.setVisible(visible);
154
            if (modal && visible) {
155
                EventQueue theQueue = getToolkit().getSystemEventQueue();
156
                while (isVisible()) {
157
                    try {
158
                        AWTEvent event = theQueue.getNextEvent();
159
                        Object src = event.getSource();
160

    
161
                        // Block all keyboard and mouse events to the parent component
162
                        if (src.equals(getParent())) {
163
                            if (event instanceof KeyEvent || event instanceof MouseEvent) {
164
                                // System.err.println("Event to parent component blocked.");
165
                                continue;
166
                            }
167
                        }
168

    
169
                        // Re-dispatch other events
170
                        if (event instanceof ActiveEvent) {
171
                              ((ActiveEvent) event).dispatch();
172
                          }                            
173
                        else if (src instanceof Component) {
174
                            ((Component) src).dispatchEvent(event);
175
                        }
176
                    }
177
                    catch (Exception exception) {
178
                            exception.printStackTrace();
179
                    }
180
                }
181
            }
182
         }
183
         else {
184
             try {
185
                 SwingUtilities.invokeAndWait(new MakeDialogVisibleTask(this, visible));
186
             }
187
             catch (Exception exception) {
188
                     exception.printStackTrace();
189
             }
190
         }
191
    }
192
    
193
    private class MakeDialogVisibleTask
194
        implements Runnable {
195
        private boolean make_visible;
196
        private ModalDialog dialog;
197
        public MakeDialogVisibleTask(ModalDialog dialog, boolean make_visible) {
198
            this.dialog = dialog;
199
            this.make_visible = make_visible;
200
        }
201
        public void run() {
202
            // Blocks until the user dismisses the dialog
203
            dialog.setVisible(make_visible);
204
        }
205
    }
206

    
207
    /** Overridden method so we can control modality and not rely on the Dialog default.
208
     * @param modal true if this dialog should be modal, ie block user actions to its owner window, false otherwise.
209
     */
210
    public void setModal (boolean modal) {
211
        this.modal = modal;
212
    }
213
}