Source for javax.swing.JRootPane

   1: /* JRootPane.java --
   2:    Copyright (C) 2002, 2004  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.swing;
  40: 
  41: import java.awt.BorderLayout;
  42: import java.awt.Component;
  43: import java.awt.Container;
  44: import java.awt.Dimension;
  45: import java.awt.IllegalComponentStateException;
  46: import java.awt.LayoutManager;
  47: import java.awt.LayoutManager2;
  48: import java.io.Serializable;
  49: 
  50: import javax.accessibility.Accessible;
  51: import javax.accessibility.AccessibleRole;
  52: import javax.swing.plaf.RootPaneUI;
  53: 
  54: /**
  55:  * This class is where JComponents are added to. Unlike awt where you could
  56:  * just say frame.add(), with swing you need to say frame.getRootPane()
  57:  * (which delivers an instance of this class) and add your components to
  58:  * that. It is implemented by several 'layers' (pane() should be read as
  59:  * plane()) each on top of the others where you can add components to.
  60:  * (getContentPane(), getGlassPane(), getLayeredPane())
  61:  *
  62:  * @author Ronald Veldema (rveldema@cs.vu.nl)
  63:  */
  64: public class JRootPane extends JComponent implements Accessible
  65: {
  66:   //  The class used to obtain the accessible role for this object.
  67:   protected class AccessibleJRootPane extends AccessibleJComponent
  68:   {
  69:     /**
  70:      * For compatability with Sun's JDK
  71:      */
  72:     private static final long serialVersionUID = 1082432482784468088L;
  73: 
  74:     /**
  75:      * Creates a new <code>AccessibleJRootPane</code> object.
  76:      */
  77:     protected AccessibleJRootPane()
  78:     {
  79:       // Nothing to do here.
  80:     }
  81: 
  82:     /**
  83:      * DOCUMENT ME!
  84:      *
  85:      * @return DOCUMENT ME!
  86:      */
  87:     public AccessibleRole getAccessibleRole()
  88:     {
  89:       return AccessibleRole.ROOT_PANE;
  90:     }
  91:   }
  92: 
  93:   // Custom Layout Manager for JRootPane. It positions contentPane and 
  94:   // menuBar withing its layeredPane.
  95:   protected class RootLayout implements LayoutManager2, Serializable
  96:   {
  97:     /** DOCUMENT ME! */
  98:     private static final long serialVersionUID = -4100116998559815027L;
  99: 
 100:     /**
 101:      * Creates a new <code>RootLayout</code> object.
 102:      */
 103:     protected RootLayout()
 104:     {
 105:       // Nothing to do here.
 106:     }
 107: 
 108:     /**
 109:      * DOCUMENT ME!
 110:      *
 111:      * @param comp DOCUMENT ME!
 112:      * @param constraints DOCUMENT ME!
 113:      */
 114:     public void addLayoutComponent(Component comp, Object constraints)
 115:     {
 116:       // Nothing to do here.
 117:     }
 118: 
 119:     /**
 120:      * DOCUMENT ME!
 121:      *
 122:      * @param name DOCUMENT ME!
 123:      * @param comp DOCUMENT ME!
 124:      */
 125:     public void addLayoutComponent(String name, Component comp)
 126:     {
 127:       // Nothing to do here.
 128:     }
 129: 
 130:     /**
 131:      * DOCUMENT ME!
 132:      *
 133:      * @param target DOCUMENT ME!
 134:      *
 135:      * @return DOCUMENT ME!
 136:      */
 137:     public float getLayoutAlignmentX(Container target)
 138:     {
 139:       return target.getAlignmentX();
 140:     }
 141: 
 142:     /**
 143:      * DOCUMENT ME!
 144:      *
 145:      * @param target DOCUMENT ME!
 146:      *
 147:      * @return DOCUMENT ME!
 148:      */
 149:     public float getLayoutAlignmentY(Container target)
 150:     {
 151:       return target.getAlignmentY();
 152:     }
 153: 
 154:     /**
 155:      * DOCUMENT ME!
 156:      *
 157:      * @param target DOCUMENT ME!
 158:      */
 159:     public void invalidateLayout(Container target)
 160:     {
 161:       // Nothing to do here.
 162:     }
 163: 
 164:     /**
 165:      * DOCUMENT ME!
 166:      *
 167:      * @param c DOCUMENT ME!
 168:      */
 169:     public void layoutContainer(Container c)
 170:     {
 171:       Dimension menuBarSize;
 172:       int containerWidth = c.getBounds().width - getInsets().left
 173:                            - getInsets().right;
 174:       int containerHeight = c.getBounds().height - getInsets().top
 175:                             - getInsets().bottom;
 176:       Dimension contentPaneSize = contentPane.getPreferredSize();
 177: 
 178:       // 1. the glassPane fills entire viewable region (bounds - insets).
 179:       // 2. the layeredPane filles entire viewable region.
 180:       // 3. the menuBar is positioned at the upper edge of layeredPane.
 181:       // 4. the contentPane fills viewable region minus menuBar, if present.
 182:       
 183:       /*
 184:        if size of top-level window wasn't set then just set
 185:        contentPane and menuBar to its preferred sizes.
 186:        Otherwise, if the size of top-level window was specified then
 187:        set menuBar to its preferred size and make content pane
 188:        to fit into the remaining space
 189: 
 190: 
 191:        +-------------------------------+
 192:        |  JLayeredPane                 |
 193:        |  +--------------------------+ |
 194:        |  | menuBar                  | |
 195:        |  +--------------------------+ |
 196:        |  +--------------------------+ |
 197:        |  |contentPane               | |
 198:        |  |                          | |
 199:        |  |                          | |
 200:        |  |                          | |
 201:        |  +--------------------------+ |
 202:        +-------------------------------+
 203: 
 204:       */
 205:       if (containerWidth == 0 && containerHeight == 0)
 206:         {
 207:           if (menuBar != null)
 208:             {
 209:               int maxWidth;
 210:               menuBarSize = menuBar.getPreferredSize();
 211:               maxWidth = Math.max(menuBarSize.width, contentPaneSize.width);
 212:               menuBar.setBounds(0, 0, maxWidth, menuBarSize.height);
 213:               glassPane.setBounds(0, 0, maxWidth, menuBarSize.height
 214:                                                   + contentPaneSize.height);
 215:               contentPane.setBounds(0, menuBarSize.height, maxWidth,
 216:                                     contentPaneSize.height);
 217:               layeredPane.setBounds(0, 0, maxWidth, menuBarSize.height
 218:                                                     + contentPaneSize.height);
 219:             }
 220:           else
 221:             {
 222:               glassPane.setBounds(0, 0, contentPaneSize.width,
 223:                                   contentPaneSize.height);
 224:               contentPane.setBounds(0, 0, contentPaneSize.width,
 225:                                     contentPaneSize.height);
 226:               layeredPane.setBounds(0, 0, contentPaneSize.width,
 227:                                     contentPaneSize.height);
 228:             }
 229:         }
 230:       else
 231:         {
 232:           if (menuBar != null)
 233:             {
 234:               menuBarSize = menuBar.getPreferredSize();
 235:               if (menuBarSize.height > containerHeight)
 236:                 menuBarSize.height = containerHeight;
 237:               menuBar.setBounds(0, 0, containerWidth, menuBarSize.height);
 238:               glassPane.setBounds(0, 0, containerWidth, containerHeight);
 239:               contentPane.setBounds(0, menuBarSize.height, containerWidth,
 240:                                     (containerHeight - menuBarSize.height));
 241:             }
 242:           else
 243:             {
 244:               glassPane.setBounds(0, 0, containerWidth, containerHeight);
 245:               contentPane.setBounds(0, 0, containerWidth, containerHeight);
 246:             }
 247:           layeredPane.setBounds(0, 0, containerWidth, containerHeight);
 248:         }
 249:     }
 250: 
 251:     /**
 252:      * DOCUMENT ME!
 253:      *
 254:      * @param target DOCUMENT ME!
 255:      *
 256:      * @return DOCUMENT ME!
 257:      */
 258:     public Dimension maximumLayoutSize(Container target)
 259:     {
 260:       return preferredLayoutSize(target);
 261:     }
 262: 
 263:     /**
 264:      * DOCUMENT ME!
 265:      *
 266:      * @param target DOCUMENT ME!
 267:      *
 268:      * @return DOCUMENT ME!
 269:      */
 270:     public Dimension minimumLayoutSize(Container target)
 271:     {
 272:       return preferredLayoutSize(target);
 273:     }
 274: 
 275:     /**
 276:      * DOCUMENT ME!
 277:      *
 278:      * @param c DOCUMENT ME!
 279:      *
 280:      * @return DOCUMENT ME!
 281:      */
 282:     public Dimension preferredLayoutSize(Container c)
 283:     {
 284:       Dimension menuBarSize;
 285:       Dimension prefSize;
 286: 
 287:       Dimension containerSize = c.getSize();
 288:       Dimension contentPaneSize = contentPane.getPreferredSize();
 289: 
 290:       if (containerSize.width == 0 && containerSize.height == 0)
 291:         {
 292:           if (menuBar != null)
 293:             {
 294:               int maxWidth;
 295:               menuBarSize = menuBar.getPreferredSize();
 296:               maxWidth = Math.max(menuBarSize.width, contentPaneSize.width);
 297:               prefSize = new Dimension(maxWidth,
 298:                                        contentPaneSize.height
 299:                                        + menuBarSize.height);
 300:             }
 301:           else
 302:             prefSize = contentPaneSize;
 303:         }
 304:       else
 305:         prefSize = c.getSize();
 306: 
 307:       return prefSize;
 308:     }
 309: 
 310:     /**
 311:      * DOCUMENT ME!
 312:      *
 313:      * @param comp DOCUMENT ME!
 314:      */
 315:     public void removeLayoutComponent(Component comp)
 316:     {
 317:       // Nothing to do here.
 318:     }
 319:   }
 320: 
 321:   /** DOCUMENT ME! */
 322:   private static final long serialVersionUID = 8690748000348575668L;
 323: 
 324:   public static final int NONE = 0;
 325:   public static final int FRAME = 1;
 326:   public static final int PLAIN_DIALOG = 2;
 327:   public static final int INFORMATION_DIALOG = 3;
 328:   public static final int ERROR_DIALOG = 4;
 329:   public static final int COLOR_CHOOSER_DIALOG = 5;
 330:   public static final int FILE_CHOOSER_DIALOG = 6;
 331:   public static final int QUESTION_DIALOG = 7;
 332:   public static final int WARNING_DIALOG = 8;
 333:           
 334:   /** DOCUMENT ME! */
 335:   protected Component glassPane;
 336: 
 337:   /** DOCUMENT ME! */
 338:   protected JLayeredPane layeredPane;
 339: 
 340:   /** DOCUMENT ME! */
 341:   protected JMenuBar menuBar;
 342: 
 343:   /** DOCUMENT ME! */
 344:   protected Container contentPane;
 345: 
 346:   protected JButton defaultButton;
 347: 
 348:   /**
 349:    * This field is unused since JDK1.3. To override the default action you
 350:    * should modify the JRootPane's ActionMap.
 351:    *
 352:    * @deprecated since JDK1.3
 353:    *
 354:    * @specnote the specs indicate that the type of this field is
 355:    *           a package private inner class
 356:    *           javax.swing.JRootPane.DefaultAction. I assume that the closest
 357:    *           public superclass is javax.swing.Action.
 358:    */
 359:   protected Action defaultPressAction;
 360: 
 361:   /**
 362:    * This field is unused since JDK1.3. To override the default action you
 363:    * should modify the JRootPane's ActionMap.
 364:    *
 365:    * @deprecated since JDK1.3
 366:    *
 367:    * @specnote the specs indicate that the type of this field is
 368:    *           a package private inner class
 369:    *           javax.swing.JRootPane.DefaultAction. I assume that the closest
 370:    *           public superclass is javax.swing.Action.
 371:    */
 372:   protected Action defaultReleaseAction;
 373: 
 374:   /**
 375:    * @since 1.4
 376:    */
 377:   private int windowDecorationStyle = NONE;
 378:   
 379:   /**
 380:    * DOCUMENT ME!
 381:    *
 382:    * @param m DOCUMENT ME!
 383:    */
 384:   public void setJMenuBar(JMenuBar m)
 385:   {
 386:     JLayeredPane jlPane = getLayeredPane();
 387:     if (menuBar != null)
 388:       jlPane.remove(menuBar);
 389:     menuBar = m;
 390:     if (menuBar != null)
 391:       jlPane.add(menuBar, JLayeredPane.FRAME_CONTENT_LAYER);
 392:   }
 393: 
 394:   /**
 395:    * @deprecated Replaced by <code>setJMenuBar()</code>
 396:    */
 397:   public void setMenuBar(JMenuBar m)
 398:   {
 399:     setJMenuBar(m);
 400:   }
 401: 
 402:   /**
 403:    * DOCUMENT ME!
 404:    *
 405:    * @return DOCUMENT ME!
 406:    */
 407:   public JMenuBar getJMenuBar()
 408:   {
 409:     return menuBar;
 410:   }
 411: 
 412:   /**
 413:    * @deprecated Replaced by <code>getJMenuBar()</code>
 414:    */
 415:   public JMenuBar getMenuBar()
 416:   {
 417:     return getJMenuBar();
 418:   }
 419: 
 420:   /**
 421:    * DOCUMENT ME!
 422:    *
 423:    * @return DOCUMENT ME!
 424:    */
 425:   public boolean isValidateRoot()
 426:   {
 427:     return true;
 428:   }
 429: 
 430:   /**
 431:    * DOCUMENT ME!
 432:    *
 433:    * @return DOCUMENT ME!
 434:    */
 435:   public Container getContentPane()
 436:   {
 437:     if (contentPane == null)
 438:       setContentPane(createContentPane());
 439:     return contentPane;
 440:   }
 441: 
 442:   /**
 443:    * Sets the JRootPane's content pane.  The content pane should typically be
 444:    * opaque for painting to work properly.  This method also 
 445:    * removes the old content pane from the layered pane.
 446:    *
 447:    * @param p the Container that will be the content pane
 448:    * @throws IllegalComponentStateException if p is null
 449:    */
 450:   public void setContentPane(Container p)
 451:   {
 452:     if (p == null)
 453:       throw new IllegalComponentStateException ("cannot " +
 454:             "have a null content pane");
 455:     else
 456:       {
 457:         if (contentPane != null && contentPane.getParent() == layeredPane)
 458:           layeredPane.remove(contentPane);
 459:         contentPane = p;
 460:         getLayeredPane().add(contentPane, JLayeredPane.FRAME_CONTENT_LAYER);
 461:       }
 462:   }
 463: 
 464:   /**
 465:    * DOCUMENT ME!
 466:    *
 467:    * @param comp DOCUMENT ME!
 468:    * @param constraints DOCUMENT ME!
 469:    * @param index DOCUMENT ME!
 470:    */
 471:   protected void addImpl(Component comp, Object constraints, int index)
 472:   {
 473:     super.addImpl(comp, constraints, index);
 474:   }
 475: 
 476:   /**
 477:    * DOCUMENT ME!
 478:    *
 479:    * @return DOCUMENT ME!
 480:    */
 481:   public Component getGlassPane()
 482:   {
 483:     if (glassPane == null)
 484:       setGlassPane(createGlassPane());
 485:     return glassPane;
 486:   }
 487: 
 488:   /**
 489:    * DOCUMENT ME!
 490:    *
 491:    * @param f DOCUMENT ME!
 492:    */
 493:   public void setGlassPane(Component f)
 494:   {
 495:     if (glassPane != null)
 496:       remove(glassPane);
 497: 
 498:     glassPane = f;
 499: 
 500:     glassPane.setVisible(false);
 501:     add(glassPane, 0);
 502:   }
 503: 
 504:   /**
 505:    * DOCUMENT ME!
 506:    *
 507:    * @return DOCUMENT ME!
 508:    */
 509:   public JLayeredPane getLayeredPane()
 510:   {
 511:     if (layeredPane == null)
 512:       setLayeredPane(createLayeredPane());
 513:     return layeredPane;
 514:   }
 515: 
 516:   /**
 517:    * DOCUMENT ME!
 518:    *
 519:    * @param f DOCUMENT ME!
 520:    */
 521:   public void setLayeredPane(JLayeredPane f)
 522:   {
 523:     if (layeredPane != null)
 524:       remove(layeredPane);
 525: 
 526:     layeredPane = f;
 527:     add(f, -1);
 528:   }
 529: 
 530:   /**
 531:    * Creates a new <code>JRootPane</code> object.
 532:    */
 533:   public JRootPane()
 534:   {
 535:     setLayout(createRootLayout());
 536:     getGlassPane();
 537:     getLayeredPane();
 538:     getContentPane();
 539:     updateUI();
 540:   }
 541: 
 542:   /**
 543:    * DOCUMENT ME!
 544:    *
 545:    * @return DOCUMENT ME!
 546:    */
 547:   protected LayoutManager createRootLayout()
 548:   {
 549:     return new RootLayout();
 550:   }
 551: 
 552:   /**
 553:    * DOCUMENT ME!
 554:    *
 555:    * @return DOCUMENT ME!
 556:    */
 557:   protected Container createContentPane()
 558:   {
 559:     JPanel p = new JPanel();
 560:     p.setName(this.getName() + ".contentPane");
 561:     p.setLayout(new BorderLayout());
 562:     return p;
 563:   }
 564: 
 565:   /**
 566:    * DOCUMENT ME!
 567:    *
 568:    * @return DOCUMENT ME!
 569:    */
 570:   protected Component createGlassPane()
 571:   {
 572:     JPanel p = new JPanel();
 573:     p.setName(this.getName() + ".glassPane");
 574:     p.setVisible(false);
 575:     p.setOpaque(false);
 576:     return p;
 577:   }
 578: 
 579:   /**
 580:    * DOCUMENT ME!
 581:    *
 582:    * @return DOCUMENT ME!
 583:    */
 584:   protected JLayeredPane createLayeredPane()
 585:   {
 586:     JLayeredPane l = new JLayeredPane();
 587:     l.setLayout(null);
 588:     return l;
 589:   }
 590: 
 591:   /**
 592:    * DOCUMENT ME!
 593:    *
 594:    * @return DOCUMENT ME!
 595:    */
 596:   public RootPaneUI getUI()
 597:   {
 598:     return (RootPaneUI) ui;
 599:   }
 600: 
 601:   /**
 602:    * DOCUMENT ME!
 603:    *
 604:    * @param ui DOCUMENT ME!
 605:    */
 606:   public void setUI(RootPaneUI ui)
 607:   {
 608:     super.setUI(ui);
 609:   }
 610: 
 611:   /**
 612:    * DOCUMENT ME!
 613:    */
 614:   public void updateUI()
 615:   {
 616:     setUI((RootPaneUI) UIManager.getUI(this));
 617:   }
 618: 
 619:   /**
 620:    * DOCUMENT ME!
 621:    *
 622:    * @return DOCUMENT ME!
 623:    */
 624:   public String getUIClassID()
 625:   {
 626:     return "RootPaneUI";
 627:   }
 628: 
 629:   public JButton getDefaultButton()
 630:   {
 631:     return defaultButton;
 632:   }
 633:   
 634:   public void setDefaultButton(JButton newButton)
 635:   {
 636:     if (defaultButton == newButton)
 637:       return;
 638:     
 639:     JButton oldButton = defaultButton;
 640:     defaultButton = newButton;
 641:     firePropertyChange("defaultButton", oldButton, newButton);
 642:   }
 643: 
 644:   /**
 645:    * @since 1.4
 646:    */
 647:   public int getWindowDecorationStyle()
 648:   {
 649:     return windowDecorationStyle;
 650:   }
 651: 
 652:   /**
 653:    * @since 1.4
 654:    */
 655:   public void setWindowDecorationStyle(int style)
 656:   {
 657:     if (style != NONE
 658:         && style != FRAME
 659:         && style != INFORMATION_DIALOG
 660:         && style != ERROR_DIALOG
 661:         && style != COLOR_CHOOSER_DIALOG
 662:         && style != FILE_CHOOSER_DIALOG
 663:         && style != QUESTION_DIALOG
 664:         && style != WARNING_DIALOG
 665:         && style != PLAIN_DIALOG)
 666:       throw new IllegalArgumentException("invalid style");
 667:     
 668:     int oldStyle = windowDecorationStyle;
 669:     windowDecorationStyle = style;
 670:     firePropertyChange("windowDecorationStyle", oldStyle, style);
 671:   }
 672: }