--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/tools/jconsole/MaximizableInternalFrame.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2006 Sun Microsystems, Inc. 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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();
+ }
+ }
+ }
+}