/******************************************************************************* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tiny Look and Feel * * (C) Copyright 2003 - 2007 Hans Bickel * * For * licensing information and credits, please refer to the * comment in file * de.muntjak.tinylookandfeel.TinyLookAndFeel * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ package de.muntjak.tinylookandfeel; import java.awt.Component; import java.awt.Container; import java.awt.Dialog; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; import java.awt.LayoutManager; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Locale; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JRootPane; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.plaf.UIResource; import de.muntjak.tinylookandfeel.controlpanel.ControlPanel; /* * @(#)TinyTitlePane.java 1.10 01/12/03 Copyright 2002 Sun Microsystems, Inc. * All rights reserved. SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license * terms. */ /* * Class that manages a JLF awt.Window-descendant class's title bar. <p> 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.10 12/03/01 @author Terry Kellerman * @since 1.4 */ /** * TinyTitlePane * * @version 1.0 * @author Hans Bickel */ @SuppressWarnings ( { "all" } ) public class TinyTitlePane extends JComponent { private static final int IMAGE_HEIGHT = 16; private static final int IMAGE_WIDTH = 16; private static TinyWindowButtonUI iconButtonUI; private static TinyWindowButtonUI maxButtonUI; private static TinyWindowButtonUI closeButtonUI; /** * PropertyChangeListener added to the JRootPane. */ private PropertyChangeListener propertyChangeListener; /** * JMenuBar, typically renders the system menu items. */ private JMenuBar menuBar; /** * Action used to close the Window. */ private Action closeAction; /** * Action used to iconify the Frame. */ private Action iconifyAction; /** * Action to restore the Frame size. */ private Action restoreAction; /** * Action to restore the Frame size. */ private Action maximizeAction; /** * Button used to maximize or restore the Frame. */ 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; /** * Listens for changes in the state of the Window listener to update the state * of the widgets. */ private WindowListener windowListener; private ComponentListener windowMoveListener; /** * Window we're currently in. */ private Window window; /** * JRootPane rendering for. */ private JRootPane rootPane; /** * Room remaining in title for bumps. */ private int buttonsWidth; /** * Buffered Frame.state property. As state isn't bound, this is kept to * determine when to avoid updating widgets. */ private int state; /** * RootPaneUI that created us. */ private TinyRootPaneUI rootPaneUI; public TinyTitlePane ( JRootPane root, TinyRootPaneUI ui ) { rootPane = root; rootPaneUI = ui; state = -1; installSubcomponents (); installDefaults (); setLayout ( createLayout () ); } /** * Uninstalls the necessary state. */ private void uninstall () { uninstallListeners (); window = null; removeAll (); } /** * Installs the necessary listeners. */ private void installListeners () { if ( window != null ) { windowListener = createWindowListener (); window.addWindowListener ( windowListener ); propertyChangeListener = createWindowPropertyChangeListener (); window.addPropertyChangeListener ( propertyChangeListener ); windowMoveListener = new WindowMoveListener (); window.addComponentListener ( windowMoveListener ); } } /** * Uninstalls the necessary listeners. */ private void uninstallListeners () { if ( window != null ) { window.removeWindowListener ( windowListener ); window.removePropertyChangeListener ( propertyChangeListener ); window.removeComponentListener ( windowMoveListener ); } } /** * Returns the <code>WindowListener</code> to add to the <code>Window</code>. */ private WindowListener createWindowListener () { return new WindowHandler (); } /** * Returns the <code>PropertyChangeListener</code> to install on the * <code>Window</code>. */ private PropertyChangeListener createWindowPropertyChangeListener () { return new PropertyChangeHandler (); } /** * Returns the <code>JRootPane</code> this was created for. */ public JRootPane getRootPane () { return rootPane; } /** * Returns the decoration style of the <code>JRootPane</code>. */ private int getWindowDecorationStyle () { return getRootPane ().getWindowDecorationStyle (); } public void addNotify () { 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 (); } } public void removeNotify () { super.removeNotify (); uninstallListeners (); window = null; } /** * Adds any sub-Components contained in the <code>TinyTitlePane</code>. */ private void installSubcomponents () { if ( getWindowDecorationStyle () == JRootPane.FRAME ) { createActions (); menuBar = createMenuBar (); add ( menuBar ); createButtons (); add ( iconifyButton ); add ( toggleButton ); add ( closeButton ); iconifyButton.putClientProperty ( "externalFrameButton", Boolean.TRUE ); toggleButton.putClientProperty ( "externalFrameButton", Boolean.TRUE ); closeButton.putClientProperty ( "externalFrameButton", Boolean.TRUE ); } else if ( getWindowDecorationStyle () != JRootPane.NONE ) { createActions (); createButtons (); add ( closeButton ); closeButton.putClientProperty ( "externalFrameButton", Boolean.FALSE ); } } /** * Installs the fonts and necessary properties on the TinyTitlePane. */ private void installDefaults () { setFont ( UIManager.getFont ( "InternalFrame.titleFont", getLocale () ) ); } /** * Uninstalls any previously installed UI values. */ private void uninstallDefaults () { } /** * Returns the <code>JMenuBar</code> displaying the appropriate system menu * items. */ protected JMenuBar createMenuBar () { menuBar = new SystemMenuBar (); menuBar.setFocusable ( false ); menuBar.setBorderPainted ( true ); menuBar.add ( createMenu () ); return menuBar; } /** * Closes the Window. */ private void close () { Window window = getWindow (); if ( window != null ) { window.dispatchEvent ( new WindowEvent ( window, WindowEvent.WINDOW_CLOSING ) ); } } /** * Iconifies the Frame. */ private void iconify () { Frame frame = getFrame (); if ( frame != null ) { frame.setExtendedState ( frame.getExtendedState () | Frame.ICONIFIED ); } } /** * Maximizes the Frame. */ private void maximize () { Frame frame = getFrame (); if ( frame != null ) { setMaximizeBounds ( frame ); frame .setExtendedState ( frame.getExtendedState () | Frame.MAXIMIZED_BOTH ); } } protected void setMaximizeBounds ( Frame frame ) { if ( frame.getMaximizedBounds () != null ) return; Insets screenInsets = Toolkit.getDefaultToolkit ().getScreenInsets ( frame.getGraphicsConfiguration () ); Dimension screenSize = Toolkit.getDefaultToolkit ().getScreenSize (); // spare any Systemmenus or Taskbars or ??... int x = screenInsets.top; int y = screenInsets.left; int w = screenSize.width - x - screenInsets.right; int h = screenSize.height - y - screenInsets.bottom; Rectangle maxBounds = new Rectangle ( x, y, w, h ); frame.setMaximizedBounds ( maxBounds ); } /** * Restores the Frame size. */ private void restore () { Frame frame = getFrame (); if ( frame == null ) { return; } if ( ( frame.getExtendedState () & Frame.ICONIFIED ) == Frame.ICONIFIED ) { frame.setExtendedState ( state & ~Frame.ICONIFIED ); } else { frame.setExtendedState ( state & ~Frame.MAXIMIZED_BOTH ); } } /** * Create the <code>Action</code>s that get associated with the buttons and * menu items. */ private void createActions () { closeAction = new CloseAction (); iconifyAction = new IconifyAction (); restoreAction = new RestoreAction (); maximizeAction = new MaximizeAction (); } /** * Returns the <code>JMenu</code> displaying the appropriate menu items for * manipulating the Frame. */ private JMenu createMenu () { JMenu menu = new JMenu ( "" ); if ( getWindowDecorationStyle () == JRootPane.FRAME ) { addMenuItems ( menu ); // we use this property to prevent the Menu from drawing rollovers menu.putClientProperty ( "isSystemMenu", Boolean.TRUE ); } return menu; } /** * Adds the necessary <code>JMenuItem</code>s to the passed in menu. */ private void addMenuItems ( JMenu menu ) { Locale locale = getRootPane ().getLocale (); JMenuItem mi = menu.add ( restoreAction ); int mnemonic = getInt ( "MetalTitlePane.restoreMnemonic", -1 ); if ( mnemonic != -1 ) { mi.setMnemonic ( mnemonic ); } mi = menu.add ( iconifyAction ); mnemonic = getInt ( "MetalTitlePane.iconifyMnemonic", -1 ); if ( mnemonic != -1 ) { mi.setMnemonic ( mnemonic ); } if ( Toolkit.getDefaultToolkit ().isFrameStateSupported ( Frame.MAXIMIZED_BOTH ) ) { mi = menu.add ( maximizeAction ); mnemonic = getInt ( "MetalTitlePane.maximizeMnemonic", -1 ); if ( mnemonic != -1 ) { mi.setMnemonic ( mnemonic ); } } menu.addSeparator (); mi = menu.add ( closeAction ); mnemonic = getInt ( "MetalTitlePane.closeMnemonic", -1 ); if ( mnemonic != -1 ) { mi.setMnemonic ( mnemonic ); } } /** * Creates the buttons of the title pane and initializes their actions. */ protected void createButtons () { if ( iconButtonUI == null ) { iconButtonUI = TinyWindowButtonUI .createButtonUIForType ( TinyWindowButtonUI.MINIMIZE ); maxButtonUI = TinyWindowButtonUI .createButtonUIForType ( TinyWindowButtonUI.MAXIMIZE ); closeButtonUI = TinyWindowButtonUI .createButtonUIForType ( TinyWindowButtonUI.CLOSE ); } iconifyButton = new SpecialUIButton ( iconButtonUI ); iconifyButton.setAction ( iconifyAction ); iconifyButton.setRolloverEnabled ( true ); toggleButton = new SpecialUIButton ( maxButtonUI ); toggleButton.setAction ( maximizeAction ); toggleButton.setRolloverEnabled ( true ); closeButton = new SpecialUIButton ( closeButtonUI ); closeButton.setAction ( closeAction ); closeButton.setRolloverEnabled ( true ); closeButton.getAccessibleContext ().setAccessibleName ( "Close" ); iconifyButton.getAccessibleContext ().setAccessibleName ( "Iconify" ); toggleButton.getAccessibleContext ().setAccessibleName ( "Maximize" ); if ( TinyLookAndFeel.controlPanelInstantiated ) { ControlPanel.setWindowButtons ( new JButton [] { iconifyButton, toggleButton, closeButton } ); } } /** * Returns the <code>LayoutManager</code> that should be installed on the * <code>TinyTitlePane</code>. */ private LayoutManager createLayout () { return new TitlePaneLayout (); } /** * Updates state dependant upon the Window's active state. */ private void setActive ( boolean isActive ) { if ( getWindowDecorationStyle () == JRootPane.FRAME ) { Boolean activeB = isActive ? Boolean.TRUE : Boolean.FALSE; iconifyButton.putClientProperty ( "paintActive", activeB ); closeButton.putClientProperty ( "paintActive", activeB ); toggleButton.putClientProperty ( "paintActive", activeB ); iconifyButton.setEnabled ( isActive ); closeButton.setEnabled ( isActive ); toggleButton.setEnabled ( isActive ); } // Repaint the whole thing as the Borders that are used have // different colors for active vs inactive getRootPane ().repaint (); } /** * Sets the state of the Window. */ private void setState ( int state ) { setState ( state, false ); } /** * Sets the state of the window. If <code>updateRegardless</code> is true * and the state has not changed, this will update anyway. */ private void setState ( int state, boolean updateRegardless ) { 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 ) == Frame.MAXIMIZED_BOTH && ( rootPane.getBorder () == null || ( rootPane.getBorder () instanceof UIResource ) ) && frame.isShowing () ) { // rootPane.setBorder(null); } else if ( ( state & Frame.MAXIMIZED_BOTH ) != Frame.MAXIMIZED_BOTH ) { // This is a croak, if state becomes bound, this can // be nuked. // rootPaneUI.installBorder(rootPane); } if ( frame.isResizable () ) { if ( ( state & Frame.MAXIMIZED_VERT ) == Frame.MAXIMIZED_VERT || ( state & Frame.MAXIMIZED_HORIZ ) == Frame.MAXIMIZED_HORIZ ) { updateToggleButton ( restoreAction ); maximizeAction.setEnabled ( false ); restoreAction.setEnabled ( true ); } else { updateToggleButton ( maximizeAction ); 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; } } /** * Updates the toggle button to contain the Icon <code>icon</code>, and * Action <code>action</code>. */ private void updateToggleButton ( Action action ) { toggleButton.setAction ( action ); toggleButton.setText ( null ); } /** * Returns the Frame rendering in. This will return null if the * <code>JRootPane</code> is not contained in a <code>Frame</code>. */ private Frame getFrame () { Window window = getWindow (); if ( window instanceof Frame ) { return ( Frame ) window; } return null; } /** * Returns the <code>Window</code> the <code>JRootPane</code> is contained * in. This will return null if there is no parent ancestor of the * <code>JRootPane</code>. */ private Window getWindow () { return window; } /** * Returns the String to display as the title. */ private String getTitle () { Window w = getWindow (); if ( w instanceof Frame ) { return ( ( Frame ) w ).getTitle (); } else if ( w instanceof Dialog ) { return ( ( Dialog ) w ).getTitle (); } return null; } public boolean isSelected () { Window window = getWindow (); return ( window == null ) ? true : window.isActive (); } public boolean isFrameMaximized () { Frame frame = getFrame (); if ( frame != null ) { return ( ( frame.getExtendedState () & Frame.MAXIMIZED_BOTH ) == Frame.MAXIMIZED_BOTH ); } return false; } /** * Renders the TitlePane ( => paints the title). */ public void paintComponent ( Graphics g ) { // As state isn't bound, we need a convenience place to check // if it has changed. if ( getFrame () != null ) { setState ( getFrame ().getExtendedState () ); } Window window = getWindow (); boolean leftToRight = ( window == null ) ? getRootPane () .getComponentOrientation ().isLeftToRight () : window .getComponentOrientation ().isLeftToRight (); boolean isSelected = ( window == null ) ? true : window.isActive (); int width = getWidth (); int height = getHeight (); int xOffset = leftToRight ? 5 : width - 5; if ( getWindowDecorationStyle () == JRootPane.FRAME ) { xOffset += leftToRight ? IMAGE_WIDTH + 5 : -IMAGE_WIDTH - 5; } String theTitle = getTitle (); if ( theTitle != null ) { Font f = UIManager.getFont ( "InternalFrame.normalTitleFont" ); FontMetrics fm = g.getFontMetrics (); 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 = clippedText ( theTitle, fm, titleW ); } else { titleW = xOffset - rect.x - rect.width - 4; theTitle = clippedText ( theTitle, fm, titleW ); xOffset -= SwingUtilities.computeStringWidth ( fm, theTitle ); } int titleLength = SwingUtilities.computeStringWidth ( fm, theTitle ); if ( isSelected ) { g.setColor ( Theme.frameTitleColor [ Theme.style ].getColor () ); g.drawString ( theTitle, xOffset, yOffset ); } else { // for an inactive window g.setColor ( Theme.frameTitleDisabledColor [ Theme.style ].getColor () ); g.drawString ( theTitle, xOffset, yOffset ); } xOffset += leftToRight ? titleLength + 5 : -5; } } /** * Convenience method to clip the passed in text to the specified size. */ private String clippedText ( String text, FontMetrics fm, int availTextWidth ) { if ( ( text == null ) || ( text.equals ( "" ) ) ) { return ""; } int textWidth = SwingUtilities.computeStringWidth ( fm, text ); String clipString = "..."; if ( textWidth > availTextWidth ) { int totalWidth = SwingUtilities.computeStringWidth ( fm, clipString ); int nChars; for ( nChars = 0 ; nChars < text.length () ; nChars++ ) { totalWidth += fm.charWidth ( text.charAt ( nChars ) ); if ( totalWidth > availTextWidth ) { break; } } text = text.substring ( 0, nChars ) + clipString; } return text; } private int getInt ( Object key, int defaultValue ) { Object value = UIManager.get ( key ); if ( value instanceof Integer ) { return ( ( Integer ) value ).intValue (); } if ( value instanceof String ) { try { return Integer.parseInt ( ( String ) value ); } catch ( NumberFormatException nfe ) { } } return defaultValue; } /** * Actions used to <code>close</code> the <code>Window</code>. */ private class CloseAction extends AbstractAction { public CloseAction () { super ( UIManager.getString ( "MetalTitlePane.closeTitle", getLocale () ) ); } public void actionPerformed ( ActionEvent e ) { close (); } } /** * Actions used to <code>iconfiy</code> the <code>Frame</code>. */ private class IconifyAction extends AbstractAction { public IconifyAction () { super ( UIManager .getString ( "MetalTitlePane.iconifyTitle", getLocale () ) ); } public void actionPerformed ( ActionEvent e ) { iconify (); } } /** * Actions used to <code>restore</code> the <code>Frame</code>. */ private class RestoreAction extends AbstractAction { public RestoreAction () { super ( UIManager .getString ( "MetalTitlePane.restoreTitle", getLocale () ) ); } public void actionPerformed ( ActionEvent e ) { restore (); } } /** * Actions used to <code>restore</code> the <code>Frame</code>. */ private class MaximizeAction extends AbstractAction { public MaximizeAction () { super ( UIManager.getString ( "MetalTitlePane.maximizeTitle", getLocale () ) ); } public void actionPerformed ( ActionEvent e ) { maximize (); } } /** * Class responsible for drawing the system menu. Looks up the image to draw * from the Frame associated with the <code>JRootPane</code>. */ private class SystemMenuBar extends JMenuBar { public void paint ( Graphics g ) { Frame frame = getFrame (); Image image = ( frame != null ) ? frame.getIconImage () : null; if ( image != null ) { g.drawImage ( image, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null ); } else { Icon icon = UIManager.getIcon ( "InternalFrame.icon" ); if ( icon != null ) { icon.paintIcon ( this, g, 0, 0 ); } } } public Dimension getMinimumSize () { return getPreferredSize (); } public Dimension getPreferredSize () { Icon icon = UIManager.getIcon ( "InternalFrame.icon" ); if ( icon != null ) { return new Dimension ( icon.getIconWidth (), icon.getIconHeight () ); } Dimension size = super.getPreferredSize (); return new Dimension ( Math.max ( IMAGE_WIDTH, size.width ), Math.max ( size.height, IMAGE_HEIGHT ) ); } } /** * This inner class is marked "public" due to a compiler bug. This * class should be treated as a "protected" inner class. Instantiate * it only within subclasses of <Foo>. */ private class TitlePaneLayout implements LayoutManager { public void addLayoutComponent ( String name, Component c ) { } public void removeLayoutComponent ( Component c ) { } public Dimension preferredLayoutSize ( Container c ) { return new Dimension ( TinyLookAndFeel.MINIMUM_FRAME_WIDTH, computeHeight () ); } public Dimension minimumLayoutSize ( Container c ) { return preferredLayoutSize ( c ); } private int computeHeight () { if ( getFrame () instanceof JFrame ) { setMaximizeBounds ( getFrame () ); return Theme.frameTitleHeight [ Theme.derivedStyle [ Theme.style ] ]; } else { return Theme.frameInternalTitleHeight [ Theme.derivedStyle [ Theme.style ] ]; } } public void layoutContainer ( Container c ) { if ( getWindowDecorationStyle () == JRootPane.NONE ) { buttonsWidth = 0; return; } boolean leftToRight = ( window == null ) ? getRootPane () .getComponentOrientation ().isLeftToRight () : window .getComponentOrientation ().isLeftToRight (); int w = getWidth (); int x; int spacing; int buttonHeight; int buttonWidth; if ( closeButton != null ) { buttonHeight = closeButton.getPreferredSize ().height; buttonWidth = closeButton.getPreferredSize ().width; } else { buttonHeight = IMAGE_HEIGHT; buttonWidth = IMAGE_WIDTH; } int y = ( getHeight () - buttonHeight ) / 2 + 1; if ( Theme.derivedStyle [ Theme.style ] == Theme.W99_STYLE ) { y += 1; } // assumes all buttons have the same dimensions, // these dimensions include the borders x = leftToRight ? w : 0; spacing = 5; x = leftToRight ? spacing : w - buttonWidth - spacing; if ( menuBar != null ) { // this is a JFrame menuBar.setBounds ( x, y, buttonWidth, buttonHeight ); } x = leftToRight ? w : 0; spacing = 2; x += leftToRight ? -spacing - buttonWidth : spacing; if ( closeButton != null ) { closeButton.setBounds ( x, y, buttonWidth, buttonHeight ); } if ( !leftToRight ) x += buttonWidth; if ( Toolkit.getDefaultToolkit ().isFrameStateSupported ( Frame.MAXIMIZED_BOTH ) ) { if ( toggleButton.getParent () != null ) { x += leftToRight ? -spacing - buttonWidth : spacing; toggleButton.setBounds ( x, y, buttonWidth, buttonHeight ); if ( !leftToRight ) { x += buttonWidth; } } } if ( iconifyButton != null && iconifyButton.getParent () != null ) { x += leftToRight ? -spacing - buttonWidth : spacing; iconifyButton.setBounds ( x, y, buttonWidth, buttonHeight ); if ( !leftToRight ) { x += buttonWidth; } } buttonsWidth = leftToRight ? w - x : x; } } /** * PropertyChangeListener installed on the Window. Updates the necessary state * as the state of the Window changes. */ private class PropertyChangeHandler implements PropertyChangeListener { public void propertyChange ( PropertyChangeEvent pce ) { String name = pce.getPropertyName (); // Frame.state isn't currently bound. if ( "resizable".equals ( name ) || "state".equals ( name ) ) { Frame frame = getFrame (); if ( frame != null ) { setState ( frame.getExtendedState (), true ); } if ( "resizable".equals ( name ) ) { getRootPane ().repaint (); } } else if ( "title".equals ( name ) ) { repaint (); } else if ( "componentOrientation".equals ( name ) ) { revalidate (); repaint (); } } } /** * WindowListener installed on the Window, updates the state as necessary. */ private class WindowHandler extends WindowAdapter { public void windowActivated ( WindowEvent ev ) { setActive ( true ); } public void windowDeactivated ( WindowEvent ev ) { setActive ( false ); } } class WindowMoveListener extends ComponentAdapter { public void componentMoved ( ComponentEvent e ) { if ( getWindowDecorationStyle () == JRootPane.NONE ) return; // paint the non-opaque upper edges Window w = getWindow (); if ( !w.isShowing () ) return; w.repaint ( 0, 0, w.getWidth (), 5 ); } public void componentResized ( ComponentEvent e ) { if ( getWindowDecorationStyle () == JRootPane.NONE ) return; // paint the non-opaque upper edges Window w = getWindow (); if ( !w.isShowing () ) return; w.repaint ( 0, 0, w.getWidth (), 5 ); } } }