1 /*
2 * Copyright (c) 2003-2008 by Cosylab d. d.
3 *
4 * This file is part of CosyBeans-Common.
5 *
6 * CosyBeans-Common is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * CosyBeans-Common is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with CosyBeans-Common. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 package com.cosylab.gui.components;
21
22 import java.awt.Container;
23 import java.awt.Window;
24 import java.awt.event.MouseAdapter;
25 import java.awt.event.MouseEvent;
26 import java.awt.event.WindowAdapter;
27 import java.awt.event.WindowEvent;
28
29 import javax.swing.JComponent;
30 import javax.swing.JDialog;
31 import javax.swing.JFrame;
32 import javax.swing.JLabel;
33
34
35 /**
36 * InterceptorPane is specialized GUI component that installs itself into any
37 * descendant of the <code>java.awt.Window</code>. It acts as a mouse click
38 * interceptor whenever the window is not active. This is a safety mechanism
39 * to prevent accidental clicks to be performed when the user only wants to
40 * bring the window into focus.
41 *
42 * <p>
43 * To install InterceptorPane onto a JFrame or JDialog, simply create a new
44 * instance using the constructor:<br>
45 * <code> JFrame frame; new InterceptorFrame(frame); </code>
46 * </p>
47 *
48 * <p>
49 * Creation date: (4/8/2002 11:51:40)
50 * </p>
51 *
52 * @author <a href="mailto:ales.pucelj@cosylab.com">Ales Pucelj</a>
53 * @version $id$
54 */
55 public final class InterceptorPane extends JComponent
56 {
57 private static final long serialVersionUID = 1L;
58
59 // Window instance interceptor is installed on
60 protected Window window = null;
61
62 // Flag indicating whether to ignore windows owned by this window
63 protected boolean ignoreOwned = false;
64
65 // Mouse click interceptor
66 private ClickListener clickListener = null;
67
68 // Monitoring of changes in focus
69 private FocusMonitor focusMonitor = null;
70
71 protected final class ClickListener extends MouseAdapter
72 {
73 private final void ignoreEvent(MouseEvent e)
74 {
75 e.consume();
76 setVisible(false);
77 }
78
79 /*
80 * (non-Javadoc)
81 * @see java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent)
82 */
83 public final void mouseClicked(MouseEvent e)
84 {
85 ignoreEvent(e);
86 }
87
88 /*
89 * (non-Javadoc)
90 * @see java.awt.event.MouseAdapter#mousePressed(java.awt.event.MouseEvent)
91 */
92 public final void mousePressed(MouseEvent e)
93 {
94 ignoreEvent(e);
95 }
96 }
97
98 /**
99 * This listener monitors changes in focus. When a window with an
100 * interceptor pane is deactivated, its interceptor pane is activated, and
101 * intercepts the mouse click in its area.
102 *
103 * @author <a href="mailto:ales.pucelj@cosylab.com">Ales Pucelj</a>
104 * @version $id$
105 */
106 protected final class FocusMonitor extends WindowAdapter
107 {
108 /**
109 * Installs the glass pane only if the
110 *
111 * @param e WindowEvent
112 *
113 * @see java.awt.event.WindowListener#windowDeactivated(WindowEvent)
114 */
115 public final void windowDeactivated(WindowEvent e)
116 {
117 if (ignoreOwned
118 && (e.getOppositeWindow().getOwner() == getWindow())) {
119 return;
120 }
121
122 setSize(getWindow().getSize());
123 setVisible(true);
124 }
125
126 /**
127 * Uneccesary, but still implemented.
128 *
129 * @param e WindowEvent
130 *
131 * @see java.awt.event.WindowListener#windowClosing(WindowEvent)
132 */
133 public final void windowClosing(WindowEvent e)
134 {
135 uninstall();
136 }
137 }
138
139 /**
140 * Default constructor for InterceptorPane. Creation date: (10.4.2002
141 * 15:15:26)
142 *
143 * @param container Container
144 */
145 public InterceptorPane(Container container)
146 {
147 this(container, false);
148 }
149
150 /**
151 * Creates new InterceptorPane with option to not ignore clicks when
152 * switching to and from windows owned by this window.
153 *
154 * @param container Container
155 * @param ignoreOwnedWindows boolean
156 */
157 public InterceptorPane(Container container, boolean ignoreOwnedWindows)
158 {
159 super();
160 initialize(container);
161 ignoreOwned = ignoreOwnedWindows;
162 }
163
164 /**
165 * Installs the interceptor pane into the component specified. If the
166 * specified container is not a valid target, and exception will be
167 * thrown.
168 *
169 * @param container Container
170 *
171 * @throws UnsupportedOperationException
172 */
173 private void initialize(Container container)
174 {
175 boolean initialized = false;
176
177 if (container instanceof JFrame) {
178 window = (JFrame)container;
179 ((JFrame)window).setGlassPane(this);
180
181 initialized = true;
182 }
183
184 if (container instanceof JDialog) {
185 window = (JDialog)container;
186 ((JDialog)window).setGlassPane(this);
187
188 initialized = true;
189 }
190
191 if (!initialized) {
192 throw new UnsupportedOperationException("Window class "
193 + container.getClass().getName()
194 + " does not support glass panes.");
195 }
196
197 clickListener = new ClickListener();
198 addMouseListener(clickListener);
199
200 // addWindowListener is used instead of addWindowFocusListener
201 // for backward compatibility
202 focusMonitor = new FocusMonitor();
203 window.addWindowListener(focusMonitor);
204 }
205
206 /**
207 * Removes InterceptorPane from the window. This method uninstalls all
208 * listeners from the window and removes itself from the glass pane. To
209 * reenable the pane, a new instance must be created.
210 */
211 public void uninstall()
212 {
213 if (window == null) {
214 return;
215 }
216
217 window.removeMouseListener(clickListener);
218
219 window.removeWindowListener(focusMonitor);
220
221 if (window instanceof JFrame) {
222 ((JFrame)window).setGlassPane(new JLabel());
223 }
224
225 if (window instanceof JDialog) {
226 ((JDialog)window).setGlassPane(new JLabel());
227 }
228
229 window = null;
230 clickListener = null;
231 focusMonitor = null;
232 }
233
234 /**
235 * Returns instance of the window this interceptor is installed on.
236 *
237 * @return Window
238 */
239 public Window getWindow()
240 {
241 return window;
242 }
243 }
244
245 /* __oOo__ */