FileDocCategorySizeDatePackage
MetalTitlePane.javaAPI DocJava SE 6 API32525Tue Jun 10 00:26:50 BST 2008javax.swing.plaf.metal

MetalTitlePane

public class MetalTitlePane extends JComponent
Class that manages a JLF awt.Window-descendant class's title bar.

This class assumes it will be created with a particular window decoration style, and that if the style changes, a new one will be created.

version
1.22 07/17/06
author
Terry Kellerman
since
1.4

Fields Summary
private static final Border
handyEmptyBorder
private static final int
IMAGE_HEIGHT
private static final int
IMAGE_WIDTH
private PropertyChangeListener
propertyChangeListener
PropertyChangeListener added to the JRootPane.
private JMenuBar
menuBar
JMenuBar, typically renders the system menu items.
private Action
closeAction
Action used to close the Window.
private Action
iconifyAction
Action used to iconify the Frame.
private Action
restoreAction
Action to restore the Frame size.
private Action
maximizeAction
Action to restore the Frame size.
private JButton
toggleButton
Button used to maximize or restore the Frame.
private JButton
iconifyButton
Button used to maximize or restore the Frame.
private JButton
closeButton
Button used to maximize or restore the Frame.
private Icon
maximizeIcon
Icon used for toggleButton when window is normal size.
private Icon
minimizeIcon
Icon used for toggleButton when window is maximized.
private Image
systemIcon
Image used for the system menu icon
private WindowListener
windowListener
Listens for changes in the state of the Window listener to update the state of the widgets.
private Window
window
Window we're currently in.
private JRootPane
rootPane
JRootPane rendering for.
private int
buttonsWidth
Room remaining in title for bumps.
private int
state
Buffered Frame.state property. As state isn't bound, this is kept to determine when to avoid updating widgets.
private MetalRootPaneUI
rootPaneUI
MetalRootPaneUI that created us.
private Color
inactiveBackground
private Color
inactiveForeground
private Color
inactiveShadow
private Color
activeBumpsHighlight
private Color
activeBumpsShadow
private Color
activeBackground
private Color
activeForeground
private Color
activeShadow
private MetalBumps
activeBumps
private MetalBumps
inactiveBumps
Constructors Summary
public MetalTitlePane(JRootPane root, MetalRootPaneUI ui)



         
        this.rootPane = root;
        rootPaneUI = ui;

        state = -1;

        installSubcomponents();
        determineColors();
        installDefaults();

        setLayout(createLayout());
    
Methods Summary
private voidaddMenuItems(javax.swing.JMenu menu)
Adds the necessary JMenuItems to the passed in menu.

        Locale locale = getRootPane().getLocale();
        JMenuItem mi = menu.add(restoreAction);
        int mnemonic = MetalUtils.getInt("MetalTitlePane.restoreMnemonic", -1);

        if (mnemonic != -1) {
            mi.setMnemonic(mnemonic);
        }

        mi = menu.add(iconifyAction);
        mnemonic = MetalUtils.getInt("MetalTitlePane.iconifyMnemonic", -1);
        if (mnemonic != -1) {
            mi.setMnemonic(mnemonic);
        }

        if (Toolkit.getDefaultToolkit().isFrameStateSupported(
                Frame.MAXIMIZED_BOTH)) {
            mi = menu.add(maximizeAction);
            mnemonic =
                MetalUtils.getInt("MetalTitlePane.maximizeMnemonic", -1);
            if (mnemonic != -1) {
                mi.setMnemonic(mnemonic);
            }
        }

        menu.add(new JSeparator());

        mi = menu.add(closeAction);
        mnemonic = MetalUtils.getInt("MetalTitlePane.closeMnemonic", -1);
        if (mnemonic != -1) {
            mi.setMnemonic(mnemonic);
        }
    
public voidaddNotify()

        super.addNotify();

        uninstallListeners();

        window = SwingUtilities.getWindowAncestor(this);
        if (window != null) {
            if (window instanceof Frame) {
                setState(((Frame)window).getExtendedState());
            }
            else {
                setState(0);
            }
            setActive(window.isActive());
            installListeners();
            updateSystemIcon();
        }
    
private voidclose()
Closes the Window.

        Window window = getWindow();

        if (window != null) {
            window.dispatchEvent(new WindowEvent(
                                 window, WindowEvent.WINDOW_CLOSING));
        }
    
private voidcreateActions()
Create the Actions that get associated with the buttons and menu items.

        closeAction = new CloseAction();
        if (getWindowDecorationStyle() == JRootPane.FRAME) {
            iconifyAction = new IconifyAction();
            restoreAction = new RestoreAction();
            maximizeAction = new MaximizeAction();
        }
    
private voidcreateButtons()
Creates the Buttons that will be placed on the TitlePane.

        closeButton = createTitleButton();
        closeButton.setAction(closeAction);
        closeButton.setText(null);
        closeButton.putClientProperty("paintActive", Boolean.TRUE);
        closeButton.setBorder(handyEmptyBorder);
        closeButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, 
                                      "Close");
        closeButton.setIcon(UIManager.getIcon("InternalFrame.closeIcon"));

        if (getWindowDecorationStyle() == JRootPane.FRAME) {
            maximizeIcon = UIManager.getIcon("InternalFrame.maximizeIcon");
            minimizeIcon = UIManager.getIcon("InternalFrame.minimizeIcon");

            iconifyButton = createTitleButton();
            iconifyButton.setAction(iconifyAction);
            iconifyButton.setText(null);
            iconifyButton.putClientProperty("paintActive", Boolean.TRUE);
            iconifyButton.setBorder(handyEmptyBorder);
            iconifyButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, 
                                            "Iconify");
            iconifyButton.setIcon(UIManager.getIcon("InternalFrame.iconifyIcon"));

            toggleButton = createTitleButton();
            toggleButton.setAction(restoreAction);
            toggleButton.putClientProperty("paintActive", Boolean.TRUE);
            toggleButton.setBorder(handyEmptyBorder);
            toggleButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, 
                                           "Maximize");
            toggleButton.setIcon(maximizeIcon);
        }
    
private java.awt.LayoutManagercreateLayout()
Returns the LayoutManager that should be installed on the MetalTitlePane.

        return new TitlePaneLayout();
    
private javax.swing.JMenucreateMenu()
Returns the JMenu displaying the appropriate menu items for manipulating the Frame.

        JMenu menu = new JMenu("");
        if (getWindowDecorationStyle() == JRootPane.FRAME) {
            addMenuItems(menu);
        }
        return menu;
    
protected javax.swing.JMenuBarcreateMenuBar()
Returns the JMenuBar displaying the appropriate system menu items.

        menuBar = new SystemMenuBar();
        menuBar.setFocusable(false);
        menuBar.setBorderPainted(true);
        menuBar.add(createMenu());
        return menuBar;
    
private javax.swing.JButtoncreateTitleButton()
Returns a JButton appropriate for placement on the TitlePane.

        JButton button = new JButton();

        button.setFocusPainted(false);
        button.setFocusable(false);
        button.setOpaque(true);
        return button;
    
private java.awt.event.WindowListenercreateWindowListener()
Returns the WindowListener to add to the Window.

        return new WindowHandler();
    
private java.beans.PropertyChangeListenercreateWindowPropertyChangeListener()
Returns the PropertyChangeListener to install on the Window.

        return new PropertyChangeHandler();
    
private voiddetermineColors()
Determines the Colors to draw with.

        switch (getWindowDecorationStyle()) {
        case JRootPane.FRAME:
            activeBackground = UIManager.getColor("activeCaption");
            activeForeground = UIManager.getColor("activeCaptionText");
            activeShadow = UIManager.getColor("activeCaptionBorder");
            break;
        case JRootPane.ERROR_DIALOG:
            activeBackground = UIManager.getColor(
                "OptionPane.errorDialog.titlePane.background");
            activeForeground = UIManager.getColor(
                "OptionPane.errorDialog.titlePane.foreground");
            activeShadow = UIManager.getColor(
                "OptionPane.errorDialog.titlePane.shadow");
            break;
        case JRootPane.QUESTION_DIALOG:
        case JRootPane.COLOR_CHOOSER_DIALOG:
        case JRootPane.FILE_CHOOSER_DIALOG:
            activeBackground = UIManager.getColor(
                "OptionPane.questionDialog.titlePane.background");
            activeForeground = UIManager.getColor(
                "OptionPane.questionDialog.titlePane.foreground");
            activeShadow = UIManager.getColor(
                "OptionPane.questionDialog.titlePane.shadow");
            break;
        case JRootPane.WARNING_DIALOG:
            activeBackground = UIManager.getColor(
                "OptionPane.warningDialog.titlePane.background");
            activeForeground = UIManager.getColor(
                "OptionPane.warningDialog.titlePane.foreground");
            activeShadow = UIManager.getColor(
                "OptionPane.warningDialog.titlePane.shadow");
            break;
        case JRootPane.PLAIN_DIALOG:
        case JRootPane.INFORMATION_DIALOG:
        default:
            activeBackground = UIManager.getColor("activeCaption");
            activeForeground = UIManager.getColor("activeCaptionText");
            activeShadow = UIManager.getColor("activeCaptionBorder");
            break;
        }
        activeBumps.setBumpColors(activeBumpsHighlight, activeBumpsShadow,
                                  activeBackground);
    
private java.awt.FramegetFrame()
Returns the Frame rendering in. This will return null if the JRootPane is not contained in a Frame.

        Window window = getWindow();

        if (window instanceof Frame) {
            return (Frame)window;
        }
        return null;
    
public javax.swing.JRootPanegetRootPane()
Returns the JRootPane this was created for.

        return rootPane;
    
private java.lang.StringgetTitle()
Returns the String to display as the title.

        Window w = getWindow();

        if (w instanceof Frame) {
            return ((Frame)w).getTitle();
        }
        else if (w instanceof Dialog) {
            return ((Dialog)w).getTitle();
        }
        return null;
    
private java.awt.WindowgetWindow()
Returns the Window the JRootPane is contained in. This will return null if there is no parent ancestor of the JRootPane.

        return window;
    
private intgetWindowDecorationStyle()
Returns the decoration style of the JRootPane.

        return getRootPane().getWindowDecorationStyle();
    
private voidiconify()
Iconifies the Frame.

        Frame frame = getFrame();
        if (frame != null) {
            frame.setExtendedState(state | Frame.ICONIFIED);
        }
    
private voidinstallDefaults()
Installs the fonts and necessary properties on the MetalTitlePane.

        setFont(UIManager.getFont("InternalFrame.titleFont", getLocale()));
    
private voidinstallListeners()
Installs the necessary listeners.

        if (window != null) {
            windowListener = createWindowListener();
            window.addWindowListener(windowListener);
            propertyChangeListener = createWindowPropertyChangeListener();
            window.addPropertyChangeListener(propertyChangeListener);
        }
    
private voidinstallSubcomponents()
Adds any sub-Components contained in the MetalTitlePane.

        int decorationStyle = getWindowDecorationStyle();
        if (decorationStyle == JRootPane.FRAME) {
            createActions();
            menuBar = createMenuBar();
            add(menuBar);
            createButtons();
            add(iconifyButton);
            add(toggleButton);
            add(closeButton);
        } else if (decorationStyle == JRootPane.PLAIN_DIALOG ||
                decorationStyle == JRootPane.INFORMATION_DIALOG ||
                decorationStyle == JRootPane.ERROR_DIALOG ||
                decorationStyle == JRootPane.COLOR_CHOOSER_DIALOG ||
                decorationStyle == JRootPane.FILE_CHOOSER_DIALOG ||
                decorationStyle == JRootPane.QUESTION_DIALOG ||
                decorationStyle == JRootPane.WARNING_DIALOG) {
            createActions();
            createButtons();
            add(closeButton);
        }
    
private voidmaximize()
Maximizes the Frame.

        Frame frame = getFrame();
        if (frame != null) {
            frame.setExtendedState(state | Frame.MAXIMIZED_BOTH);
        }
    
public voidpaintComponent(java.awt.Graphics g)
Renders the TitlePane.

        // As state isn't bound, we need a convenience place to check
        // if it has changed. Changing the state typically changes the
        if (getFrame() != null) {
            setState(getFrame().getExtendedState());
        }
        JRootPane rootPane = getRootPane();
        Window window = getWindow();
        boolean leftToRight = (window == null) ?
                               rootPane.getComponentOrientation().isLeftToRight() :
                               window.getComponentOrientation().isLeftToRight();
        boolean isSelected = (window == null) ? true : window.isActive();
        int width = getWidth();
        int height = getHeight();

        Color background;
        Color foreground;
        Color darkShadow;

        MetalBumps bumps;

        if (isSelected) {
            background = activeBackground;
            foreground = activeForeground;
            darkShadow = activeShadow;
            bumps = activeBumps;
        } else {
            background = inactiveBackground;
            foreground = inactiveForeground;
            darkShadow = inactiveShadow;
            bumps = inactiveBumps;
        }

        g.setColor(background);
        g.fillRect(0, 0, width, height);

        g.setColor( darkShadow );
        g.drawLine ( 0, height - 1, width, height -1);
        g.drawLine ( 0, 0, 0 ,0);    
        g.drawLine ( width - 1, 0 , width -1, 0);

        int xOffset = leftToRight ? 5 : width - 5;

        if (getWindowDecorationStyle() == JRootPane.FRAME) {
            xOffset += leftToRight ? IMAGE_WIDTH + 5 : - IMAGE_WIDTH - 5;
        }
        
        String theTitle = getTitle();
        if (theTitle != null) {
            FontMetrics fm = SwingUtilities2.getFontMetrics(rootPane, g);

            g.setColor(foreground);

            int yOffset = ( (height - fm.getHeight() ) / 2 ) + fm.getAscent();

            Rectangle rect = new Rectangle(0, 0, 0, 0);
            if (iconifyButton != null && iconifyButton.getParent() != null) {
                rect = iconifyButton.getBounds();
            }
            int titleW;

            if( leftToRight ) {
                if (rect.x == 0) {
                    rect.x = window.getWidth() - window.getInsets().right-2;
                }
                titleW = rect.x - xOffset - 4;
                theTitle = SwingUtilities2.clipStringIfNecessary(
                                rootPane, fm, theTitle, titleW);
            } else {
                titleW = xOffset - rect.x - rect.width - 4;
                theTitle = SwingUtilities2.clipStringIfNecessary(
                                rootPane, fm, theTitle, titleW);
                xOffset -= SwingUtilities2.stringWidth(rootPane, fm,
                                                       theTitle);
            }
            int titleLength = SwingUtilities2.stringWidth(rootPane, fm,
                                                          theTitle);
            SwingUtilities2.drawString(rootPane, g, theTitle, xOffset,
                                       yOffset );
            xOffset += leftToRight ? titleLength + 5  : -5;
        }
  
        int bumpXOffset;
        int bumpLength;
        if( leftToRight ) {
            bumpLength = width - buttonsWidth - xOffset - 5;
            bumpXOffset = xOffset;
        } else {
            bumpLength = xOffset - buttonsWidth - 5;
            bumpXOffset = buttonsWidth + 5;
        }
        int bumpYOffset = 3;
        int bumpHeight = getHeight() - (2 * bumpYOffset);        
        bumps.setBumpArea( bumpLength, bumpHeight );
        bumps.paintIcon(this, g, bumpXOffset, bumpYOffset);
    
public voidremoveNotify()

        super.removeNotify();

        uninstallListeners();
        window = null;
    
private voidrestore()
Restores the Frame size.

        Frame frame = getFrame();

        if (frame == null) {
            return;
        }

        if ((state & Frame.ICONIFIED) != 0) {
            frame.setExtendedState(state & ~Frame.ICONIFIED);
        } else {
            frame.setExtendedState(state & ~Frame.MAXIMIZED_BOTH);
        }
    
private voidsetActive(boolean isActive)
Updates state dependant upon the Window's active state.

        Boolean activeB = isActive ? Boolean.TRUE : Boolean.FALSE;

        closeButton.putClientProperty("paintActive", activeB);
        if (getWindowDecorationStyle() == JRootPane.FRAME) {
            iconifyButton.putClientProperty("paintActive", activeB);
            toggleButton.putClientProperty("paintActive", activeB);
        }
        // Repaint the whole thing as the Borders that are used have
        // different colors for active vs inactive
        getRootPane().repaint();
    
private voidsetState(int state)
Sets the state of the Window.

        setState(state, false);
    
private voidsetState(int state, boolean updateRegardless)
Sets the state of the window. If updateRegardless is true and the state has not changed, this will update anyway.

        Window w = getWindow();

        if (w != null && getWindowDecorationStyle() == JRootPane.FRAME) {
            if (this.state == state && !updateRegardless) {
                return;
            }
            Frame frame = getFrame();

            if (frame != null) {
                JRootPane rootPane = getRootPane();

                if (((state & Frame.MAXIMIZED_BOTH) != 0) &&
                        (rootPane.getBorder() == null ||
                        (rootPane.getBorder() instanceof UIResource)) &&
                            frame.isShowing()) {
                    rootPane.setBorder(null);
                }
                else if ((state & Frame.MAXIMIZED_BOTH) == 0) {
                    // This is a croak, if state becomes bound, this can
                    // be nuked.
                    rootPaneUI.installBorder(rootPane);
                }
                if (frame.isResizable()) {
                    if ((state & Frame.MAXIMIZED_BOTH) != 0) {
                        updateToggleButton(restoreAction, minimizeIcon);
                        maximizeAction.setEnabled(false);
                        restoreAction.setEnabled(true);
                    }
                    else {
                        updateToggleButton(maximizeAction, maximizeIcon);
                        maximizeAction.setEnabled(true);
                        restoreAction.setEnabled(false);
                    }
                    if (toggleButton.getParent() == null ||
                        iconifyButton.getParent() == null) {
                        add(toggleButton);
                        add(iconifyButton);
                        revalidate();
                        repaint();
                    }
                    toggleButton.setText(null);
                }
                else {
                    maximizeAction.setEnabled(false);
                    restoreAction.setEnabled(false);
                    if (toggleButton.getParent() != null) {
                        remove(toggleButton);
                        revalidate();
                        repaint();
                    }
                }
            }
            else {
                // Not contained in a Frame
                maximizeAction.setEnabled(false);
                restoreAction.setEnabled(false);
                iconifyAction.setEnabled(false);
                remove(toggleButton);
                remove(iconifyButton);
                revalidate();
                repaint();
            }
            closeAction.setEnabled(true);
            this.state = state;
        }
    
private voiduninstall()
Uninstalls the necessary state.

        uninstallListeners();
        window = null;
        removeAll();
    
private voiduninstallDefaults()
Uninstalls any previously installed UI values.

    
private voiduninstallListeners()
Uninstalls the necessary listeners.

        if (window != null) {
            window.removeWindowListener(windowListener);
            window.removePropertyChangeListener(propertyChangeListener);
        }
    
private voidupdateSystemIcon()
Update the image used for the system icon

        Window window = getWindow();
        if (window == null) {
            systemIcon = null;
            return;
        }
        java.util.List<Image> icons = window.getIconImages();
        assert icons != null;

        if (icons.size() == 0) {
            systemIcon = null;
        }
        else if (icons.size() == 1) {
            systemIcon = icons.get(0);
        }
        else {
            systemIcon = SunToolkit.getScaledIconImage(icons,
                                                       IMAGE_WIDTH,
                                                       IMAGE_HEIGHT);
        } 
    
private voidupdateToggleButton(javax.swing.Action action, javax.swing.Icon icon)
Updates the toggle button to contain the Icon icon, and Action action.

        toggleButton.setAction(action);
        toggleButton.setIcon(icon);
        toggleButton.setText(null);