345 lines · 12.5 KB · Java
RawDownload
/* * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.tools.jconsole; import java.awt.*;import java.beans.*;import java.lang.reflect.*; import javax.swing.*;import javax.swing.border.*;import javax.swing.plaf.basic.*;  /** * This class is a temporary workaround for bug 4834918: * Win L&F: JInternalFrame should merge with JMenuBar when maximized. * It is not a general solution, but intended for use within the * limited scope of JConsole when running with XP/Vista styles. */@SuppressWarnings("serial")public class MaximizableInternalFrame extends JInternalFrame {    private boolean isXP;    private JFrame mainFrame;    private JMenuBar mainMenuBar;    private String mainTitle;    private JComponent titlePane;    private Border normalBorder;    private PropertyChangeListener pcl;     public MaximizableInternalFrame(String title, boolean resizable,                                    boolean closable, boolean maximizable,                                    boolean iconifiable) {        super(title, resizable, closable, maximizable, iconifiable);         init();    }     private void init() {        normalBorder = getBorder();        isXP = normalBorder.getClass().getName().endsWith("XPBorder");        if (isXP) {            setRootPaneCheckingEnabled(false);            titlePane = ((BasicInternalFrameUI)getUI()).getNorthPane();             if (pcl == null) {                pcl = new PropertyChangeListener() {                    public void propertyChange(PropertyChangeEvent ev) {                        String prop = ev.getPropertyName();                        if (prop.equals("icon") ||                            prop.equals("maximum") ||                            prop.equals("closed")) {                             updateFrame();                        }                    }                };                addPropertyChangeListener(pcl);            }        } else if (pcl != null) {            removePropertyChangeListener(pcl);            pcl = null;        }    }     private void updateFrame() {        JFrame mainFrame;        if (!isXP || (mainFrame = getMainFrame()) == null) {            return;        }        JMenuBar menuBar = getMainMenuBar();        BasicInternalFrameUI ui = (BasicInternalFrameUI)getUI();        if (isMaximum() && !isIcon() && !isClosed()) {            if (ui.getNorthPane() != null) {                // Merge title bar into menu bar                mainTitle = mainFrame.getTitle();                mainFrame.setTitle(mainTitle + " - " + getTitle());                if (menuBar != null) {                    // Move buttons to menu bar                    updateButtonStates();                    menuBar.add(Box.createGlue());                    for (Component c : titlePane.getComponents()) {                        if (c instanceof JButton) {                            menuBar.add(c);                        } else if (c instanceof JLabel) {                            // This is the system menu icon                            menuBar.add(Box.createHorizontalStrut(3), 0);                            menuBar.add(c, 1);                            menuBar.add(Box.createHorizontalStrut(3), 2);                        }                    }                    ui.setNorthPane(null);                    setBorder(null);                }            }        } else {            if (ui.getNorthPane() == null) {                // Restore title bar                mainFrame.setTitle(mainTitle);                if (menuBar != null) {                    // Move buttons back to title bar                    for (Component c : menuBar.getComponents()) {                        if (c instanceof JButton || c instanceof JLabel) {                            titlePane.add(c);                        } else if (c instanceof Box.Filler) {                            menuBar.remove(c);                        }                    }                    menuBar.repaint();                    updateButtonStates();                    ui.setNorthPane(titlePane);                    setBorder(normalBorder);                }            }        }    }     public void updateUI() {        boolean isMax = (isXP && getBorder() == null);        if (isMax) {            try {                setMaximum(false);            } catch (PropertyVetoException ex) { }        }        super.updateUI();        init();        if (isMax) {            try {                setMaximum(true);            } catch (PropertyVetoException ex) { }        }    }     private JFrame getMainFrame() {        if (mainFrame == null) {            JDesktopPane desktop = getDesktopPane();            if (desktop != null) {                mainFrame = (JFrame)SwingUtilities.getWindowAncestor(desktop);            }        }        return mainFrame;    }     private JMenuBar getMainMenuBar() {        if (mainMenuBar == null) {            JFrame mainFrame = getMainFrame();            if (mainFrame != null) {                mainMenuBar = mainFrame.getJMenuBar();                if (mainMenuBar != null &&                    !(mainMenuBar.getLayout() instanceof FixedMenuBarLayout)) {                     mainMenuBar.setLayout(new FixedMenuBarLayout(mainMenuBar,                                                            BoxLayout.X_AXIS));                }            }        }        return mainMenuBar;    }     public void setTitle(String title) {        if (isXP && isMaximum()) {            if (getMainFrame() != null) {                getMainFrame().setTitle(mainTitle + " - " + title);            }        }        super.setTitle(title);    }      private class FixedMenuBarLayout extends BoxLayout {        public FixedMenuBarLayout(Container target, int axis) {            super(target, axis);        }         public void layoutContainer(Container target) {            super.layoutContainer(target);             for (Component c : target.getComponents()) {                if (c instanceof JButton) {                    int y = (target.getHeight() - c.getHeight()) / 2;                    c.setLocation(c.getX(), Math.max(2, y));                }            }        }    }      // The rest of this class is messy and should not be relied upon. It    // uses reflection to access private, undocumented, and unsupported    // classes and fields.    //    // Install icon wrappers to display MDI icons when the buttons    // are in the menubar.    //    // Please note that this will very likely fail in a future version    // of Swing, but at least it should fail silently.    //    private static Object WP_MINBUTTON, WP_RESTOREBUTTON, WP_CLOSEBUTTON,                          WP_MDIMINBUTTON, WP_MDIRESTOREBUTTON, WP_MDICLOSEBUTTON;    static {        if (JConsole.IS_WIN) {            try {                Class Part =                    Class.forName("com.sun.java.swing.plaf.windows.TMSchema$Part");                if (Part != null) {                    WP_MINBUTTON        = Part.getField("WP_MINBUTTON").get(null);                    WP_RESTOREBUTTON    = Part.getField("WP_RESTOREBUTTON").get(null);                    WP_CLOSEBUTTON      = Part.getField("WP_CLOSEBUTTON").get(null);                    WP_MDIMINBUTTON     = Part.getField("WP_MDIMINBUTTON").get(null);                    WP_MDIRESTOREBUTTON = Part.getField("WP_MDIRESTOREBUTTON").get(null);                    WP_MDICLOSEBUTTON   = Part.getField("WP_MDICLOSEBUTTON").get(null);                }                 for (String str : new String[] { "maximize", "minimize",                                                 "iconify", "close" }) {                    String key = "InternalFrame." + str + "Icon";                    UIManager.put(key,                                  new MDIButtonIcon(UIManager.getIcon(key)));                }            } catch (ClassNotFoundException ex) {                if (JConsole.debug) {                    ex.printStackTrace();                }            } catch (NoSuchFieldException ex) {                if (JConsole.debug) {                    ex.printStackTrace();                }            } catch (IllegalAccessException ex) {                if (JConsole.debug) {                    ex.printStackTrace();                }            }        }    }      // A wrapper class for the title pane button icons.    // This code should really go in the WindowsIconsFactory class.    private static class MDIButtonIcon implements Icon {        Icon windowsIcon;        Field part;         MDIButtonIcon(Icon icon) {            windowsIcon = icon;             if (WP_MINBUTTON != null) {                try {                    part = windowsIcon.getClass().getDeclaredField("part");                    part.setAccessible(true);                } catch (NoSuchFieldException ex) {                    if (JConsole.debug) {                        ex.printStackTrace();                    }                }            }        }         public void paintIcon(Component c, Graphics g, int x, int y) {            if (part != null) {                try {                    Object v = part.get(windowsIcon);                     if (c.getParent() instanceof JMenuBar) {                        // Use MDI icons                        if (v == WP_MINBUTTON) {                            part.set(windowsIcon, WP_MDIMINBUTTON);                        } else if (v == WP_RESTOREBUTTON) {                            part.set(windowsIcon, WP_MDIRESTOREBUTTON);                        } else if (v == WP_CLOSEBUTTON) {                            part.set(windowsIcon, WP_MDICLOSEBUTTON);                        }                    } else {                        // Use regular icons                        if (v == WP_MDIMINBUTTON) {                            part.set(windowsIcon, WP_MINBUTTON);                        } else if (v == WP_MDIRESTOREBUTTON) {                            part.set(windowsIcon, WP_RESTOREBUTTON);                        } else if (v == WP_MDICLOSEBUTTON) {                            part.set(windowsIcon, WP_CLOSEBUTTON);                        }                    }                } catch (IllegalAccessException ex) {                    if (JConsole.debug) {                        ex.printStackTrace();                    }                }            }            windowsIcon.paintIcon(c, g, x, y);        }         public int getIconWidth(){            return windowsIcon.getIconWidth();        }         public int getIconHeight() {            return windowsIcon.getIconHeight();        }    }      // Use reflection to invoke protected methods in BasicInternalFrameTitlePane    private Method setButtonIcons;    private Method enableActions;     private void updateButtonStates() {        try {            if (setButtonIcons == null) {                Class<? extends JComponent> cls = titlePane.getClass();                Class<?> superCls = cls.getSuperclass();                setButtonIcons = cls.getDeclaredMethod("setButtonIcons");                enableActions  = superCls.getDeclaredMethod("enableActions");                setButtonIcons.setAccessible(true);                enableActions.setAccessible(true);            }            setButtonIcons.invoke(titlePane);            enableActions.invoke(titlePane);        } catch (Exception ex) {            if (JConsole.debug) {                ex.printStackTrace();            }        }    }}