~ubuntu-branches/debian/stretch/insubstantial/stretch

« back to all changes in this revision

Viewing changes to flamingo/src/main/java/org/pushingpixels/flamingo/internal/ui/common/popup/BasicPopupPanelUI.java

  • Committer: Package Import Robot
  • Author(s): Felix Natter
  • Date: 2016-01-18 20:58:45 UTC
  • Revision ID: package-import@ubuntu.com-20160118205845-crbmrkda61qsi5qa
Tags: upstream-7.3+dfsg2
ImportĀ upstreamĀ versionĀ 7.3+dfsg2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2005-2010 Flamingo Kirill Grouchnikov. All Rights Reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without 
 
5
 * modification, are permitted provided that the following conditions are met:
 
6
 * 
 
7
 *  o Redistributions of source code must retain the above copyright notice, 
 
8
 *    this list of conditions and the following disclaimer. 
 
9
 *     
 
10
 *  o Redistributions in binary form must reproduce the above copyright notice, 
 
11
 *    this list of conditions and the following disclaimer in the documentation 
 
12
 *    and/or other materials provided with the distribution. 
 
13
 *     
 
14
 *  o Neither the name of Flamingo Kirill Grouchnikov nor the names of 
 
15
 *    its contributors may be used to endorse or promote products derived 
 
16
 *    from this software without specific prior written permission. 
 
17
 *     
 
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 
19
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
 
20
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 
21
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
 
22
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 
23
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 
24
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 
25
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 
26
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
 
27
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
 
28
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
29
 */
 
30
package org.pushingpixels.flamingo.internal.ui.common.popup;
 
31
 
 
32
import java.applet.Applet;
 
33
import java.awt.*;
 
34
import java.awt.event.*;
 
35
import java.util.List;
 
36
 
 
37
import javax.swing.*;
 
38
import javax.swing.border.*;
 
39
import javax.swing.plaf.*;
 
40
import javax.swing.plaf.basic.ComboPopup;
 
41
 
 
42
import org.pushingpixels.flamingo.api.common.JCommandButton;
 
43
import org.pushingpixels.flamingo.api.common.popup.JPopupPanel;
 
44
import org.pushingpixels.flamingo.api.common.popup.PopupPanelManager;
 
45
import org.pushingpixels.flamingo.api.common.popup.PopupPanelManager.PopupEvent;
 
46
import org.pushingpixels.flamingo.api.ribbon.JRibbon;
 
47
import org.pushingpixels.flamingo.internal.ui.ribbon.JRibbonTaskToggleButton;
 
48
import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.JRibbonApplicationMenuPopupPanel;
 
49
import org.pushingpixels.flamingo.internal.utils.FlamingoUtilities;
 
50
import org.pushingpixels.flamingo.internal.utils.KeyTipManager;
 
51
 
 
52
/**
 
53
 * Basic UI for popup panel {@link JPopupPanel}.
 
54
 * 
 
55
 * @author Kirill Grouchnikov
 
56
 */
 
57
public class BasicPopupPanelUI extends PopupPanelUI {
 
58
        /**
 
59
         * The associated popup panel.
 
60
         */
 
61
        protected JPopupPanel popupPanel;
 
62
 
 
63
        /*
 
64
         * (non-Javadoc)
 
65
         * 
 
66
         * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
 
67
         */
 
68
        public static ComponentUI createUI(JComponent c) {
 
69
                return new BasicPopupPanelUI();
 
70
        }
 
71
 
 
72
        /*
 
73
         * (non-Javadoc)
 
74
         * 
 
75
         * @see javax.swing.plaf.ComponentUI#installUI(javax.swing.JComponent)
 
76
         */
 
77
        @Override
 
78
        public void installUI(JComponent c) {
 
79
                this.popupPanel = (JPopupPanel) c;
 
80
                super.installUI(this.popupPanel);
 
81
                installDefaults();
 
82
                installComponents();
 
83
                installListeners();
 
84
        }
 
85
 
 
86
        /*
 
87
         * (non-Javadoc)
 
88
         * 
 
89
         * @see javax.swing.plaf.ComponentUI#uninstallUI(javax.swing.JComponent)
 
90
         */
 
91
        @Override
 
92
        public void uninstallUI(JComponent c) {
 
93
                uninstallListeners();
 
94
                uninstallComponents();
 
95
                uninstallDefaults();
 
96
                super.uninstallUI(this.popupPanel);
 
97
        }
 
98
 
 
99
        /**
 
100
         * Installs default settings for the associated command popup menu.
 
101
         */
 
102
        protected void installDefaults() {
 
103
                Color bg = this.popupPanel.getBackground();
 
104
                if (bg == null || bg instanceof UIResource) {
 
105
                        this.popupPanel.setBackground(FlamingoUtilities.getColor(
 
106
                                        Color.lightGray, "PopupPanel.background",
 
107
                                        "Panel.background"));
 
108
                }
 
109
 
 
110
                Border b = this.popupPanel.getBorder();
 
111
                if (b == null || b instanceof UIResource) {
 
112
                        Border toSet = UIManager.getBorder("PopupPanel.border");
 
113
                        if (toSet == null)
 
114
                                toSet = new BorderUIResource.CompoundBorderUIResource(
 
115
                                                new LineBorder(FlamingoUtilities.getBorderColor()),
 
116
                                                new EmptyBorder(1, 1, 1, 1));
 
117
                        this.popupPanel.setBorder(toSet);
 
118
                }
 
119
                LookAndFeel.installProperty(this.popupPanel, "opaque", Boolean.TRUE);
 
120
        }
 
121
 
 
122
        /**
 
123
         * Installs listeners on the associated command popup menu.
 
124
         */
 
125
        protected void installListeners() {
 
126
                initiliazeGlobalListeners();
 
127
        }
 
128
 
 
129
        /**
 
130
         * Installs components on the associated command popup menu.
 
131
         */
 
132
        protected void installComponents() {
 
133
        }
 
134
 
 
135
        /**
 
136
         * Uninstalls default settings from the associated command popup menu.
 
137
         */
 
138
        protected void uninstallDefaults() {
 
139
                LookAndFeel.uninstallBorder(this.popupPanel);
 
140
        }
 
141
 
 
142
        /**
 
143
         * Uninstalls listeners from the associated command popup menu.
 
144
         */
 
145
        protected void uninstallListeners() {
 
146
        }
 
147
 
 
148
        /**
 
149
         * Uninstalls subcomponents from the associated command popup menu.
 
150
         */
 
151
        protected void uninstallComponents() {
 
152
        }
 
153
 
 
154
        /**
 
155
         * The global listener that tracks the ESC key action on the root panes of
 
156
         * windows that show popup panels.
 
157
         */
 
158
        static PopupPanelManager.PopupListener popupPanelManagerListener;
 
159
 
 
160
        /**
 
161
         * Initializes the global listeners.
 
162
         */
 
163
        protected static synchronized void initiliazeGlobalListeners() {
 
164
                if (popupPanelManagerListener != null) {
 
165
                        return;
 
166
                }
 
167
 
 
168
                popupPanelManagerListener = new PopupPanelEscapeDismisser();
 
169
                PopupPanelManager.defaultManager().addPopupListener(
 
170
                                popupPanelManagerListener);
 
171
 
 
172
                new WindowTracker();
 
173
        }
 
174
 
 
175
        /**
 
176
         * This class is used to trace the changes in the shown popup panels and
 
177
         * install ESC key listener on the matching root pane so that the popup
 
178
         * panels can be dismissed with the ESC key.
 
179
         * 
 
180
         * @author Kirill Grouchnikov
 
181
         */
 
182
        protected static class PopupPanelEscapeDismisser implements
 
183
                        PopupPanelManager.PopupListener {
 
184
                /**
 
185
                 * The currently installed action map on the {@link #tracedRootPane}.
 
186
                 */
 
187
                private ActionMap newActionMap;
 
188
 
 
189
                /**
 
190
                 * The currently installed input map on the {@link #tracedRootPane}.
 
191
                 */
 
192
                private InputMap newInputMap;
 
193
 
 
194
                /**
 
195
                 * The last shown popup panel sequence.
 
196
                 */
 
197
                List<PopupPanelManager.PopupInfo> lastPathSelected;
 
198
 
 
199
                /**
 
200
                 * Currently traced root pane. It is the root pane of the originating
 
201
                 * component of the first popup panel in the currently shown sequence of
 
202
                 * {@link PopupPanelManager}.
 
203
                 */
 
204
                private JRootPane tracedRootPane;
 
205
 
 
206
                /**
 
207
                 * Creates a new tracer for popup panels to be dismissed with ESC key.
 
208
                 */
 
209
                public PopupPanelEscapeDismisser() {
 
210
                        PopupPanelManager popupPanelManager = PopupPanelManager
 
211
                                        .defaultManager();
 
212
                        this.lastPathSelected = popupPanelManager.getShownPath();
 
213
                        if (this.lastPathSelected.size() != 0) {
 
214
                                traceRootPane(this.lastPathSelected);
 
215
                        }
 
216
                }
 
217
 
 
218
                @Override
 
219
                public void popupHidden(PopupEvent event) {
 
220
                        PopupPanelManager msm = PopupPanelManager.defaultManager();
 
221
                        List<PopupPanelManager.PopupInfo> p = msm.getShownPath();
 
222
 
 
223
                        if (lastPathSelected.size() != 0 && p.size() == 0) {
 
224
                                // if it is the last popup panel to be dismissed, untrace the
 
225
                                // root pane
 
226
                                untraceRootPane();
 
227
                        }
 
228
 
 
229
                        lastPathSelected = p;
 
230
                }
 
231
 
 
232
                /**
 
233
                 * Removes the installed maps on the currently traced root pane.
 
234
                 */
 
235
                private void untraceRootPane() {
 
236
                        if (this.tracedRootPane != null) {
 
237
                                removeUIActionMap(this.tracedRootPane, this.newActionMap);
 
238
                                removeUIInputMap(this.tracedRootPane, this.newInputMap);
 
239
                        }
 
240
                }
 
241
 
 
242
                @Override
 
243
                public void popupShown(PopupEvent event) {
 
244
                        PopupPanelManager msm = PopupPanelManager.defaultManager();
 
245
                        List<PopupPanelManager.PopupInfo> p = msm.getShownPath();
 
246
 
 
247
                        if (lastPathSelected.size() == 0 && p.size() != 0) {
 
248
                                // if it is the first popup panel to be shown, trace the root
 
249
                                // panel
 
250
                                traceRootPane(p);
 
251
                        }
 
252
 
 
253
                        lastPathSelected = p;
 
254
                }
 
255
 
 
256
                /**
 
257
                 * Installs the maps on the root pane of the originating component of
 
258
                 * the first popup panel of the specified sequence to trace the ESC key
 
259
                 * and dismiss the shown popup panels.
 
260
                 * 
 
261
                 * @param shownPath
 
262
                 *            Popup panel sequence.
 
263
                 */
 
264
                private void traceRootPane(List<PopupPanelManager.PopupInfo> shownPath) {
 
265
                        JComponent originator = shownPath.get(0).getPopupOriginator();
 
266
                        this.tracedRootPane = SwingUtilities.getRootPane(originator);
 
267
 
 
268
                        if (this.tracedRootPane != null) {
 
269
                                newInputMap = new ComponentInputMapUIResource(tracedRootPane);
 
270
                                newInputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
 
271
                                                "hidePopupPanel");
 
272
 
 
273
                                newActionMap = new ActionMapUIResource();
 
274
                                newActionMap.put("hidePopupPanel", new AbstractAction() {
 
275
                                        @Override
 
276
                                        public void actionPerformed(ActionEvent e) {
 
277
                                                // Hide the last sequence popup for every ESC keystroke.
 
278
                                                // There is special case - if the keytips are shown
 
279
                                                // for the *second* panel of the app menu popup panel,
 
280
                                                // do not dismiss the popup
 
281
                                                List<PopupPanelManager.PopupInfo> popups = PopupPanelManager
 
282
                                                                .defaultManager().getShownPath();
 
283
                                                if (popups.size() > 0) {
 
284
                                                        PopupPanelManager.PopupInfo lastPopup = popups
 
285
                                                                        .get(popups.size() - 1);
 
286
                                                        if (lastPopup.getPopupPanel() instanceof JRibbonApplicationMenuPopupPanel) {
 
287
                                                                JRibbonApplicationMenuPopupPanel appMenuPopupPanel = (JRibbonApplicationMenuPopupPanel) lastPopup
 
288
                                                                                .getPopupPanel();
 
289
                                                                KeyTipManager.KeyTipChain currentlyShownKeyTipChain = KeyTipManager
 
290
                                                                                .defaultManager()
 
291
                                                                                .getCurrentlyShownKeyTipChain();
 
292
                                                                if ((currentlyShownKeyTipChain != null)
 
293
                                                                                && (currentlyShownKeyTipChain.chainParentComponent == appMenuPopupPanel
 
294
                                                                                                .getPanelLevel2()))
 
295
                                                                        return;
 
296
                                                        }
 
297
                                                }
 
298
                                                PopupPanelManager.defaultManager().hideLastPopup();
 
299
                                        }
 
300
                                });
 
301
 
 
302
                                addUIInputMap(tracedRootPane, newInputMap);
 
303
                                addUIActionMap(tracedRootPane, newActionMap);
 
304
                        }
 
305
                }
 
306
 
 
307
                /**
 
308
                 * Adds the specified input map to the specified component.
 
309
                 * 
 
310
                 * @param c
 
311
                 *            Component.
 
312
                 * @param map
 
313
                 *            Input map to add.
 
314
                 */
 
315
                void addUIInputMap(JComponent c, InputMap map) {
 
316
                        InputMap lastNonUI = null;
 
317
                        InputMap parent = c.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
 
318
 
 
319
                        while (parent != null && !(parent instanceof UIResource)) {
 
320
                                lastNonUI = parent;
 
321
                                parent = parent.getParent();
 
322
                        }
 
323
 
 
324
                        if (lastNonUI == null) {
 
325
                                c.setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, map);
 
326
                        } else {
 
327
                                lastNonUI.setParent(map);
 
328
                        }
 
329
                        map.setParent(parent);
 
330
                }
 
331
 
 
332
                /**
 
333
                 * Adds the specified action map to the specified component.
 
334
                 * 
 
335
                 * @param c
 
336
                 *            Component.
 
337
                 * @param map
 
338
                 *            Action map to add.
 
339
                 */
 
340
                void addUIActionMap(JComponent c, ActionMap map) {
 
341
                        ActionMap lastNonUI = null;
 
342
                        ActionMap parent = c.getActionMap();
 
343
 
 
344
                        while (parent != null && !(parent instanceof UIResource)) {
 
345
                                lastNonUI = parent;
 
346
                                parent = parent.getParent();
 
347
                        }
 
348
 
 
349
                        if (lastNonUI == null) {
 
350
                                c.setActionMap(map);
 
351
                        } else {
 
352
                                lastNonUI.setParent(map);
 
353
                        }
 
354
                        map.setParent(parent);
 
355
                }
 
356
 
 
357
                /**
 
358
                 * Removes the specified input map from the specified component.
 
359
                 * 
 
360
                 * @param c
 
361
                 *            Component.
 
362
                 * @param map
 
363
                 *            Input map to remove.
 
364
                 */
 
365
                void removeUIInputMap(JComponent c, InputMap map) {
 
366
                        InputMap im = null;
 
367
                        InputMap parent = c.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
 
368
 
 
369
                        while (parent != null) {
 
370
                                if (parent == map) {
 
371
                                        if (im == null) {
 
372
                                                c.setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, map
 
373
                                                                .getParent());
 
374
                                        } else {
 
375
                                                im.setParent(map.getParent());
 
376
                                        }
 
377
                                        break;
 
378
                                }
 
379
                                im = parent;
 
380
                                parent = parent.getParent();
 
381
                        }
 
382
                }
 
383
 
 
384
                /**
 
385
                 * Removes the specified action map from the specified component.
 
386
                 * 
 
387
                 * @param c
 
388
                 *            Component.
 
389
                 * @param map
 
390
                 *            Action map to remove.
 
391
                 */
 
392
                void removeUIActionMap(JComponent c, ActionMap map) {
 
393
                        ActionMap im = null;
 
394
                        ActionMap parent = c.getActionMap();
 
395
 
 
396
                        while (parent != null) {
 
397
                                if (parent == map) {
 
398
                                        if (im == null) {
 
399
                                                c.setActionMap(map.getParent());
 
400
                                        } else {
 
401
                                                im.setParent(map.getParent());
 
402
                                        }
 
403
                                        break;
 
404
                                }
 
405
                                im = parent;
 
406
                                parent = parent.getParent();
 
407
                        }
 
408
                }
 
409
        }
 
410
 
 
411
        /**
 
412
         * This class is used to dismiss popup panels on the following events:
 
413
         * 
 
414
         * <ul>
 
415
         * <li>Mouse click outside any shown popup panel.</li>
 
416
         * <li>Closing, iconifying or deactivation of a top-level window.</li>
 
417
         * <li>Any change in the component hierarchy of a top-level window.</li>
 
418
         * </ul>
 
419
         * 
 
420
         * Only one top-level window is tracked at any time. The assumption is that
 
421
         * the {@link PopupPanelManager} only shows popup panels originating from
 
422
         * one top-level window.
 
423
         * 
 
424
         * @author Kirill Grouchnikov
 
425
         */
 
426
        protected static class WindowTracker implements
 
427
                        PopupPanelManager.PopupListener, AWTEventListener,
 
428
                        ComponentListener, WindowListener {
 
429
 
 
430
                /**
 
431
                 * The currently tracked window. It is the window of the originating
 
432
                 * component of the first popup panel in the currently shown sequence of
 
433
                 * {@link PopupPanelManager}.
 
434
                 */
 
435
                Window grabbedWindow;
 
436
 
 
437
                /**
 
438
                 * Last selected path in the {@link PopupPanelManager}.
 
439
                 */
 
440
                List<PopupPanelManager.PopupInfo> lastPathSelected;
 
441
 
 
442
                /**
 
443
                 * Creates the new window tracker.
 
444
                 */
 
445
                public WindowTracker() {
 
446
                        PopupPanelManager popupPanelManager = PopupPanelManager
 
447
                                        .defaultManager();
 
448
                        popupPanelManager.addPopupListener(this);
 
449
                        this.lastPathSelected = popupPanelManager.getShownPath();
 
450
                        if (this.lastPathSelected.size() != 0) {
 
451
                                grabWindow(this.lastPathSelected);
 
452
                        }
 
453
                }
 
454
 
 
455
                /**
 
456
                 * Grabs the window of the first popup panel in the specified popup
 
457
                 * panel sequence.
 
458
                 * 
 
459
                 * @param shownPath
 
460
                 *            Sequence of the currently shown popup panels.
 
461
                 */
 
462
                void grabWindow(List<PopupPanelManager.PopupInfo> shownPath) {
 
463
                        final Toolkit tk = Toolkit.getDefaultToolkit();
 
464
                        java.security.AccessController
 
465
                                        .doPrivileged(new java.security.PrivilegedAction() {
 
466
                                                @Override
 
467
                        public Object run() {
 
468
                                                        tk.addAWTEventListener(WindowTracker.this,
 
469
                                                                        AWTEvent.MOUSE_EVENT_MASK
 
470
                                                                                        | AWTEvent.MOUSE_MOTION_EVENT_MASK
 
471
                                                                                        | AWTEvent.MOUSE_WHEEL_EVENT_MASK
 
472
                                                                                        | AWTEvent.WINDOW_EVENT_MASK);
 
473
                                                        return null;
 
474
                                                }
 
475
                                        });
 
476
 
 
477
                        Component invoker = shownPath.get(0).getPopupOriginator();
 
478
                        grabbedWindow = invoker instanceof Window ? (Window) invoker
 
479
                                        : SwingUtilities.getWindowAncestor(invoker);
 
480
                        if (grabbedWindow != null) {
 
481
                                grabbedWindow.addComponentListener(this);
 
482
                                grabbedWindow.addWindowListener(this);
 
483
                        }
 
484
                }
 
485
 
 
486
                /**
 
487
                 * Ungrabs the currently tracked window.
 
488
                 */
 
489
                void ungrabWindow() {
 
490
                        final Toolkit tk = Toolkit.getDefaultToolkit();
 
491
                        // The grab should be removed
 
492
                        java.security.AccessController
 
493
                                        .doPrivileged(new java.security.PrivilegedAction() {
 
494
                                                @Override
 
495
                        public Object run() {
 
496
                                                        tk.removeAWTEventListener(WindowTracker.this);
 
497
                                                        return null;
 
498
                                                }
 
499
                                        });
 
500
                        if (grabbedWindow != null) {
 
501
                                grabbedWindow.removeComponentListener(this);
 
502
                                grabbedWindow.removeWindowListener(this);
 
503
                                grabbedWindow = null;
 
504
                        }
 
505
                }
 
506
 
 
507
                @Override
 
508
                public void popupShown(PopupEvent event) {
 
509
                        PopupPanelManager msm = PopupPanelManager.defaultManager();
 
510
                        List<PopupPanelManager.PopupInfo> p = msm.getShownPath();
 
511
 
 
512
                        if (lastPathSelected.size() == 0 && p.size() != 0) {
 
513
                                // if it is the first popup panel to be shown, grab its window
 
514
                                grabWindow(p);
 
515
                        }
 
516
 
 
517
                        lastPathSelected = p;
 
518
                }
 
519
 
 
520
                @Override
 
521
                public void popupHidden(PopupEvent event) {
 
522
                        PopupPanelManager msm = PopupPanelManager.defaultManager();
 
523
                        List<PopupPanelManager.PopupInfo> p = msm.getShownPath();
 
524
 
 
525
                        if (lastPathSelected.size() != 0 && p.size() == 0) {
 
526
                                // if it is the last popup panel to be hidden, ungrab its window
 
527
                                ungrabWindow();
 
528
                        }
 
529
 
 
530
                        lastPathSelected = p;
 
531
                }
 
532
 
 
533
                @Override
 
534
        public void eventDispatched(AWTEvent ev) {
 
535
                        if (!(ev instanceof MouseEvent)) {
 
536
                                // We are interested in MouseEvents only
 
537
                                return;
 
538
                        }
 
539
                        MouseEvent me = (MouseEvent) ev;
 
540
                        final Component src = me.getComponent();
 
541
                        JPopupPanel popupPanelParent = (JPopupPanel) SwingUtilities
 
542
                                        .getAncestorOfClass(JPopupPanel.class, src);
 
543
                        switch (me.getID()) {
 
544
                        case MouseEvent.MOUSE_PRESSED:
 
545
                                boolean wasCommandButtonPopupShowing = false;
 
546
                                if (src instanceof JCommandButton) {
 
547
                                        wasCommandButtonPopupShowing = ((JCommandButton) src)
 
548
                                                        .getPopupModel().isPopupShowing();
 
549
                                }
 
550
 
 
551
                                if (!wasCommandButtonPopupShowing && (popupPanelParent != null)) {
 
552
                                        // close all popups until this parent and return
 
553
                                        PopupPanelManager.defaultManager().hidePopups(
 
554
                                                        popupPanelParent);
 
555
                                        return;
 
556
                                }
 
557
                                if (src instanceof JRibbonTaskToggleButton) {
 
558
                                        JRibbon ribbon = (JRibbon) SwingUtilities
 
559
                                                        .getAncestorOfClass(JRibbon.class, src);
 
560
                                        if ((ribbon != null)
 
561
                                                        && FlamingoUtilities
 
562
                                                                        .isShowingMinimizedRibbonInPopup(ribbon)) {
 
563
                                                // This will be handled in the action listener installed
 
564
                                                // on ribbon task toggle buttons in BasicRibbonUI.
 
565
                                                // There the ribbon popup will be hidden.
 
566
                                                return;
 
567
                                        }
 
568
                                }
 
569
 
 
570
                                // if the popup of command button was showing, it will be hidden
 
571
                                // in BasicCommandButtonUI.processPopupAction() - via
 
572
                                // BasicCommandButtonUI.createPopupActionListener().
 
573
                                if (!wasCommandButtonPopupShowing) {
 
574
                                        // special case - ignore mouse press on an item in a combo popup
 
575
                                        if (SwingUtilities
 
576
                                                        .getAncestorOfClass(ComboPopup.class, src) == null) {
 
577
                                                PopupPanelManager.defaultManager().hidePopups(src);
 
578
                                        }
 
579
                                }
 
580
 
 
581
                                // pass the event so that it gets processed by the controls
 
582
                                break;
 
583
 
 
584
                        case MouseEvent.MOUSE_RELEASED:
 
585
                                // special case - mouse release on an item in a combo popup
 
586
                                if (SwingUtilities.getAncestorOfClass(ComboPopup.class, src) != null) {
 
587
                                        SwingUtilities.invokeLater(new Runnable() {
 
588
                                                @Override
 
589
                                                public void run() {
 
590
                                                        PopupPanelManager.defaultManager().hidePopups(src);
 
591
                                                }
 
592
                                        });
 
593
                                }
 
594
 
 
595
                                // pass the event so that it gets processed by the controls
 
596
                                break;
 
597
 
 
598
                        case MouseEvent.MOUSE_WHEEL:
 
599
                                if (popupPanelParent != null) {
 
600
                                        // close all popups until this parent and return
 
601
                                        PopupPanelManager.defaultManager().hidePopups(
 
602
                                                        popupPanelParent);
 
603
                                        return;
 
604
                                }
 
605
 
 
606
                                PopupPanelManager.defaultManager().hidePopups(src);
 
607
                                break;
 
608
                        }
 
609
                }
 
610
 
 
611
                /**
 
612
                 * Checks whether the specified component lies inside a
 
613
                 * {@link JPopupPanel}.
 
614
                 * 
 
615
                 * @param src
 
616
                 *            Component.
 
617
                 * @return <code>true</code> if the specified component lies inside a
 
618
                 *         {@link JPopupPanel}.
 
619
                 */
 
620
                boolean isInPopupPanel(Component src) {
 
621
                        for (Component c = src; c != null; c = c.getParent()) {
 
622
                                if (c instanceof Applet || c instanceof Window) {
 
623
                                        break;
 
624
                                } else if (c instanceof JPopupPanel) {
 
625
                                        return true;
 
626
                                }
 
627
                        }
 
628
                        return false;
 
629
                }
 
630
 
 
631
                @Override
 
632
        public void componentResized(ComponentEvent e) {
 
633
                        PopupPanelManager.defaultManager().hidePopups(null);
 
634
                }
 
635
 
 
636
                @Override
 
637
        public void componentMoved(ComponentEvent e) {
 
638
                        PopupPanelManager.defaultManager().hidePopups(null);
 
639
                }
 
640
 
 
641
                @Override
 
642
        public void componentShown(ComponentEvent e) {
 
643
                        PopupPanelManager.defaultManager().hidePopups(null);
 
644
                }
 
645
 
 
646
                @Override
 
647
        public void componentHidden(ComponentEvent e) {
 
648
                        PopupPanelManager.defaultManager().hidePopups(null);
 
649
                }
 
650
 
 
651
                @Override
 
652
        public void windowClosing(WindowEvent e) {
 
653
                        PopupPanelManager.defaultManager().hidePopups(null);
 
654
                }
 
655
 
 
656
                @Override
 
657
        public void windowClosed(WindowEvent e) {
 
658
                        PopupPanelManager.defaultManager().hidePopups(null);
 
659
                }
 
660
 
 
661
                @Override
 
662
        public void windowIconified(WindowEvent e) {
 
663
                        PopupPanelManager.defaultManager().hidePopups(null);
 
664
                }
 
665
 
 
666
                @Override
 
667
        public void windowDeactivated(WindowEvent e) {
 
668
                        PopupPanelManager.defaultManager().hidePopups(null);
 
669
                }
 
670
 
 
671
                @Override
 
672
        public void windowOpened(WindowEvent e) {
 
673
                }
 
674
 
 
675
                @Override
 
676
        public void windowDeiconified(WindowEvent e) {
 
677
                }
 
678
 
 
679
                @Override
 
680
        public void windowActivated(WindowEvent e) {
 
681
                }
 
682
        }
 
683
}