View Javadoc

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__ */