Save This Page
Home » openjdk-7 » javax » swing » plaf » metal » [javadoc | source]
    1   /*
    2    * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.swing.plaf.metal;
   27   
   28   import sun.swing.SwingUtilities2;
   29   import sun.awt.SunToolkit;
   30   import java.awt;
   31   import java.awt.event;
   32   import java.beans;
   33   import javax.swing;
   34   import javax.swing.border;
   35   import javax.swing.event.InternalFrameEvent;
   36   import javax.swing.plaf;
   37   import javax.swing.plaf.basic;
   38   import java.util.Locale;
   39   import javax.accessibility;
   40   
   41   
   42   /**
   43    * Class that manages a JLF awt.Window-descendant class's title bar.
   44    * <p>
   45    * This class assumes it will be created with a particular window
   46    * decoration style, and that if the style changes, a new one will
   47    * be created.
   48    *
   49    * @author Terry Kellerman
   50    * @since 1.4
   51    */
   52   class MetalTitlePane extends JComponent {
   53       private static final Border handyEmptyBorder = new EmptyBorder(0,0,0,0);
   54       private static final int IMAGE_HEIGHT = 16;
   55       private static final int IMAGE_WIDTH = 16;
   56   
   57       /**
   58        * PropertyChangeListener added to the JRootPane.
   59        */
   60       private PropertyChangeListener propertyChangeListener;
   61   
   62       /**
   63        * JMenuBar, typically renders the system menu items.
   64        */
   65       private JMenuBar menuBar;
   66       /**
   67        * Action used to close the Window.
   68        */
   69       private Action closeAction;
   70   
   71       /**
   72        * Action used to iconify the Frame.
   73        */
   74       private Action iconifyAction;
   75   
   76       /**
   77        * Action to restore the Frame size.
   78        */
   79       private Action restoreAction;
   80   
   81       /**
   82        * Action to restore the Frame size.
   83        */
   84       private Action maximizeAction;
   85   
   86       /**
   87        * Button used to maximize or restore the Frame.
   88        */
   89       private JButton toggleButton;
   90   
   91       /**
   92        * Button used to maximize or restore the Frame.
   93        */
   94       private JButton iconifyButton;
   95   
   96       /**
   97        * Button used to maximize or restore the Frame.
   98        */
   99       private JButton closeButton;
  100   
  101       /**
  102        * Icon used for toggleButton when window is normal size.
  103        */
  104       private Icon maximizeIcon;
  105   
  106       /**
  107        * Icon used for toggleButton when window is maximized.
  108        */
  109       private Icon minimizeIcon;
  110   
  111       /**
  112        * Image used for the system menu icon
  113        */
  114       private Image systemIcon;
  115   
  116       /**
  117        * Listens for changes in the state of the Window listener to update
  118        * the state of the widgets.
  119        */
  120       private WindowListener windowListener;
  121   
  122       /**
  123        * Window we're currently in.
  124        */
  125       private Window window;
  126   
  127       /**
  128        * JRootPane rendering for.
  129        */
  130       private JRootPane rootPane;
  131   
  132       /**
  133        * Room remaining in title for bumps.
  134        */
  135       private int buttonsWidth;
  136   
  137       /**
  138        * Buffered Frame.state property. As state isn't bound, this is kept
  139        * to determine when to avoid updating widgets.
  140        */
  141       private int state;
  142   
  143       /**
  144        * MetalRootPaneUI that created us.
  145        */
  146       private MetalRootPaneUI rootPaneUI;
  147   
  148   
  149       // Colors
  150       private Color inactiveBackground = UIManager.getColor("inactiveCaption");
  151       private Color inactiveForeground = UIManager.getColor("inactiveCaptionText");
  152       private Color inactiveShadow = UIManager.getColor("inactiveCaptionBorder");
  153       private Color activeBumpsHighlight = MetalLookAndFeel.getPrimaryControlHighlight();
  154       private Color activeBumpsShadow = MetalLookAndFeel.getPrimaryControlDarkShadow();
  155       private Color activeBackground = null;
  156       private Color activeForeground = null;
  157       private Color activeShadow = null;
  158   
  159       // Bumps
  160       private MetalBumps activeBumps
  161           = new MetalBumps( 0, 0,
  162                             activeBumpsHighlight,
  163                             activeBumpsShadow,
  164                             MetalLookAndFeel.getPrimaryControl() );
  165       private MetalBumps inactiveBumps
  166           = new MetalBumps( 0, 0,
  167                             MetalLookAndFeel.getControlHighlight(),
  168                             MetalLookAndFeel.getControlDarkShadow(),
  169                             MetalLookAndFeel.getControl() );
  170   
  171   
  172       public MetalTitlePane(JRootPane root, MetalRootPaneUI ui) {
  173           this.rootPane = root;
  174           rootPaneUI = ui;
  175   
  176           state = -1;
  177   
  178           installSubcomponents();
  179           determineColors();
  180           installDefaults();
  181   
  182           setLayout(createLayout());
  183       }
  184   
  185       /**
  186        * Uninstalls the necessary state.
  187        */
  188       private void uninstall() {
  189           uninstallListeners();
  190           window = null;
  191           removeAll();
  192       }
  193   
  194       /**
  195        * Installs the necessary listeners.
  196        */
  197       private void installListeners() {
  198           if (window != null) {
  199               windowListener = createWindowListener();
  200               window.addWindowListener(windowListener);
  201               propertyChangeListener = createWindowPropertyChangeListener();
  202               window.addPropertyChangeListener(propertyChangeListener);
  203           }
  204       }
  205   
  206       /**
  207        * Uninstalls the necessary listeners.
  208        */
  209       private void uninstallListeners() {
  210           if (window != null) {
  211               window.removeWindowListener(windowListener);
  212               window.removePropertyChangeListener(propertyChangeListener);
  213           }
  214       }
  215   
  216       /**
  217        * Returns the <code>WindowListener</code> to add to the
  218        * <code>Window</code>.
  219        */
  220       private WindowListener createWindowListener() {
  221           return new WindowHandler();
  222       }
  223   
  224       /**
  225        * Returns the <code>PropertyChangeListener</code> to install on
  226        * the <code>Window</code>.
  227        */
  228       private PropertyChangeListener createWindowPropertyChangeListener() {
  229           return new PropertyChangeHandler();
  230       }
  231   
  232       /**
  233        * Returns the <code>JRootPane</code> this was created for.
  234        */
  235       public JRootPane getRootPane() {
  236           return rootPane;
  237       }
  238   
  239       /**
  240        * Returns the decoration style of the <code>JRootPane</code>.
  241        */
  242       private int getWindowDecorationStyle() {
  243           return getRootPane().getWindowDecorationStyle();
  244       }
  245   
  246       public void addNotify() {
  247           super.addNotify();
  248   
  249           uninstallListeners();
  250   
  251           window = SwingUtilities.getWindowAncestor(this);
  252           if (window != null) {
  253               if (window instanceof Frame) {
  254                   setState(((Frame)window).getExtendedState());
  255               }
  256               else {
  257                   setState(0);
  258               }
  259               setActive(window.isActive());
  260               installListeners();
  261               updateSystemIcon();
  262           }
  263       }
  264   
  265       public void removeNotify() {
  266           super.removeNotify();
  267   
  268           uninstallListeners();
  269           window = null;
  270       }
  271   
  272       /**
  273        * Adds any sub-Components contained in the <code>MetalTitlePane</code>.
  274        */
  275       private void installSubcomponents() {
  276           int decorationStyle = getWindowDecorationStyle();
  277           if (decorationStyle == JRootPane.FRAME) {
  278               createActions();
  279               menuBar = createMenuBar();
  280               add(menuBar);
  281               createButtons();
  282               add(iconifyButton);
  283               add(toggleButton);
  284               add(closeButton);
  285           } else if (decorationStyle == JRootPane.PLAIN_DIALOG ||
  286                   decorationStyle == JRootPane.INFORMATION_DIALOG ||
  287                   decorationStyle == JRootPane.ERROR_DIALOG ||
  288                   decorationStyle == JRootPane.COLOR_CHOOSER_DIALOG ||
  289                   decorationStyle == JRootPane.FILE_CHOOSER_DIALOG ||
  290                   decorationStyle == JRootPane.QUESTION_DIALOG ||
  291                   decorationStyle == JRootPane.WARNING_DIALOG) {
  292               createActions();
  293               createButtons();
  294               add(closeButton);
  295           }
  296       }
  297   
  298       /**
  299        * Determines the Colors to draw with.
  300        */
  301       private void determineColors() {
  302           switch (getWindowDecorationStyle()) {
  303           case JRootPane.FRAME:
  304               activeBackground = UIManager.getColor("activeCaption");
  305               activeForeground = UIManager.getColor("activeCaptionText");
  306               activeShadow = UIManager.getColor("activeCaptionBorder");
  307               break;
  308           case JRootPane.ERROR_DIALOG:
  309               activeBackground = UIManager.getColor(
  310                   "OptionPane.errorDialog.titlePane.background");
  311               activeForeground = UIManager.getColor(
  312                   "OptionPane.errorDialog.titlePane.foreground");
  313               activeShadow = UIManager.getColor(
  314                   "OptionPane.errorDialog.titlePane.shadow");
  315               break;
  316           case JRootPane.QUESTION_DIALOG:
  317           case JRootPane.COLOR_CHOOSER_DIALOG:
  318           case JRootPane.FILE_CHOOSER_DIALOG:
  319               activeBackground = UIManager.getColor(
  320                   "OptionPane.questionDialog.titlePane.background");
  321               activeForeground = UIManager.getColor(
  322                   "OptionPane.questionDialog.titlePane.foreground");
  323               activeShadow = UIManager.getColor(
  324                   "OptionPane.questionDialog.titlePane.shadow");
  325               break;
  326           case JRootPane.WARNING_DIALOG:
  327               activeBackground = UIManager.getColor(
  328                   "OptionPane.warningDialog.titlePane.background");
  329               activeForeground = UIManager.getColor(
  330                   "OptionPane.warningDialog.titlePane.foreground");
  331               activeShadow = UIManager.getColor(
  332                   "OptionPane.warningDialog.titlePane.shadow");
  333               break;
  334           case JRootPane.PLAIN_DIALOG:
  335           case JRootPane.INFORMATION_DIALOG:
  336           default:
  337               activeBackground = UIManager.getColor("activeCaption");
  338               activeForeground = UIManager.getColor("activeCaptionText");
  339               activeShadow = UIManager.getColor("activeCaptionBorder");
  340               break;
  341           }
  342           activeBumps.setBumpColors(activeBumpsHighlight, activeBumpsShadow,
  343                                     activeBackground);
  344       }
  345   
  346       /**
  347        * Installs the fonts and necessary properties on the MetalTitlePane.
  348        */
  349       private void installDefaults() {
  350           setFont(UIManager.getFont("InternalFrame.titleFont", getLocale()));
  351       }
  352   
  353       /**
  354        * Uninstalls any previously installed UI values.
  355        */
  356       private void uninstallDefaults() {
  357       }
  358   
  359       /**
  360        * Returns the <code>JMenuBar</code> displaying the appropriate
  361        * system menu items.
  362        */
  363       protected JMenuBar createMenuBar() {
  364           menuBar = new SystemMenuBar();
  365           menuBar.setFocusable(false);
  366           menuBar.setBorderPainted(true);
  367           menuBar.add(createMenu());
  368           return menuBar;
  369       }
  370   
  371       /**
  372        * Closes the Window.
  373        */
  374       private void close() {
  375           Window window = getWindow();
  376   
  377           if (window != null) {
  378               window.dispatchEvent(new WindowEvent(
  379                                    window, WindowEvent.WINDOW_CLOSING));
  380           }
  381       }
  382   
  383       /**
  384        * Iconifies the Frame.
  385        */
  386       private void iconify() {
  387           Frame frame = getFrame();
  388           if (frame != null) {
  389               frame.setExtendedState(state | Frame.ICONIFIED);
  390           }
  391       }
  392   
  393       /**
  394        * Maximizes the Frame.
  395        */
  396       private void maximize() {
  397           Frame frame = getFrame();
  398           if (frame != null) {
  399               frame.setExtendedState(state | Frame.MAXIMIZED_BOTH);
  400           }
  401       }
  402   
  403       /**
  404        * Restores the Frame size.
  405        */
  406       private void restore() {
  407           Frame frame = getFrame();
  408   
  409           if (frame == null) {
  410               return;
  411           }
  412   
  413           if ((state & Frame.ICONIFIED) != 0) {
  414               frame.setExtendedState(state & ~Frame.ICONIFIED);
  415           } else {
  416               frame.setExtendedState(state & ~Frame.MAXIMIZED_BOTH);
  417           }
  418       }
  419   
  420       /**
  421        * Create the <code>Action</code>s that get associated with the
  422        * buttons and menu items.
  423        */
  424       private void createActions() {
  425           closeAction = new CloseAction();
  426           if (getWindowDecorationStyle() == JRootPane.FRAME) {
  427               iconifyAction = new IconifyAction();
  428               restoreAction = new RestoreAction();
  429               maximizeAction = new MaximizeAction();
  430           }
  431       }
  432   
  433       /**
  434        * Returns the <code>JMenu</code> displaying the appropriate menu items
  435        * for manipulating the Frame.
  436        */
  437       private JMenu createMenu() {
  438           JMenu menu = new JMenu("");
  439           if (getWindowDecorationStyle() == JRootPane.FRAME) {
  440               addMenuItems(menu);
  441           }
  442           return menu;
  443       }
  444   
  445       /**
  446        * Adds the necessary <code>JMenuItem</code>s to the passed in menu.
  447        */
  448       private void addMenuItems(JMenu menu) {
  449           Locale locale = getRootPane().getLocale();
  450           JMenuItem mi = menu.add(restoreAction);
  451           int mnemonic = MetalUtils.getInt("MetalTitlePane.restoreMnemonic", -1);
  452   
  453           if (mnemonic != -1) {
  454               mi.setMnemonic(mnemonic);
  455           }
  456   
  457           mi = menu.add(iconifyAction);
  458           mnemonic = MetalUtils.getInt("MetalTitlePane.iconifyMnemonic", -1);
  459           if (mnemonic != -1) {
  460               mi.setMnemonic(mnemonic);
  461           }
  462   
  463           if (Toolkit.getDefaultToolkit().isFrameStateSupported(
  464                   Frame.MAXIMIZED_BOTH)) {
  465               mi = menu.add(maximizeAction);
  466               mnemonic =
  467                   MetalUtils.getInt("MetalTitlePane.maximizeMnemonic", -1);
  468               if (mnemonic != -1) {
  469                   mi.setMnemonic(mnemonic);
  470               }
  471           }
  472   
  473           menu.add(new JSeparator());
  474   
  475           mi = menu.add(closeAction);
  476           mnemonic = MetalUtils.getInt("MetalTitlePane.closeMnemonic", -1);
  477           if (mnemonic != -1) {
  478               mi.setMnemonic(mnemonic);
  479           }
  480       }
  481   
  482       /**
  483        * Returns a <code>JButton</code> appropriate for placement on the
  484        * TitlePane.
  485        */
  486       private JButton createTitleButton() {
  487           JButton button = new JButton();
  488   
  489           button.setFocusPainted(false);
  490           button.setFocusable(false);
  491           button.setOpaque(true);
  492           return button;
  493       }
  494   
  495       /**
  496        * Creates the Buttons that will be placed on the TitlePane.
  497        */
  498       private void createButtons() {
  499           closeButton = createTitleButton();
  500           closeButton.setAction(closeAction);
  501           closeButton.setText(null);
  502           closeButton.putClientProperty("paintActive", Boolean.TRUE);
  503           closeButton.setBorder(handyEmptyBorder);
  504           closeButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
  505                                         "Close");
  506           closeButton.setIcon(UIManager.getIcon("InternalFrame.closeIcon"));
  507   
  508           if (getWindowDecorationStyle() == JRootPane.FRAME) {
  509               maximizeIcon = UIManager.getIcon("InternalFrame.maximizeIcon");
  510               minimizeIcon = UIManager.getIcon("InternalFrame.minimizeIcon");
  511   
  512               iconifyButton = createTitleButton();
  513               iconifyButton.setAction(iconifyAction);
  514               iconifyButton.setText(null);
  515               iconifyButton.putClientProperty("paintActive", Boolean.TRUE);
  516               iconifyButton.setBorder(handyEmptyBorder);
  517               iconifyButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
  518                                               "Iconify");
  519               iconifyButton.setIcon(UIManager.getIcon("InternalFrame.iconifyIcon"));
  520   
  521               toggleButton = createTitleButton();
  522               toggleButton.setAction(restoreAction);
  523               toggleButton.putClientProperty("paintActive", Boolean.TRUE);
  524               toggleButton.setBorder(handyEmptyBorder);
  525               toggleButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
  526                                              "Maximize");
  527               toggleButton.setIcon(maximizeIcon);
  528           }
  529       }
  530   
  531       /**
  532        * Returns the <code>LayoutManager</code> that should be installed on
  533        * the <code>MetalTitlePane</code>.
  534        */
  535       private LayoutManager createLayout() {
  536           return new TitlePaneLayout();
  537       }
  538   
  539       /**
  540        * Updates state dependant upon the Window's active state.
  541        */
  542       private void setActive(boolean isActive) {
  543           Boolean activeB = isActive ? Boolean.TRUE : Boolean.FALSE;
  544   
  545           closeButton.putClientProperty("paintActive", activeB);
  546           if (getWindowDecorationStyle() == JRootPane.FRAME) {
  547               iconifyButton.putClientProperty("paintActive", activeB);
  548               toggleButton.putClientProperty("paintActive", activeB);
  549           }
  550           // Repaint the whole thing as the Borders that are used have
  551           // different colors for active vs inactive
  552           getRootPane().repaint();
  553       }
  554   
  555       /**
  556        * Sets the state of the Window.
  557        */
  558       private void setState(int state) {
  559           setState(state, false);
  560       }
  561   
  562       /**
  563        * Sets the state of the window. If <code>updateRegardless</code> is
  564        * true and the state has not changed, this will update anyway.
  565        */
  566       private void setState(int state, boolean updateRegardless) {
  567           Window w = getWindow();
  568   
  569           if (w != null && getWindowDecorationStyle() == JRootPane.FRAME) {
  570               if (this.state == state && !updateRegardless) {
  571                   return;
  572               }
  573               Frame frame = getFrame();
  574   
  575               if (frame != null) {
  576                   JRootPane rootPane = getRootPane();
  577   
  578                   if (((state & Frame.MAXIMIZED_BOTH) != 0) &&
  579                           (rootPane.getBorder() == null ||
  580                           (rootPane.getBorder() instanceof UIResource)) &&
  581                               frame.isShowing()) {
  582                       rootPane.setBorder(null);
  583                   }
  584                   else if ((state & Frame.MAXIMIZED_BOTH) == 0) {
  585                       // This is a croak, if state becomes bound, this can
  586                       // be nuked.
  587                       rootPaneUI.installBorder(rootPane);
  588                   }
  589                   if (frame.isResizable()) {
  590                       if ((state & Frame.MAXIMIZED_BOTH) != 0) {
  591                           updateToggleButton(restoreAction, minimizeIcon);
  592                           maximizeAction.setEnabled(false);
  593                           restoreAction.setEnabled(true);
  594                       }
  595                       else {
  596                           updateToggleButton(maximizeAction, maximizeIcon);
  597                           maximizeAction.setEnabled(true);
  598                           restoreAction.setEnabled(false);
  599                       }
  600                       if (toggleButton.getParent() == null ||
  601                           iconifyButton.getParent() == null) {
  602                           add(toggleButton);
  603                           add(iconifyButton);
  604                           revalidate();
  605                           repaint();
  606                       }
  607                       toggleButton.setText(null);
  608                   }
  609                   else {
  610                       maximizeAction.setEnabled(false);
  611                       restoreAction.setEnabled(false);
  612                       if (toggleButton.getParent() != null) {
  613                           remove(toggleButton);
  614                           revalidate();
  615                           repaint();
  616                       }
  617                   }
  618               }
  619               else {
  620                   // Not contained in a Frame
  621                   maximizeAction.setEnabled(false);
  622                   restoreAction.setEnabled(false);
  623                   iconifyAction.setEnabled(false);
  624                   remove(toggleButton);
  625                   remove(iconifyButton);
  626                   revalidate();
  627                   repaint();
  628               }
  629               closeAction.setEnabled(true);
  630               this.state = state;
  631           }
  632       }
  633   
  634       /**
  635        * Updates the toggle button to contain the Icon <code>icon</code>, and
  636        * Action <code>action</code>.
  637        */
  638       private void updateToggleButton(Action action, Icon icon) {
  639           toggleButton.setAction(action);
  640           toggleButton.setIcon(icon);
  641           toggleButton.setText(null);
  642       }
  643   
  644       /**
  645        * Returns the Frame rendering in. This will return null if the
  646        * <code>JRootPane</code> is not contained in a <code>Frame</code>.
  647        */
  648       private Frame getFrame() {
  649           Window window = getWindow();
  650   
  651           if (window instanceof Frame) {
  652               return (Frame)window;
  653           }
  654           return null;
  655       }
  656   
  657       /**
  658        * Returns the <code>Window</code> the <code>JRootPane</code> is
  659        * contained in. This will return null if there is no parent ancestor
  660        * of the <code>JRootPane</code>.
  661        */
  662       private Window getWindow() {
  663           return window;
  664       }
  665   
  666       /**
  667        * Returns the String to display as the title.
  668        */
  669       private String getTitle() {
  670           Window w = getWindow();
  671   
  672           if (w instanceof Frame) {
  673               return ((Frame)w).getTitle();
  674           }
  675           else if (w instanceof Dialog) {
  676               return ((Dialog)w).getTitle();
  677           }
  678           return null;
  679       }
  680   
  681       /**
  682        * Renders the TitlePane.
  683        */
  684       public void paintComponent(Graphics g)  {
  685           // As state isn't bound, we need a convenience place to check
  686           // if it has changed. Changing the state typically changes the
  687           if (getFrame() != null) {
  688               setState(getFrame().getExtendedState());
  689           }
  690           JRootPane rootPane = getRootPane();
  691           Window window = getWindow();
  692           boolean leftToRight = (window == null) ?
  693                                  rootPane.getComponentOrientation().isLeftToRight() :
  694                                  window.getComponentOrientation().isLeftToRight();
  695           boolean isSelected = (window == null) ? true : window.isActive();
  696           int width = getWidth();
  697           int height = getHeight();
  698   
  699           Color background;
  700           Color foreground;
  701           Color darkShadow;
  702   
  703           MetalBumps bumps;
  704   
  705           if (isSelected) {
  706               background = activeBackground;
  707               foreground = activeForeground;
  708               darkShadow = activeShadow;
  709               bumps = activeBumps;
  710           } else {
  711               background = inactiveBackground;
  712               foreground = inactiveForeground;
  713               darkShadow = inactiveShadow;
  714               bumps = inactiveBumps;
  715           }
  716   
  717           g.setColor(background);
  718           g.fillRect(0, 0, width, height);
  719   
  720           g.setColor( darkShadow );
  721           g.drawLine ( 0, height - 1, width, height -1);
  722           g.drawLine ( 0, 0, 0 ,0);
  723           g.drawLine ( width - 1, 0 , width -1, 0);
  724   
  725           int xOffset = leftToRight ? 5 : width - 5;
  726   
  727           if (getWindowDecorationStyle() == JRootPane.FRAME) {
  728               xOffset += leftToRight ? IMAGE_WIDTH + 5 : - IMAGE_WIDTH - 5;
  729           }
  730   
  731           String theTitle = getTitle();
  732           if (theTitle != null) {
  733               FontMetrics fm = SwingUtilities2.getFontMetrics(rootPane, g);
  734   
  735               g.setColor(foreground);
  736   
  737               int yOffset = ( (height - fm.getHeight() ) / 2 ) + fm.getAscent();
  738   
  739               Rectangle rect = new Rectangle(0, 0, 0, 0);
  740               if (iconifyButton != null && iconifyButton.getParent() != null) {
  741                   rect = iconifyButton.getBounds();
  742               }
  743               int titleW;
  744   
  745               if( leftToRight ) {
  746                   if (rect.x == 0) {
  747                       rect.x = window.getWidth() - window.getInsets().right-2;
  748                   }
  749                   titleW = rect.x - xOffset - 4;
  750                   theTitle = SwingUtilities2.clipStringIfNecessary(
  751                                   rootPane, fm, theTitle, titleW);
  752               } else {
  753                   titleW = xOffset - rect.x - rect.width - 4;
  754                   theTitle = SwingUtilities2.clipStringIfNecessary(
  755                                   rootPane, fm, theTitle, titleW);
  756                   xOffset -= SwingUtilities2.stringWidth(rootPane, fm,
  757                                                          theTitle);
  758               }
  759               int titleLength = SwingUtilities2.stringWidth(rootPane, fm,
  760                                                             theTitle);
  761               SwingUtilities2.drawString(rootPane, g, theTitle, xOffset,
  762                                          yOffset );
  763               xOffset += leftToRight ? titleLength + 5  : -5;
  764           }
  765   
  766           int bumpXOffset;
  767           int bumpLength;
  768           if( leftToRight ) {
  769               bumpLength = width - buttonsWidth - xOffset - 5;
  770               bumpXOffset = xOffset;
  771           } else {
  772               bumpLength = xOffset - buttonsWidth - 5;
  773               bumpXOffset = buttonsWidth + 5;
  774           }
  775           int bumpYOffset = 3;
  776           int bumpHeight = getHeight() - (2 * bumpYOffset);
  777           bumps.setBumpArea( bumpLength, bumpHeight );
  778           bumps.paintIcon(this, g, bumpXOffset, bumpYOffset);
  779       }
  780   
  781       /**
  782        * Actions used to <code>close</code> the <code>Window</code>.
  783        */
  784       private class CloseAction extends AbstractAction {
  785           public CloseAction() {
  786               super(UIManager.getString("MetalTitlePane.closeTitle",
  787                                         getLocale()));
  788           }
  789   
  790           public void actionPerformed(ActionEvent e) {
  791               close();
  792           }
  793       }
  794   
  795   
  796       /**
  797        * Actions used to <code>iconfiy</code> the <code>Frame</code>.
  798        */
  799       private class IconifyAction extends AbstractAction {
  800           public IconifyAction() {
  801               super(UIManager.getString("MetalTitlePane.iconifyTitle",
  802                                         getLocale()));
  803           }
  804   
  805           public void actionPerformed(ActionEvent e) {
  806               iconify();
  807           }
  808       }
  809   
  810   
  811       /**
  812        * Actions used to <code>restore</code> the <code>Frame</code>.
  813        */
  814       private class RestoreAction extends AbstractAction {
  815           public RestoreAction() {
  816               super(UIManager.getString
  817                     ("MetalTitlePane.restoreTitle", getLocale()));
  818           }
  819   
  820           public void actionPerformed(ActionEvent e) {
  821               restore();
  822           }
  823       }
  824   
  825   
  826       /**
  827        * Actions used to <code>restore</code> the <code>Frame</code>.
  828        */
  829       private class MaximizeAction extends AbstractAction {
  830           public MaximizeAction() {
  831               super(UIManager.getString("MetalTitlePane.maximizeTitle",
  832                                         getLocale()));
  833           }
  834   
  835           public void actionPerformed(ActionEvent e) {
  836               maximize();
  837           }
  838       }
  839   
  840   
  841       /**
  842        * Class responsible for drawing the system menu. Looks up the
  843        * image to draw from the Frame associated with the
  844        * <code>JRootPane</code>.
  845        */
  846       private class SystemMenuBar extends JMenuBar {
  847           public void paint(Graphics g) {
  848               if (isOpaque()) {
  849                   g.setColor(getBackground());
  850                   g.fillRect(0, 0, getWidth(), getHeight());
  851               }
  852   
  853               if (systemIcon != null) {
  854                   g.drawImage(systemIcon, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, null);
  855               } else {
  856                   Icon icon = UIManager.getIcon("InternalFrame.icon");
  857   
  858                   if (icon != null) {
  859                       icon.paintIcon(this, g, 0, 0);
  860                   }
  861               }
  862           }
  863           public Dimension getMinimumSize() {
  864               return getPreferredSize();
  865           }
  866           public Dimension getPreferredSize() {
  867               Dimension size = super.getPreferredSize();
  868   
  869               return new Dimension(Math.max(IMAGE_WIDTH, size.width),
  870                                    Math.max(size.height, IMAGE_HEIGHT));
  871           }
  872       }
  873   
  874       private class TitlePaneLayout implements LayoutManager {
  875           public void addLayoutComponent(String name, Component c) {}
  876           public void removeLayoutComponent(Component c) {}
  877           public Dimension preferredLayoutSize(Container c)  {
  878               int height = computeHeight();
  879               return new Dimension(height, height);
  880           }
  881   
  882           public Dimension minimumLayoutSize(Container c) {
  883               return preferredLayoutSize(c);
  884           }
  885   
  886           private int computeHeight() {
  887               FontMetrics fm = rootPane.getFontMetrics(getFont());
  888               int fontHeight = fm.getHeight();
  889               fontHeight += 7;
  890               int iconHeight = 0;
  891               if (getWindowDecorationStyle() == JRootPane.FRAME) {
  892                   iconHeight = IMAGE_HEIGHT;
  893               }
  894   
  895               int finalHeight = Math.max( fontHeight, iconHeight );
  896               return finalHeight;
  897           }
  898   
  899           public void layoutContainer(Container c) {
  900               boolean leftToRight = (window == null) ?
  901                   getRootPane().getComponentOrientation().isLeftToRight() :
  902                   window.getComponentOrientation().isLeftToRight();
  903   
  904               int w = getWidth();
  905               int x;
  906               int y = 3;
  907               int spacing;
  908               int buttonHeight;
  909               int buttonWidth;
  910   
  911               if (closeButton != null && closeButton.getIcon() != null) {
  912                   buttonHeight = closeButton.getIcon().getIconHeight();
  913                   buttonWidth = closeButton.getIcon().getIconWidth();
  914               }
  915               else {
  916                   buttonHeight = IMAGE_HEIGHT;
  917                   buttonWidth = IMAGE_WIDTH;
  918               }
  919   
  920               // assumes all buttons have the same dimensions
  921               // these dimensions include the borders
  922   
  923               x = leftToRight ? w : 0;
  924   
  925               spacing = 5;
  926               x = leftToRight ? spacing : w - buttonWidth - spacing;
  927               if (menuBar != null) {
  928                   menuBar.setBounds(x, y, buttonWidth, buttonHeight);
  929               }
  930   
  931               x = leftToRight ? w : 0;
  932               spacing = 4;
  933               x += leftToRight ? -spacing -buttonWidth : spacing;
  934               if (closeButton != null) {
  935                   closeButton.setBounds(x, y, buttonWidth, buttonHeight);
  936               }
  937   
  938               if( !leftToRight ) x += buttonWidth;
  939   
  940               if (getWindowDecorationStyle() == JRootPane.FRAME) {
  941                   if (Toolkit.getDefaultToolkit().isFrameStateSupported(
  942                           Frame.MAXIMIZED_BOTH)) {
  943                       if (toggleButton.getParent() != null) {
  944                           spacing = 10;
  945                           x += leftToRight ? -spacing -buttonWidth : spacing;
  946                           toggleButton.setBounds(x, y, buttonWidth, buttonHeight);
  947                           if (!leftToRight) {
  948                               x += buttonWidth;
  949                           }
  950                       }
  951                   }
  952   
  953                   if (iconifyButton != null && iconifyButton.getParent() != null) {
  954                       spacing = 2;
  955                       x += leftToRight ? -spacing -buttonWidth : spacing;
  956                       iconifyButton.setBounds(x, y, buttonWidth, buttonHeight);
  957                       if (!leftToRight) {
  958                           x += buttonWidth;
  959                       }
  960                   }
  961               }
  962               buttonsWidth = leftToRight ? w - x : x;
  963           }
  964       }
  965   
  966   
  967   
  968       /**
  969        * PropertyChangeListener installed on the Window. Updates the necessary
  970        * state as the state of the Window changes.
  971        */
  972       private class PropertyChangeHandler implements PropertyChangeListener {
  973           public void propertyChange(PropertyChangeEvent pce) {
  974               String name = pce.getPropertyName();
  975   
  976               // Frame.state isn't currently bound.
  977               if ("resizable".equals(name) || "state".equals(name)) {
  978                   Frame frame = getFrame();
  979   
  980                   if (frame != null) {
  981                       setState(frame.getExtendedState(), true);
  982                   }
  983                   if ("resizable".equals(name)) {
  984                       getRootPane().repaint();
  985                   }
  986               }
  987               else if ("title".equals(name)) {
  988                   repaint();
  989               }
  990               else if ("componentOrientation" == name) {
  991                   revalidate();
  992                   repaint();
  993               }
  994               else if ("iconImage" == name) {
  995                   updateSystemIcon();
  996                   revalidate();
  997                   repaint();
  998               }
  999           }
 1000       }
 1001   
 1002       /**
 1003        * Update the image used for the system icon
 1004        */
 1005       private void updateSystemIcon() {
 1006           Window window = getWindow();
 1007           if (window == null) {
 1008               systemIcon = null;
 1009               return;
 1010           }
 1011           java.util.List<Image> icons = window.getIconImages();
 1012           assert icons != null;
 1013   
 1014           if (icons.size() == 0) {
 1015               systemIcon = null;
 1016           }
 1017           else if (icons.size() == 1) {
 1018               systemIcon = icons.get(0);
 1019           }
 1020           else {
 1021               systemIcon = SunToolkit.getScaledIconImage(icons,
 1022                                                          IMAGE_WIDTH,
 1023                                                          IMAGE_HEIGHT);
 1024           }
 1025       }
 1026   
 1027   
 1028       /**
 1029        * WindowListener installed on the Window, updates the state as necessary.
 1030        */
 1031       private class WindowHandler extends WindowAdapter {
 1032           public void windowActivated(WindowEvent ev) {
 1033               setActive(true);
 1034           }
 1035   
 1036           public void windowDeactivated(WindowEvent ev) {
 1037               setActive(false);
 1038           }
 1039       }
 1040   }

Save This Page
Home » openjdk-7 » javax » swing » plaf » metal » [javadoc | source]