001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.gui.util;
020
021import icy.system.IcyExceptionHandler;
022import icy.system.SystemUtil;
023import icy.util.ReflectionUtil;
024
025import java.awt.Component;
026import java.lang.reflect.Method;
027
028import javax.swing.Popup;
029import javax.swing.PopupFactory;
030
031public class CustomPopupFactory extends PopupFactory
032{
033    // private static final Float OPAQUE = new Float(1.0F);
034
035    private final boolean macos;
036
037    private Method getPopupMethod;
038    private int heavy;
039
040    public CustomPopupFactory()
041    {
042        super();
043
044        getPopupMethod = null;
045        heavy = 0;
046
047        macos = SystemUtil.isMac();
048
049        if (macos)
050        {
051            try
052            {
053                // those methods should be protected...
054                getPopupMethod = ReflectionUtil.getMethod(PopupFactory.class, "getPopup", true, Component.class,
055                        Component.class, int.class, int.class, int.class);
056                heavy = ReflectionUtil.getField(PopupFactory.class, "HEAVY_WEIGHT_POPUP", true).getInt(null);
057            }
058            catch (Exception e)
059            {
060                IcyExceptionHandler.showErrorMessage(e, false);
061                getPopupMethod = null;
062                heavy = 0;
063            }
064        }
065    }
066
067    // private static Window getWindow(Component component)
068    // {
069    // Object obj;
070    // for (obj = component; !(obj instanceof Window) && obj != null; obj = ((Component)
071    // (obj)).getParent())
072    // ;
073    // return (Window) obj;
074    // }
075
076    @Override
077    public Popup getPopup(Component owner, Component contents, int x, int y)
078    {
079        if (contents == null)
080        {
081            throw new IllegalArgumentException("Popup.getPopup must be passed non-null contents");
082        }
083
084        if (macos && (getPopupMethod != null))
085        {
086            try
087            {
088                return (Popup) getPopupMethod.invoke(this, owner, contents, Integer.valueOf(x), Integer.valueOf(y),
089                        Integer.valueOf(heavy));
090            }
091            catch (Exception e)
092            {
093                // ignore
094            }
095
096            // popup = getPopup(owner, contents, x, y, HEAVY_WEIGHT_POPUP);
097            //
098            // // this is intended to force Heavy Weight popup component
099            // final Popup popup = super.getPopup(null, component1, x, y);
100            //
101            // final Window window = getWindow(component1);
102            //
103            // if (window == null)
104            // return popup;
105            // if (!(window instanceof RootPaneContainer))
106            // return popup;
107            //
108            // final JRootPane popupRootPane = ((RootPaneContainer) window).getRootPane();
109            // popupRootPane.putClientProperty("Window.alpha", OPAQUE);
110            // popupRootPane.putClientProperty("Window.shadow", Boolean.FALSE);
111            //
112            // return popup;
113        }
114
115        return super.getPopup(owner, contents, x, y);
116    }
117}