|
@@ -1,329 +0,0 @@
|
1
|
|
-
|
2
|
|
-/**
|
3
|
|
- * Copyright (c) 2006-2009, Alexander Potochkin All rights reserved.
|
4
|
|
- *
|
5
|
|
- * Redistribution and use in source and binary forms, with or without modification, are permitted
|
6
|
|
- * provided that the following conditions are met:
|
7
|
|
- *
|
8
|
|
- * * Redistributions of source code must retain the above copyright notice, this list of conditions
|
9
|
|
- * and the following disclaimer. * Redistributions in binary form must reproduce the above copyright
|
10
|
|
- * notice, this list of conditions and the following disclaimer in the documentation and/or other
|
11
|
|
- * materials provided with the distribution. * Neither the name of the JXLayer project nor the names
|
12
|
|
- * of its contributors may be used to endorse or promote products derived from this software without
|
13
|
|
- * specific prior written permission.
|
14
|
|
- *
|
15
|
|
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
|
16
|
|
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
17
|
|
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
18
|
|
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
19
|
|
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
20
|
|
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
21
|
|
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
|
22
|
|
- * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
23
|
|
- */
|
24
|
|
-package com.dmdirc.addons.ui_swing.components;
|
25
|
|
-
|
26
|
|
-import java.awt.Component;
|
27
|
|
-import java.awt.Cursor;
|
28
|
|
-import java.awt.Graphics;
|
29
|
|
-import java.awt.Graphics2D;
|
30
|
|
-import java.awt.KeyboardFocusManager;
|
31
|
|
-import java.awt.event.FocusEvent;
|
32
|
|
-import java.awt.event.FocusListener;
|
33
|
|
-
|
34
|
|
-import javax.swing.JComponent;
|
35
|
|
-import javax.swing.SwingUtilities;
|
36
|
|
-
|
37
|
|
-import org.jdesktop.jxlayer.JXLayer;
|
38
|
|
-import org.jdesktop.jxlayer.plaf.AbstractBufferedLayerUI;
|
39
|
|
-import org.jdesktop.jxlayer.plaf.effect.LayerEffect;
|
40
|
|
-
|
41
|
|
-/**
|
42
|
|
- * An implementation of the {@code BufferedLayerUI} which provides a lightweight disabling for the
|
43
|
|
- * content of its {@link JXLayer}. This allows temporarily blocking a part of the interface with all
|
44
|
|
- * it subcomponents, it is also useful when some kind of action is in progress, e.g. reading data
|
45
|
|
- * from a database.
|
46
|
|
- * <p>
|
47
|
|
- * When {@code true} is passed to the {@link #setLocked(boolean)}, the {@code JXLayer} of this
|
48
|
|
- * {@code LockableLayerUI} becomes "locked". It sets the "wait" mouse cursor and stops reacting on
|
49
|
|
- * mouse, keyboard and focus events.
|
50
|
|
- * <p>
|
51
|
|
- * If {@code setLocked(boolean)} is called with {@code false} parameter after that, the
|
52
|
|
- * {@code JXLayer}, together with all its subcomponents, gets back to live.
|
53
|
|
- * <p>
|
54
|
|
- * Subclasses usually override {@link #paintLayer(Graphics2D,JXLayer)} or
|
55
|
|
- * {@link #getLayerEffects(JXLayer)} to implement some visual effects when {@code JXLayer} is in
|
56
|
|
- * locked state.
|
57
|
|
- * <p>
|
58
|
|
- * Here is an example of using {@code LockableLayerUI}:
|
59
|
|
- * <pre>
|
60
|
|
- * JComponent myComponent = getMyComponent(); // just any component
|
61
|
|
- *
|
62
|
|
- * LockableLayerUI lockableUI = new LockableLayerUI();
|
63
|
|
- * JXLayer<JComponent> layer = new JXLayer<JComponent>(myComponent,
|
64
|
|
- * lockableUI);
|
65
|
|
- *
|
66
|
|
- * // locking the layer, use lockableUI.setLocked(false) to unlock
|
67
|
|
- * lockableUI.setLocked(true);
|
68
|
|
- *
|
69
|
|
- * // add the layer to a frame or a panel, like any other component
|
70
|
|
- * frame.add(layer);
|
71
|
|
- * </pre>
|
72
|
|
- *
|
73
|
|
- * @param <T> Generic type
|
74
|
|
- */
|
75
|
|
-public class LockedLayer<T extends JComponent> extends AbstractBufferedLayerUI<T> {
|
76
|
|
-
|
77
|
|
- /** A version number for this class. */
|
78
|
|
- private static final long serialVersionUID = 1;
|
79
|
|
- /** Are we locked. */
|
80
|
|
- private boolean locked;
|
81
|
|
- /** Most recent focus owner? */
|
82
|
|
- private Component recentFocusOwner;
|
83
|
|
- /** Cursor to show when locked. */
|
84
|
|
- private Cursor lockedCursor = Cursor.getPredefinedCursor(
|
85
|
|
- Cursor.DEFAULT_CURSOR);
|
86
|
|
- /** Effect to apply when locked. */
|
87
|
|
- private LayerEffect[] lockedEffects = new LayerEffect[0];
|
88
|
|
- /** Focus listener. */
|
89
|
|
- private final transient FocusListener focusListener = new FocusListener() {
|
90
|
|
-
|
91
|
|
- @Override
|
92
|
|
- public void focusGained(final FocusEvent e) {
|
93
|
|
- // we don't want extra repaintings
|
94
|
|
- // when focus comes from another window
|
95
|
|
- if (e.getOppositeComponent() != null) {
|
96
|
|
- setDirty(true);
|
97
|
|
- }
|
98
|
|
- }
|
99
|
|
-
|
100
|
|
- @Override
|
101
|
|
- public void focusLost(final FocusEvent e) {
|
102
|
|
- //Ignore
|
103
|
|
- }
|
104
|
|
- };
|
105
|
|
-
|
106
|
|
- /**
|
107
|
|
- * Creates a new instance of LockableUI.
|
108
|
|
- */
|
109
|
|
- public LockedLayer() {
|
110
|
|
- this((LayerEffect[]) null);
|
111
|
|
- }
|
112
|
|
-
|
113
|
|
- /**
|
114
|
|
- * Creates a new instance of LockableUI, passed lockedEffects will be used for when this UI in
|
115
|
|
- * the locked state.
|
116
|
|
- *
|
117
|
|
- * @param effects effects to be used when this UI is locked
|
118
|
|
- *
|
119
|
|
- * @see #setLocked(boolean)
|
120
|
|
- * @see #setLockedEffects(LayerEffect...)
|
121
|
|
- */
|
122
|
|
- public LockedLayer(final LayerEffect... effects) {
|
123
|
|
-
|
124
|
|
- setLockedEffects(effects);
|
125
|
|
- }
|
126
|
|
-
|
127
|
|
- @Override
|
128
|
|
- public void installUI(final JComponent c) {
|
129
|
|
- super.installUI(c);
|
130
|
|
- // we need to repaint the layer when it receives the focus
|
131
|
|
- // otherwise the focused component will have it on the buffer image
|
132
|
|
- c.addFocusListener(focusListener);
|
133
|
|
- }
|
134
|
|
-
|
135
|
|
- @Override
|
136
|
|
- public void uninstallUI(final JComponent c) {
|
137
|
|
- super.uninstallUI(c);
|
138
|
|
- c.removeFocusListener(focusListener);
|
139
|
|
- }
|
140
|
|
-
|
141
|
|
- /**
|
142
|
|
- * Returns {@code true} if this {@code LockableLayerUI} is in locked state and all
|
143
|
|
- * {@link JXLayer}'s mouse, keyboard and focus events are temporarily blocked, otherwise returns
|
144
|
|
- * {@code false}.
|
145
|
|
- *
|
146
|
|
- * @return {@code true} if this {@code LockableLayerUI} is in locked state and all
|
147
|
|
- * {@code JXLayer}'s mouse, keyboard and focus events are temporarily blocked, otherwise
|
148
|
|
- * returns {@code false}
|
149
|
|
- */
|
150
|
|
- public boolean isLocked() {
|
151
|
|
- return locked;
|
152
|
|
- }
|
153
|
|
-
|
154
|
|
- /**
|
155
|
|
- * If {@code isLocked} is {@code true} then all mouse, keyboard and focus events from the
|
156
|
|
- * {@link JXLayer} of this {@code LockableLayerUI} will be temporarily blocked.
|
157
|
|
- *
|
158
|
|
- * @param isLocked if {@code true} then all mouse, keyboard and focus events from the
|
159
|
|
- * {@code JXLayer} of this {@code LockableLayerUI} will be temporarily blocked
|
160
|
|
- */
|
161
|
|
- public void setLocked(final boolean isLocked) {
|
162
|
|
- if (isLocked != isLocked()) {
|
163
|
|
- if (getLayer() != null) {
|
164
|
|
- final KeyboardFocusManager kfm = KeyboardFocusManager.
|
165
|
|
- getCurrentKeyboardFocusManager();
|
166
|
|
- final Component focusOwner = kfm.getPermanentFocusOwner();
|
167
|
|
- final boolean focusInLayer = focusOwner != null
|
168
|
|
- && SwingUtilities.isDescendingFrom(focusOwner,
|
169
|
|
- getLayer());
|
170
|
|
- if (isLocked) {
|
171
|
|
- if (focusInLayer && kfm.getFocusedWindow()
|
172
|
|
- == SwingUtilities.getWindowAncestor(getLayer())) {
|
173
|
|
- recentFocusOwner = focusOwner;
|
174
|
|
- // setDirty() will be called from the layer's
|
175
|
|
- //focusListener when focus already left layer's view
|
176
|
|
- //and hiding it in the paintLayer() won't mess the
|
177
|
|
- //focus up getLayer().requestFocusInWindow();
|
178
|
|
- } else {
|
179
|
|
- setDirty(true);
|
180
|
|
- }
|
181
|
|
- // the mouse cursor is set to the glassPane
|
182
|
|
- getLayer().getGlassPane().setCursor(getLockedCursor());
|
183
|
|
- } else {
|
184
|
|
- // show the view again
|
185
|
|
- getLayer().getView().setVisible(true);
|
186
|
|
- // restore the focus if it is still in the layer
|
187
|
|
- if (focusInLayer && recentFocusOwner != null) {
|
188
|
|
- recentFocusOwner.requestFocusInWindow();
|
189
|
|
- }
|
190
|
|
- recentFocusOwner = null;
|
191
|
|
- getLayer().getGlassPane().setCursor(null);
|
192
|
|
- }
|
193
|
|
- }
|
194
|
|
- this.locked = isLocked;
|
195
|
|
- firePropertyChange("locked", !isLocked, isLocked);
|
196
|
|
- }
|
197
|
|
- }
|
198
|
|
-
|
199
|
|
- // If it is locked, the buffer image will be updated
|
200
|
|
- // only if the layer changes its size or setDirty(true) was called
|
201
|
|
- @Override
|
202
|
|
- protected boolean isIncrementalUpdate(
|
203
|
|
- final JXLayer<? extends T> l) {
|
204
|
|
- return !isLocked();
|
205
|
|
- }
|
206
|
|
-
|
207
|
|
- @Override
|
208
|
|
- protected void paintLayer(final Graphics2D g2,
|
209
|
|
- final JXLayer<? extends T> l) {
|
210
|
|
- if (isLocked()) {
|
211
|
|
- // Note: this code will be called only if layer changes its size,
|
212
|
|
- // or setDirty(true) was called,
|
213
|
|
- // otherwise the previously created buffer is used
|
214
|
|
- l.getView().setVisible(true);
|
215
|
|
- l.paint(g2);
|
216
|
|
- // hide the layer's view component
|
217
|
|
- // this is the only way to disable key shortcuts
|
218
|
|
- // installed on its subcomponents
|
219
|
|
- l.getView().setVisible(false);
|
220
|
|
- }
|
221
|
|
- }
|
222
|
|
-
|
223
|
|
- @Override
|
224
|
|
- public void paint(final Graphics g, final JComponent c) {
|
225
|
|
- super.paint(g, c);
|
226
|
|
- // if it is not locked, we need to paint the layer as is
|
227
|
|
- // otherwise we also need to paint it again;
|
228
|
|
- // if there are any glassPane's children
|
229
|
|
- // they should be shown unfiltered
|
230
|
|
- c.paint(g);
|
231
|
|
- }
|
232
|
|
-
|
233
|
|
- /**
|
234
|
|
- * Returns the mouse cursor to be used by this {@code LockableLayerUI} when it locked state.
|
235
|
|
- *
|
236
|
|
- * @return the mouse cursor to be used by this {@code LockableLayerUI} when it locked state
|
237
|
|
- *
|
238
|
|
- * @see #getLockedCursor()
|
239
|
|
- * @see #setLocked(boolean)
|
240
|
|
- */
|
241
|
|
- public Cursor getLockedCursor() {
|
242
|
|
- return lockedCursor;
|
243
|
|
- }
|
244
|
|
-
|
245
|
|
- /**
|
246
|
|
- * Sets the mouse cursor to be used by this {@code LockableLayerUI} when it locked state.
|
247
|
|
- *
|
248
|
|
- * @param newCursor the mouse cursor to be used by this {@code LockableLayerUI} when it locked
|
249
|
|
- * state
|
250
|
|
- */
|
251
|
|
- public void setLockedCursor(final Cursor newCursor) {
|
252
|
|
- final Cursor oldCursor = getLockedCursor();
|
253
|
|
- this.lockedCursor = newCursor;
|
254
|
|
- firePropertyChange("lockedCursor", oldCursor, newCursor);
|
255
|
|
- if (isLocked()) {
|
256
|
|
- getLayer().getGlassPane().setCursor(newCursor);
|
257
|
|
- }
|
258
|
|
- }
|
259
|
|
-
|
260
|
|
- /**
|
261
|
|
- * Returns the effects to be used when this UI is locked.
|
262
|
|
- *
|
263
|
|
- * @return the effects to be used when this UI is locked
|
264
|
|
- *
|
265
|
|
- * @see #setLocked(boolean)
|
266
|
|
- */
|
267
|
|
- public LayerEffect[] getLockedEffects() {
|
268
|
|
- final LayerEffect[] result = new LayerEffect[lockedEffects.length];
|
269
|
|
- System.arraycopy(lockedEffects, 0, result, 0, result.length);
|
270
|
|
- return result;
|
271
|
|
- }
|
272
|
|
-
|
273
|
|
- /**
|
274
|
|
- * This method returns the array of {@code LayerEffect}s set using
|
275
|
|
- * {@link #setLockedEffects(LayerEffect...)}
|
276
|
|
- * <p>
|
277
|
|
- * If a {@code LockableUI} provides more extensive API to support different {@code Effect}s
|
278
|
|
- * depending on its state or on the state of the passed {@code JXLayer}, this method should be
|
279
|
|
- * overridden.
|
280
|
|
- *
|
281
|
|
- * @param l Layer to get effects from
|
282
|
|
- *
|
283
|
|
- * @return Locked layer effect
|
284
|
|
- *
|
285
|
|
- * @see #setLockedEffects (LayerEffect...)
|
286
|
|
- * @see #getLockedEffects()
|
287
|
|
- */
|
288
|
|
- protected LayerEffect[] getLockedEffects(
|
289
|
|
- final JXLayer<? extends JComponent> l) {
|
290
|
|
- return getLockedEffects();
|
291
|
|
- }
|
292
|
|
-
|
293
|
|
- /**
|
294
|
|
- * Sets the effects to be used when this UI is locked.
|
295
|
|
- *
|
296
|
|
- * @param effects the effects to be used when this UI is locked
|
297
|
|
- *
|
298
|
|
- * @see #setLocked(boolean)
|
299
|
|
- */
|
300
|
|
- public void setLockedEffects(final LayerEffect... effects) {
|
301
|
|
- final LayerEffect[] layerEffect;
|
302
|
|
- final LayerEffect[] oldEffects = getLockedEffects();
|
303
|
|
- if (effects == null) {
|
304
|
|
- layerEffect = new LayerEffect[0];
|
305
|
|
- } else {
|
306
|
|
- layerEffect = effects;
|
307
|
|
- }
|
308
|
|
- for (LayerEffect effect : getLockedEffects()) {
|
309
|
|
- effect.removePropertyChangeListener(this);
|
310
|
|
- }
|
311
|
|
- this.lockedEffects = new LayerEffect[layerEffect.length];
|
312
|
|
- System.arraycopy(layerEffect, 0, this.lockedEffects, 0,
|
313
|
|
- layerEffect.length);
|
314
|
|
- for (LayerEffect lockedEffect : layerEffect) {
|
315
|
|
- lockedEffect.addPropertyChangeListener(this);
|
316
|
|
- }
|
317
|
|
- firePropertyChange("lockedEffects", oldEffects, layerEffect);
|
318
|
|
- }
|
319
|
|
-
|
320
|
|
- @Override
|
321
|
|
- protected LayerEffect[] getLayerEffects(final JXLayer<? extends T> l) {
|
322
|
|
- if (isLocked()) {
|
323
|
|
- return getLockedEffects(l);
|
324
|
|
- } else {
|
325
|
|
- return super.getLayerEffects(l);
|
326
|
|
- }
|
327
|
|
- }
|
328
|
|
-
|
329
|
|
-}
|