1 /*
2  * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.apple.laf;
27 
28 import java.awt.*;
29 import javax.swing.*;
30 
31 import sun.lwawt.macosx.CPlatformWindow;
32 import sun.swing.SwingAccessor;
33 
34 class ScreenPopupFactory extends PopupFactory {
35     static final Float TRANSLUCENT = 248f/255f;
36     static final Float OPAQUE = 1.0f;
37 
38     boolean fIsActive = true;
39 
40     // Only popups generated with the Aqua LaF turned on will be translucent with shadows
setActive(final boolean b)41     void setActive(final boolean b) {
42         fIsActive = b;
43     }
44 
getWindow(final Component c)45     private static Window getWindow(final Component c) {
46         Component w = c;
47         while(!(w instanceof Window) && (w!=null)) {
48             w = w.getParent();
49         }
50         return (Window)w;
51     }
52 
getPopup(final Component comp, final Component invoker, final int x, final int y)53     public Popup getPopup(final Component comp, final Component invoker, final int x, final int y) {
54         if (invoker == null) throw new IllegalArgumentException("Popup.getPopup must be passed non-null contents");
55 
56         final Popup popup;
57         if (fIsActive) {
58             popup = SwingAccessor.getPopupFactoryAccessor()
59                     .getHeavyWeightPopup(this, comp, invoker, x, y);
60         } else {
61             popup = super.getPopup(comp, invoker, x, y);
62         }
63 
64         // Make the popup semi-translucent if it is a heavy weight
65         // see <rdar://problem/3547670> JPopupMenus have incorrect background
66         final Window w = getWindow(invoker);
67         if (w == null) return popup;
68 
69         if (!(w instanceof RootPaneContainer)) return popup;
70         final JRootPane popupRootPane = ((RootPaneContainer)w).getRootPane();
71 
72         // we need to set every time, because PopupFactory caches the heavy weight
73         // TODO: CPlatformWindow constants?
74         if (fIsActive) {
75             popupRootPane.putClientProperty(CPlatformWindow.WINDOW_ALPHA, TRANSLUCENT);
76             popupRootPane.putClientProperty(CPlatformWindow.WINDOW_SHADOW, Boolean.TRUE);
77             popupRootPane.putClientProperty(CPlatformWindow.WINDOW_FADE_DELEGATE, invoker);
78 
79             w.setBackground(UIManager.getColor("PopupMenu.translucentBackground"));
80             popupRootPane.putClientProperty(CPlatformWindow.WINDOW_DRAGGABLE_BACKGROUND, Boolean.FALSE);
81             SwingUtilities.invokeLater(new Runnable() {
82                 public void run() {
83                     popupRootPane.putClientProperty(CPlatformWindow.WINDOW_SHADOW_REVALIDATE_NOW, Double.valueOf(Math.random()));
84                 }
85             });
86         } else {
87             popupRootPane.putClientProperty(CPlatformWindow.WINDOW_ALPHA, OPAQUE);
88             popupRootPane.putClientProperty(CPlatformWindow.WINDOW_SHADOW, Boolean.FALSE);
89         }
90 
91         return popup;
92     }
93 }
94