1 /*
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing.plaf.basic;
  27 
  28 import sun.swing.SwingUtilities2;
  29 import java.awt.*;
  30 import java.awt.event.*;
  31 import javax.accessibility.AccessibleContext;
  32 import javax.swing.*;
  33 import javax.swing.plaf.*;
  34 import javax.swing.border.*;
  35 import javax.swing.event.InternalFrameEvent;
  36 import java.util.EventListener;
  37 import java.beans.PropertyChangeListener;
  38 import java.beans.PropertyChangeEvent;
  39 import java.beans.VetoableChangeListener;
  40 import java.beans.PropertyVetoException;
  41 
  42 import sun.swing.DefaultLookup;
  43 import sun.swing.UIAction;
  44 
  45 /**
  46  * The class that manages a basic title bar
  47  * <p>
  48  * <strong>Warning:</strong>
  49  * Serialized objects of this class will not be compatible with
  50  * future Swing releases. The current serialization support is
  51  * appropriate for short term storage or RMI between applications running
  52  * the same version of Swing.  As of 1.4, support for long term storage
  53  * of all JavaBeans&trade;
  54  * has been added to the <code>java.beans</code> package.
  55  * Please see {@link java.beans.XMLEncoder}.
  56  *
  57  * @author David Kloba
  58  * @author Steve Wilson
  59  */
  60 @SuppressWarnings("serial") // Same-version serialization only
  61 public class BasicInternalFrameTitlePane extends JComponent
  62 {
  63     protected JMenuBar menuBar;
  64     protected JButton iconButton;
  65     protected JButton maxButton;
  66     protected JButton closeButton;
  67 
  68     protected JMenu windowMenu;
  69     protected JInternalFrame frame;
  70 
  71     protected Color selectedTitleColor;
  72     protected Color selectedTextColor;
  73     protected Color notSelectedTitleColor;
  74     protected Color notSelectedTextColor;
  75 
  76     protected Icon maxIcon;
  77     protected Icon minIcon;
  78     protected Icon iconIcon;
  79     protected Icon closeIcon;
  80 
  81     protected PropertyChangeListener propertyChangeListener;
  82 
  83     protected Action closeAction;
  84     protected Action maximizeAction;
  85     protected Action iconifyAction;
  86     protected Action restoreAction;
  87     protected Action moveAction;
  88     protected Action sizeAction;
  89 
  90     // These constants are not used in JDK code
  91     protected static final String CLOSE_CMD =
  92         UIManager.getString("InternalFrameTitlePane.closeButtonText");
  93     protected static final String ICONIFY_CMD =
  94         UIManager.getString("InternalFrameTitlePane.minimizeButtonText");
  95     protected static final String RESTORE_CMD =
  96         UIManager.getString("InternalFrameTitlePane.restoreButtonText");
  97     protected static final String MAXIMIZE_CMD =
  98         UIManager.getString("InternalFrameTitlePane.maximizeButtonText");
  99     protected static final String MOVE_CMD =
 100         UIManager.getString("InternalFrameTitlePane.moveButtonText");
 101     protected static final String SIZE_CMD =
 102         UIManager.getString("InternalFrameTitlePane.sizeButtonText");
 103 
 104     private String closeButtonToolTip;
 105     private String iconButtonToolTip;
 106     private String restoreButtonToolTip;
 107     private String maxButtonToolTip;
 108     private Handler handler;
 109 
 110     public BasicInternalFrameTitlePane(JInternalFrame f) {
 111         frame = f;
 112         installTitlePane();
 113     }
 114 
 115     protected void installTitlePane() {
 116         installDefaults();
 117         installListeners();
 118 
 119         createActions();
 120         enableActions();
 121         createActionMap();
 122 
 123         setLayout(createLayout());
 124 
 125         assembleSystemMenu();
 126         createButtons();
 127         addSubComponents();
 128 
 129     }
 130 
 131     protected void addSubComponents() {
 132         add(menuBar);
 133         add(iconButton);
 134         add(maxButton);
 135         add(closeButton);
 136     }
 137 
 138     protected void createActions() {
 139         maximizeAction = new MaximizeAction();
 140         iconifyAction = new IconifyAction();
 141         closeAction = new CloseAction();
 142         restoreAction = new RestoreAction();
 143         moveAction = new MoveAction();
 144         sizeAction = new SizeAction();
 145     }
 146 
 147     ActionMap createActionMap() {
 148         ActionMap map = new ActionMapUIResource();
 149         map.put("showSystemMenu", new ShowSystemMenuAction(true));
 150         map.put("hideSystemMenu", new ShowSystemMenuAction(false));
 151         return map;
 152     }
 153 
 154     protected void installListeners() {
 155         if( propertyChangeListener == null ) {
 156             propertyChangeListener = createPropertyChangeListener();
 157         }
 158         frame.addPropertyChangeListener(propertyChangeListener);
 159     }
 160 
 161     protected void uninstallListeners() {
 162         frame.removePropertyChangeListener(propertyChangeListener);
 163         handler = null;
 164     }
 165 
 166     protected void installDefaults() {
 167         maxIcon = UIManager.getIcon("InternalFrame.maximizeIcon");
 168         minIcon = UIManager.getIcon("InternalFrame.minimizeIcon");
 169         iconIcon = UIManager.getIcon("InternalFrame.iconifyIcon");
 170         closeIcon = UIManager.getIcon("InternalFrame.closeIcon");
 171 
 172         selectedTitleColor = UIManager.getColor("InternalFrame.activeTitleBackground");
 173         selectedTextColor = UIManager.getColor("InternalFrame.activeTitleForeground");
 174         notSelectedTitleColor = UIManager.getColor("InternalFrame.inactiveTitleBackground");
 175         notSelectedTextColor = UIManager.getColor("InternalFrame.inactiveTitleForeground");
 176         setFont(UIManager.getFont("InternalFrame.titleFont"));
 177         closeButtonToolTip =
 178                 UIManager.getString("InternalFrame.closeButtonToolTip");
 179         iconButtonToolTip =
 180                 UIManager.getString("InternalFrame.iconButtonToolTip");
 181         restoreButtonToolTip =
 182                 UIManager.getString("InternalFrame.restoreButtonToolTip");
 183         maxButtonToolTip =
 184                 UIManager.getString("InternalFrame.maxButtonToolTip");
 185     }
 186 
 187 
 188     protected void uninstallDefaults() {
 189     }
 190 
 191     protected void createButtons() {
 192         iconButton = new NoFocusButton(
 193                      "InternalFrameTitlePane.iconifyButtonAccessibleName",
 194                      "InternalFrameTitlePane.iconifyButtonOpacity");
 195         iconButton.addActionListener(iconifyAction);
 196         if (iconButtonToolTip != null && iconButtonToolTip.length() != 0) {
 197             iconButton.setToolTipText(iconButtonToolTip);
 198         }
 199 
 200         maxButton = new NoFocusButton(
 201                         "InternalFrameTitlePane.maximizeButtonAccessibleName",
 202                         "InternalFrameTitlePane.maximizeButtonOpacity");
 203         maxButton.addActionListener(maximizeAction);
 204 
 205         closeButton = new NoFocusButton(
 206                       "InternalFrameTitlePane.closeButtonAccessibleName",
 207                       "InternalFrameTitlePane.closeButtonOpacity");
 208         closeButton.addActionListener(closeAction);
 209         if (closeButtonToolTip != null && closeButtonToolTip.length() != 0) {
 210             closeButton.setToolTipText(closeButtonToolTip);
 211         }
 212 
 213         setButtonIcons();
 214     }
 215 
 216     protected void setButtonIcons() {
 217         if(frame.isIcon()) {
 218             if (minIcon != null) {
 219                 iconButton.setIcon(minIcon);
 220             }
 221             if (restoreButtonToolTip != null &&
 222                     restoreButtonToolTip.length() != 0) {
 223                 iconButton.setToolTipText(restoreButtonToolTip);
 224             }
 225             if (maxIcon != null) {
 226                 maxButton.setIcon(maxIcon);
 227             }
 228             if (maxButtonToolTip != null && maxButtonToolTip.length() != 0) {
 229                 maxButton.setToolTipText(maxButtonToolTip);
 230             }
 231         } else if (frame.isMaximum()) {
 232             if (iconIcon != null) {
 233                 iconButton.setIcon(iconIcon);
 234             }
 235             if (iconButtonToolTip != null && iconButtonToolTip.length() != 0) {
 236                 iconButton.setToolTipText(iconButtonToolTip);
 237             }
 238             if (minIcon != null) {
 239                 maxButton.setIcon(minIcon);
 240             }
 241             if (restoreButtonToolTip != null &&
 242                     restoreButtonToolTip.length() != 0) {
 243                 maxButton.setToolTipText(restoreButtonToolTip);
 244             }
 245         } else {
 246             if (iconIcon != null) {
 247                 iconButton.setIcon(iconIcon);
 248             }
 249             if (iconButtonToolTip != null && iconButtonToolTip.length() != 0) {
 250                 iconButton.setToolTipText(iconButtonToolTip);
 251             }
 252             if (maxIcon != null) {
 253                 maxButton.setIcon(maxIcon);
 254             }
 255             if (maxButtonToolTip != null && maxButtonToolTip.length() != 0) {
 256                 maxButton.setToolTipText(maxButtonToolTip);
 257             }
 258         }
 259         if (closeIcon != null) {
 260             closeButton.setIcon(closeIcon);
 261         }
 262     }
 263 
 264     protected void assembleSystemMenu() {
 265         menuBar = createSystemMenuBar();
 266         windowMenu = createSystemMenu();
 267         menuBar.add(windowMenu);
 268         addSystemMenuItems(windowMenu);
 269         enableActions();
 270     }
 271 
 272     protected void addSystemMenuItems(JMenu systemMenu) {
 273         JMenuItem mi = systemMenu.add(restoreAction);
 274         mi.setMnemonic(getButtonMnemonic("restore"));
 275         mi = systemMenu.add(moveAction);
 276         mi.setMnemonic(getButtonMnemonic("move"));
 277         mi = systemMenu.add(sizeAction);
 278         mi.setMnemonic(getButtonMnemonic("size"));
 279         mi = systemMenu.add(iconifyAction);
 280         mi.setMnemonic(getButtonMnemonic("minimize"));
 281         mi = systemMenu.add(maximizeAction);
 282         mi.setMnemonic(getButtonMnemonic("maximize"));
 283         systemMenu.add(new JSeparator());
 284         mi = systemMenu.add(closeAction);
 285         mi.setMnemonic(getButtonMnemonic("close"));
 286     }
 287 
 288     private static int getButtonMnemonic(String button) {
 289         try {
 290             return Integer.parseInt(UIManager.getString(
 291                     "InternalFrameTitlePane." + button + "Button.mnemonic"));
 292         } catch (NumberFormatException e) {
 293             return -1;
 294         }
 295     }
 296 
 297     protected JMenu createSystemMenu() {
 298         return new JMenu("    ");
 299     }
 300 
 301     protected JMenuBar createSystemMenuBar() {
 302         menuBar = new SystemMenuBar();
 303         menuBar.setBorderPainted(false);
 304         return menuBar;
 305     }
 306 
 307     protected void showSystemMenu(){
 308         //      windowMenu.setPopupMenuVisible(true);
 309       //      windowMenu.setVisible(true);
 310       windowMenu.doClick();
 311     }
 312 
 313     public void paintComponent(Graphics g)  {
 314         paintTitleBackground(g);
 315 
 316         if(frame.getTitle() != null) {
 317             boolean isSelected = frame.isSelected();
 318             Font f = g.getFont();
 319             g.setFont(getFont());
 320             if(isSelected)
 321                 g.setColor(selectedTextColor);
 322             else
 323                 g.setColor(notSelectedTextColor);
 324 
 325             // Center text vertically.
 326             FontMetrics fm = SwingUtilities2.getFontMetrics(frame, g);
 327             int baseline = (getHeight() + fm.getAscent() - fm.getLeading() -
 328                     fm.getDescent()) / 2;
 329 
 330             int titleX;
 331             Rectangle r = new Rectangle(0, 0, 0, 0);
 332             if (frame.isIconifiable())  r = iconButton.getBounds();
 333             else if (frame.isMaximizable())  r = maxButton.getBounds();
 334             else if (frame.isClosable())  r = closeButton.getBounds();
 335             int titleW;
 336 
 337             String title = frame.getTitle();
 338             if( BasicGraphicsUtils.isLeftToRight(frame) ) {
 339               if (r.x == 0)  r.x = frame.getWidth()-frame.getInsets().right;
 340               titleX = menuBar.getX() + menuBar.getWidth() + 2;
 341               titleW = r.x - titleX - 3;
 342               title = getTitle(frame.getTitle(), fm, titleW);
 343             } else {
 344                 titleX = menuBar.getX() - 2
 345                          - SwingUtilities2.stringWidth(frame,fm,title);
 346             }
 347 
 348             SwingUtilities2.drawString(frame, g, title, titleX, baseline);
 349             g.setFont(f);
 350         }
 351     }
 352 
 353    /**
 354     * Invoked from paintComponent.
 355     * Paints the background of the titlepane.  All text and icons will
 356     * then be rendered on top of this background.
 357     * @param g the graphics to use to render the background
 358     * @since 1.4
 359     */
 360     protected void paintTitleBackground(Graphics g) {
 361         boolean isSelected = frame.isSelected();
 362 
 363         if(isSelected)
 364             g.setColor(selectedTitleColor);
 365         else
 366             g.setColor(notSelectedTitleColor);
 367         g.fillRect(0, 0, getWidth(), getHeight());
 368     }
 369 
 370     protected String getTitle(String text, FontMetrics fm, int availTextWidth) {
 371         return SwingUtilities2.clipStringIfNecessary(
 372                            frame, fm, text, availTextWidth);
 373       }
 374 
 375     /**
 376      * Post a WINDOW_CLOSING-like event to the frame, so that it can
 377      * be treated like a regular Frame.
 378      */
 379     protected void postClosingEvent(JInternalFrame frame) {
 380         InternalFrameEvent e = new InternalFrameEvent(
 381             frame, InternalFrameEvent.INTERNAL_FRAME_CLOSING);
 382         // Try posting event, unless there's a SecurityManager.
 383         if (JInternalFrame.class.getClassLoader() == null) {
 384             try {
 385                 Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(e);
 386                 return;
 387             } catch (SecurityException se) {
 388                 // Use dispatchEvent instead.
 389             }
 390         }
 391         frame.dispatchEvent(e);
 392     }
 393 
 394 
 395     protected void enableActions() {
 396         restoreAction.setEnabled(frame.isMaximum() || frame.isIcon());
 397         maximizeAction.setEnabled(
 398             (frame.isMaximizable() && !frame.isMaximum() && !frame.isIcon()) ||
 399             (frame.isMaximizable() && frame.isIcon()));
 400         iconifyAction.setEnabled(frame.isIconifiable() && !frame.isIcon());
 401         closeAction.setEnabled(frame.isClosable());
 402         sizeAction.setEnabled(false);
 403         moveAction.setEnabled(false);
 404     }
 405 
 406     private Handler getHandler() {
 407         if (handler == null) {
 408             handler = new Handler();
 409         }
 410         return handler;
 411     }
 412 
 413     protected PropertyChangeListener createPropertyChangeListener() {
 414         return getHandler();
 415     }
 416 
 417     protected LayoutManager createLayout() {
 418         return getHandler();
 419     }
 420 
 421 
 422     private class Handler implements LayoutManager, PropertyChangeListener {
 423         //
 424         // PropertyChangeListener
 425         //
 426         public void propertyChange(PropertyChangeEvent evt) {
 427             String prop = evt.getPropertyName();
 428 
 429             if (prop == JInternalFrame.IS_SELECTED_PROPERTY) {
 430                 repaint();
 431                 return;
 432             }
 433 
 434             if (prop == JInternalFrame.IS_ICON_PROPERTY ||
 435                     prop == JInternalFrame.IS_MAXIMUM_PROPERTY) {
 436                 setButtonIcons();
 437                 enableActions();
 438                 return;
 439             }
 440 
 441             if ("closable" == prop) {
 442                 if (evt.getNewValue() == Boolean.TRUE) {
 443                     add(closeButton);
 444                 } else {
 445                     remove(closeButton);
 446                 }
 447             } else if ("maximizable" == prop) {
 448                 if (evt.getNewValue() == Boolean.TRUE) {
 449                     add(maxButton);
 450                 } else {
 451                     remove(maxButton);
 452                 }
 453             } else if ("iconable" == prop) {
 454                 if (evt.getNewValue() == Boolean.TRUE) {
 455                     add(iconButton);
 456                 } else {
 457                     remove(iconButton);
 458                 }
 459             }
 460             enableActions();
 461 
 462             revalidate();
 463             repaint();
 464         }
 465 
 466 
 467         //
 468         // LayoutManager
 469         //
 470         public void addLayoutComponent(String name, Component c) {}
 471         public void removeLayoutComponent(Component c) {}
 472         public Dimension preferredLayoutSize(Container c) {
 473             return minimumLayoutSize(c);
 474         }
 475 
 476         public Dimension minimumLayoutSize(Container c) {
 477             // Calculate width.
 478             int width = 22;
 479 
 480             if (frame.isClosable()) {
 481                 width += 19;
 482             }
 483             if (frame.isMaximizable()) {
 484                 width += 19;
 485             }
 486             if (frame.isIconifiable()) {
 487                 width += 19;
 488             }
 489 
 490             FontMetrics fm = frame.getFontMetrics(getFont());
 491             String frameTitle = frame.getTitle();
 492             int title_w = frameTitle != null ? SwingUtilities2.stringWidth(
 493                                frame, fm, frameTitle) : 0;
 494             int title_length = frameTitle != null ? frameTitle.length() : 0;
 495 
 496             // Leave room for three characters in the title.
 497             if (title_length > 3) {
 498                 int subtitle_w = SwingUtilities2.stringWidth(
 499                     frame, fm, frameTitle.substring(0, 3) + "...");
 500                 width += (title_w < subtitle_w) ? title_w : subtitle_w;
 501             } else {
 502                 width += title_w;
 503             }
 504 
 505             // Calculate height.
 506             Icon icon = frame.getFrameIcon();
 507             int fontHeight = fm.getHeight();
 508             fontHeight += 2;
 509             int iconHeight = 0;
 510             if (icon != null) {
 511                 // SystemMenuBar forces the icon to be 16x16 or less.
 512                 iconHeight = Math.min(icon.getIconHeight(), 16);
 513             }
 514             iconHeight += 2;
 515 
 516             int height = Math.max( fontHeight, iconHeight );
 517 
 518             Dimension dim = new Dimension(width, height);
 519 
 520             // Take into account the border insets if any.
 521             if (getBorder() != null) {
 522                 Insets insets = getBorder().getBorderInsets(c);
 523                 dim.height += insets.top + insets.bottom;
 524                 dim.width += insets.left + insets.right;
 525             }
 526             return dim;
 527         }
 528 
 529         public void layoutContainer(Container c) {
 530             boolean leftToRight = BasicGraphicsUtils.isLeftToRight(frame);
 531 
 532             int w = getWidth();
 533             int h = getHeight();
 534             int x;
 535 
 536             int buttonHeight = closeButton.getIcon().getIconHeight();
 537 
 538             Icon icon = frame.getFrameIcon();
 539             int iconHeight = 0;
 540             if (icon != null) {
 541                 iconHeight = icon.getIconHeight();
 542             }
 543             x = (leftToRight) ? 2 : w - 16 - 2;
 544             menuBar.setBounds(x, (h - iconHeight) / 2, 16, 16);
 545 
 546             x = (leftToRight) ? w - 16 - 2 : 2;
 547 
 548             if (frame.isClosable()) {
 549                 closeButton.setBounds(x, (h - buttonHeight) / 2, 16, 14);
 550                 x += (leftToRight) ? -(16 + 2) : 16 + 2;
 551             }
 552 
 553             if (frame.isMaximizable()) {
 554                 maxButton.setBounds(x, (h - buttonHeight) / 2, 16, 14);
 555                 x += (leftToRight) ? -(16 + 2) : 16 + 2;
 556             }
 557 
 558             if (frame.isIconifiable()) {
 559                 iconButton.setBounds(x, (h - buttonHeight) / 2, 16, 14);
 560             }
 561         }
 562     }
 563 
 564     /**
 565      * This class should be treated as a &quot;protected&quot; inner class.
 566      * Instantiate it only within subclasses of <code>Foo</code>.
 567      */
 568     public class PropertyChangeHandler implements PropertyChangeListener {
 569         // NOTE: This class exists only for backward compatibility. All
 570         // its functionality has been moved into Handler. If you need to add
 571         // new functionality add it to the Handler, but make sure this
 572         // class calls into the Handler.
 573         public void propertyChange(PropertyChangeEvent evt) {
 574             getHandler().propertyChange(evt);
 575         }
 576     }
 577 
 578     /**
 579      * This class should be treated as a &quot;protected&quot; inner class.
 580      * Instantiate it only within subclasses of <code>Foo</code>.
 581      */
 582     public class TitlePaneLayout implements LayoutManager {
 583         // NOTE: This class exists only for backward compatibility. All
 584         // its functionality has been moved into Handler. If you need to add
 585         // new functionality add it to the Handler, but make sure this
 586         // class calls into the Handler.
 587         public void addLayoutComponent(String name, Component c) {
 588             getHandler().addLayoutComponent(name, c);
 589         }
 590 
 591         public void removeLayoutComponent(Component c) {
 592             getHandler().removeLayoutComponent(c);
 593         }
 594 
 595         public Dimension preferredLayoutSize(Container c)  {
 596             return getHandler().preferredLayoutSize(c);
 597         }
 598 
 599         public Dimension minimumLayoutSize(Container c) {
 600             return getHandler().minimumLayoutSize(c);
 601         }
 602 
 603         public void layoutContainer(Container c) {
 604             getHandler().layoutContainer(c);
 605         }
 606     }
 607 
 608     /**
 609      * This class should be treated as a &quot;protected&quot; inner class.
 610      * Instantiate it only within subclasses of <code>Foo</code>.
 611      */
 612     public class CloseAction extends AbstractAction {
 613         public CloseAction() {
 614             super(UIManager.getString(
 615                     "InternalFrameTitlePane.closeButtonText"));
 616         }
 617 
 618         public void actionPerformed(ActionEvent e) {
 619             if(frame.isClosable()) {
 620                 frame.doDefaultCloseAction();
 621             }
 622         }
 623     } // end CloseAction
 624 
 625     /**
 626      * This class should be treated as a &quot;protected&quot; inner class.
 627      * Instantiate it only within subclasses of <code>Foo</code>.
 628      */
 629     public class MaximizeAction extends AbstractAction {
 630         public MaximizeAction() {
 631             super(UIManager.getString(
 632                     "InternalFrameTitlePane.maximizeButtonText"));
 633         }
 634 
 635         public void actionPerformed(ActionEvent evt) {
 636             if (frame.isMaximizable()) {
 637                 if (frame.isMaximum() && frame.isIcon()) {
 638                     try {
 639                         frame.setIcon(false);
 640                     } catch (PropertyVetoException e) { }
 641                 } else if (!frame.isMaximum()) {
 642                     try {
 643                         frame.setMaximum(true);
 644                     } catch (PropertyVetoException e) { }
 645                 } else {
 646                     try {
 647                         frame.setMaximum(false);
 648                     } catch (PropertyVetoException e) { }
 649                 }
 650             }
 651         }
 652     }
 653 
 654     /**
 655      * This class should be treated as a &quot;protected&quot; inner class.
 656      * Instantiate it only within subclasses of <code>Foo</code>.
 657      */
 658     public class IconifyAction extends AbstractAction {
 659         public IconifyAction() {
 660             super(UIManager.getString(
 661                     "InternalFrameTitlePane.minimizeButtonText"));
 662         }
 663 
 664         public void actionPerformed(ActionEvent e) {
 665             if(frame.isIconifiable()) {
 666               if(!frame.isIcon()) {
 667                 try { frame.setIcon(true); } catch (PropertyVetoException e1) { }
 668               } else{
 669                 try { frame.setIcon(false); } catch (PropertyVetoException e1) { }
 670               }
 671             }
 672         }
 673     } // end IconifyAction
 674 
 675     /**
 676      * This class should be treated as a &quot;protected&quot; inner class.
 677      * Instantiate it only within subclasses of <code>Foo</code>.
 678      */
 679     public class RestoreAction extends AbstractAction {
 680         public RestoreAction() {
 681             super(UIManager.getString(
 682                     "InternalFrameTitlePane.restoreButtonText"));
 683         }
 684 
 685         public void actionPerformed(ActionEvent evt) {
 686             if (frame.isMaximizable() && frame.isMaximum() && frame.isIcon()) {
 687                 try {
 688                     frame.setIcon(false);
 689                 } catch (PropertyVetoException e) { }
 690             } else if (frame.isMaximizable() && frame.isMaximum()) {
 691                 try {
 692                     frame.setMaximum(false);
 693                 } catch (PropertyVetoException e) { }
 694             } else if (frame.isIconifiable() && frame.isIcon()) {
 695                 try {
 696                     frame.setIcon(false);
 697                 } catch (PropertyVetoException e) { }
 698             }
 699         }
 700     }
 701 
 702     /**
 703      * This class should be treated as a &quot;protected&quot; inner class.
 704      * Instantiate it only within subclasses of <code>Foo</code>.
 705      */
 706     public class MoveAction extends AbstractAction {
 707         public MoveAction() {
 708             super(UIManager.getString(
 709                     "InternalFrameTitlePane.moveButtonText"));
 710         }
 711 
 712         public void actionPerformed(ActionEvent e) {
 713             // This action is currently undefined
 714         }
 715     } // end MoveAction
 716 
 717     /*
 718      * Handles showing and hiding the system menu.
 719      */
 720     private class ShowSystemMenuAction extends AbstractAction {
 721         private boolean show;   // whether to show the menu
 722 
 723         public ShowSystemMenuAction(boolean show) {
 724             this.show = show;
 725         }
 726 
 727         public void actionPerformed(ActionEvent e) {
 728             if (show) {
 729                 windowMenu.doClick();
 730             } else {
 731                 windowMenu.setVisible(false);
 732             }
 733         }
 734     }
 735 
 736     /**
 737      * This class should be treated as a &quot;protected&quot; inner class.
 738      * Instantiate it only within subclasses of <code>Foo</code>.
 739      */
 740     public class SizeAction extends AbstractAction {
 741         public SizeAction() {
 742             super(UIManager.getString(
 743                     "InternalFrameTitlePane.sizeButtonText"));
 744         }
 745 
 746         public void actionPerformed(ActionEvent e) {
 747             // This action is currently undefined
 748         }
 749     } // end SizeAction
 750 
 751 
 752     /**
 753      * This class should be treated as a &quot;protected&quot; inner class.
 754      * Instantiate it only within subclasses of <code>Foo</code>.
 755      */
 756     public class SystemMenuBar extends JMenuBar {
 757         public boolean isFocusTraversable() { return false; }
 758         public void requestFocus() {}
 759         public void paint(Graphics g) {
 760             Icon icon = frame.getFrameIcon();
 761             if (icon == null) {
 762               icon = (Icon)DefaultLookup.get(frame, frame.getUI(),
 763                       "InternalFrame.icon");
 764             }
 765             if (icon != null) {
 766                 // Resize to 16x16 if necessary.
 767                 if (icon instanceof ImageIcon && (icon.getIconWidth() > 16 || icon.getIconHeight() > 16)) {
 768                     Image img = ((ImageIcon)icon).getImage();
 769                     ((ImageIcon)icon).setImage(img.getScaledInstance(16, 16, Image.SCALE_SMOOTH));
 770                 }
 771                 icon.paintIcon(this, g, 0, 0);
 772             }
 773         }
 774 
 775         public boolean isOpaque() {
 776             return true;
 777         }
 778     } // end SystemMenuBar
 779 
 780 
 781     private class NoFocusButton extends JButton {
 782         private String uiKey;
 783         public NoFocusButton(String uiKey, String opacityKey) {
 784             setFocusPainted(false);
 785             setMargin(new Insets(0,0,0,0));
 786             this.uiKey = uiKey;
 787 
 788             Object opacity = UIManager.get(opacityKey);
 789             if (opacity instanceof Boolean) {
 790                 setOpaque(((Boolean)opacity).booleanValue());
 791             }
 792         }
 793         public boolean isFocusTraversable() { return false; }
 794         public void requestFocus() {}
 795         public AccessibleContext getAccessibleContext() {
 796             AccessibleContext ac = super.getAccessibleContext();
 797             if (uiKey != null) {
 798                 ac.setAccessibleName(UIManager.getString(uiKey));
 799                 uiKey = null;
 800             }
 801             return ac;
 802         }
 803     }  // end NoFocusButton
 804 
 805 }   // End Title Pane Class