Source for javax.swing.JToolBar

   1: /* JToolBar.java --
   2:    Copyright (C) 2002, 2004, 2005  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.Component;
  42: import java.awt.Container;
  43: import java.awt.Dimension;
  44: import java.awt.Graphics;
  45: import java.awt.Insets;
  46: import java.awt.LayoutManager;
  47: import java.beans.PropertyChangeListener;
  48: 
  49: import javax.accessibility.Accessible;
  50: import javax.accessibility.AccessibleContext;
  51: import javax.accessibility.AccessibleRole;
  52: import javax.accessibility.AccessibleStateSet;
  53: import javax.swing.JButton;
  54: import javax.swing.plaf.ToolBarUI;
  55: 
  56: /**
  57:  * JToolBar is a component that provides a toolbar to Swing programs. Users
  58:  * can add buttons (or actions that will be represented by JButtons) as well
  59:  * as other components to the JToolBar. JToolBars can be dragged in and out
  60:  * of their parent components. If the JToolBar is dragged out of the parent,
  61:  * then it will be displayed in its own RootPaneContainer. For dragging to
  62:  * work properly, JToolBars need to be placed in a Container that has a
  63:  * BorderLayout. That parent Container cannot have components in the NORTH,
  64:  * EAST, SOUTH,  or WEST components (that is not the JToolBar).
  65:  */
  66: public class JToolBar extends JComponent implements SwingConstants, Accessible
  67: {
  68:   /**
  69:    * AccessibleJToolBar
  70:    */
  71:   protected class AccessibleJToolBar extends AccessibleJComponent
  72:   {
  73:     /** DOCUMENT ME! */
  74:     private static final long serialVersionUID = -5516888265903814215L;
  75: 
  76:     /**
  77:      * Constructor AccessibleJToolBar
  78:      */
  79:     protected AccessibleJToolBar()
  80:     {
  81:     }
  82: 
  83:     /**
  84:      * getAccessibleStateSet
  85:      *
  86:      * @return AccessibleStateSet
  87:      */
  88:     public AccessibleStateSet getAccessibleStateSet()
  89:     {
  90:       return null; // TODO
  91:     }
  92: 
  93:     /**
  94:      * getAccessibleRole
  95:      *
  96:      * @return AccessibleRole
  97:      */
  98:     public AccessibleRole getAccessibleRole()
  99:     {
 100:       return AccessibleRole.TOOL_BAR;
 101:     }
 102:   }
 103: 
 104:   /**
 105:    * This is the private JToolBar layout manager.
 106:    */
 107:   private class DefaultToolBarLayout implements LayoutManager
 108:   {
 109:     /**
 110:      * This method is called when a new component is added to the container.
 111:      *
 112:      * @param name The name of the component added.
 113:      * @param comp The component that was added.
 114:      */
 115:     public void addLayoutComponent(String name, Component comp)
 116:     {
 117:       // Do nothing.
 118:     }
 119: 
 120:     /**
 121:      * This method is called to lay out the given container  to position and
 122:      * size the child components.
 123:      *
 124:      * @param c The container to lay out.
 125:      *
 126:      * @throws Error DOCUMENT ME!
 127:      */
 128:     public void layoutContainer(Container c)
 129:     {
 130:       if (! (c instanceof JToolBar))
 131:     throw new Error("DefaultToolBarLayout can only be used on JToolBars.");
 132:       Insets insets = getInsets();
 133:       Insets margin = getMargin();
 134:       int middle;
 135:       if (margin != null)
 136:         {
 137:       insets.left += margin.left;
 138:       insets.top += margin.top;
 139:       insets.bottom += margin.bottom;
 140:       insets.right += margin.right;
 141:         }
 142:       Component[] components = c.getComponents();
 143:       Dimension tdims = c.getSize();
 144:       int start = 0;
 145:       Dimension pref;
 146: 
 147:       if (getOrientation() == SwingUtilities.HORIZONTAL)
 148:         {
 149:       start += insets.left;
 150:       for (int i = 0; i < components.length; i++)
 151:         {
 152:           if (components[i] != null && components[i].isVisible())
 153:             {
 154:           pref = components[i].getPreferredSize();
 155:           if (pref != null)
 156:             {
 157:               middle = (tdims.height - pref.height) / 2;
 158:               components[i].setBounds(start, middle, pref.width,
 159:                                       pref.height);
 160:               start += pref.width;
 161:             }
 162:             }
 163:         }
 164:         }
 165:       else
 166:         {
 167:       start += insets.top;
 168:       for (int i = 0; i < components.length; i++)
 169:         {
 170:           if (components[i] != null && components[i].isVisible())
 171:             {
 172:           pref = components[i].getPreferredSize();
 173:           if (pref != null)
 174:             {
 175:               middle = (tdims.width - pref.width) / 2;
 176:               components[i].setBounds(middle, start, pref.width,
 177:                                       pref.height);
 178:               start += pref.height;
 179:             }
 180:             }
 181:         }
 182:         }
 183:     }
 184: 
 185:     /**
 186:      * This method returns the minimum size of the given container given the
 187:      * child components.
 188:      *
 189:      * @param parent The container to measure.
 190:      *
 191:      * @return The minimum size of the given container.
 192:      */
 193:     public Dimension minimumLayoutSize(Container parent)
 194:     {
 195:       return preferredLayoutSize(parent);
 196:     }
 197: 
 198:     /**
 199:      * This method returns the preferred size of the given container given the
 200:      * child components.
 201:      *
 202:      * @param parent The container to measure.
 203:      *
 204:      * @return The preferred size of the given container.
 205:      */
 206:     public Dimension preferredLayoutSize(Container parent)
 207:     {
 208:       int orientation = getOrientation();
 209:       Component[] components = getComponents();
 210: 
 211:       int limit = 0;
 212:       int total = 0;
 213:       Dimension dims;
 214: 
 215:       int w = 0;
 216:       int h = 0;
 217: 
 218:       if (orientation == SwingConstants.HORIZONTAL)
 219:         {
 220:       for (int i = 0; i < components.length; i++)
 221:         {
 222:           dims = components[i].getPreferredSize();
 223:           if (dims != null)
 224:             {
 225:           if (dims.height > limit)
 226:             limit = dims.height;
 227:           total += dims.width;
 228:             }
 229:         }
 230:       w = total;
 231:       h = limit;
 232:         }
 233:       else
 234:         {
 235:       for (int i = 0; i < components.length; i++)
 236:         {
 237:           dims = components[i].getPreferredSize();
 238:           if (dims != null)
 239:             {
 240:           if (dims.width > limit)
 241:             limit = dims.width;
 242:           total += dims.height;
 243:             }
 244:         }
 245:       w = limit;
 246:       h = total;
 247:         }
 248: 
 249:       Insets insets = getInsets();
 250:       w += insets.left + insets.right;
 251:       h += insets.top + insets.bottom;
 252: 
 253:       Insets margin = getMargin();
 254:       if (margin != null)
 255:         {
 256:       w += margin.left + margin.right;
 257:       h += margin.top + margin.bottom;
 258:         }
 259: 
 260:       return new Dimension(w, h);
 261:     }
 262: 
 263:     /**
 264:      * This method is called when the given component  is removed from the
 265:      * container.
 266:      *
 267:      * @param comp The component removed.
 268:      */
 269:     public void removeLayoutComponent(Component comp)
 270:     {
 271:       // Do nothing.
 272:     }
 273:   }
 274: 
 275:   /**
 276:    * This is an extension of JSeparator used in toolbars. Unlike JSeparator,
 277:    * nothing is painted for this Separator, it is only blank space that
 278:    * separates components.
 279:    */
 280:   public static class Separator extends JSeparator
 281:   {
 282:     /** DOCUMENT ME! */
 283:     private static final long serialVersionUID = -1656745644823105219L;
 284: 
 285:     /**
 286:      * Creates a new Separator object.
 287:      */
 288:     public Separator()
 289:     {
 290:       super();
 291:     } // Separator()
 292: 
 293:     /**
 294:      * Creates a new Separator object with the given size.
 295:      *
 296:      * @param size The size of the separator.
 297:      */
 298:     public Separator(Dimension size)
 299:     {
 300:       setPreferredSize(size);
 301:     } // Separator()
 302: 
 303:     /**
 304:      * This method returns the String ID of the UI class of  Separator.
 305:      *
 306:      * @return The UI class' String ID.
 307:      */
 308:     public String getUIClassID()
 309:     {
 310:       return "ToolBarSeparatorUI";
 311:     } // getUIClassID()
 312: 
 313:     /**
 314:      * This method returns the preferred size of the Separator.
 315:      *
 316:      * @return The preferred size of the Separator.
 317:      */
 318:     public Dimension getPreferredSize()
 319:     {
 320:       return super.getPreferredSize();
 321:     } // getPreferredSize()
 322: 
 323:     /**
 324:      * This method returns the maximum size of the Separator.
 325:      *
 326:      * @return The maximum size of the Separator.
 327:      */
 328:     public Dimension getMaximumSize()
 329:     {
 330:       return super.getPreferredSize();
 331:     } // getMaximumSize()
 332: 
 333:     /**
 334:      * This method returns the minimum size of the Separator.
 335:      *
 336:      * @return The minimum size of the Separator.
 337:      */
 338:     public Dimension getMinimumSize()
 339:     {
 340:       return super.getPreferredSize();
 341:     } // getMinimumSize()
 342: 
 343:     /**
 344:      * This method returns the size of the Separator.
 345:      *
 346:      * @return The size of the Separator.
 347:      */
 348:     public Dimension getSeparatorSize()
 349:     {
 350:       return super.getPreferredSize();
 351:     } // getSeparatorSize()
 352: 
 353:     /**
 354:      * This method sets the size of the Separator.
 355:      *
 356:      * @param size The new size of the Separator.
 357:      */
 358:     public void setSeparatorSize(Dimension size)
 359:     {
 360:       setPreferredSize(size);
 361:     } // setSeparatorSize()
 362:   } // Separator
 363: 
 364:   /** DOCUMENT ME! */
 365:   private static final long serialVersionUID = -1269915519555129643L;
 366: 
 367:   /** Whether the JToolBar paints its border. */
 368:   private transient boolean paintBorder = true;
 369: 
 370:   /** The extra insets around the JToolBar. */
 371:   private transient Insets margin;
 372: 
 373:   /** Whether the JToolBar can float (and be dragged around). */
 374:   private transient boolean floatable = true;
 375: 
 376:   /** Whether the buttons will have rollover borders. */
 377:   private transient boolean rollover;
 378: 
 379:   /** The orientation of the JToolBar. */
 380:   private int orientation = HORIZONTAL;
 381: 
 382:   /**
 383:    * This method creates a new JToolBar object with horizontal orientation
 384:    * and no name.
 385:    */
 386:   public JToolBar()
 387:   {
 388:     this(null, HORIZONTAL);
 389:   } // JToolBar()
 390: 
 391:   /**
 392:    * This method creates a new JToolBar with the given orientation and  no
 393:    * name.
 394:    *
 395:    * @param orientation JToolBar orientation (HORIZONTAL or VERTICAL)
 396:    */
 397:   public JToolBar(int orientation)
 398:   {
 399:     this(null, orientation);
 400:   } // JToolBar()
 401: 
 402:   /**
 403:    * This method creates a new JToolBar object with the given name and
 404:    * horizontal orientation.
 405:    *
 406:    * @param name Name assigned to undocked tool bar.
 407:    */
 408:   public JToolBar(String name)
 409:   {
 410:     this(name, HORIZONTAL);
 411:   } // JToolBar()
 412: 
 413:   /**
 414:    * This method creates a new JToolBar object with the given name and
 415:    * orientation.
 416:    *
 417:    * @param name Name assigned to undocked tool bar.
 418:    * @param orientation JToolBar orientation (HORIZONTAL or VERTICAL)
 419:    */
 420:   public JToolBar(String name, int orientation)
 421:   {
 422:     setName(name);
 423:     setOrientation(orientation);
 424:     setLayout(new DefaultToolBarLayout());
 425:     revalidate();
 426:     updateUI();
 427:   } // JToolBar()
 428: 
 429:   /**
 430:    * This method adds a new JButton that performs the given Action to the
 431:    * JToolBar.
 432:    *
 433:    * @param action The Action to add to the JToolBar.
 434:    *
 435:    * @return The JButton that wraps the Action.
 436:    */
 437:   public JButton add(Action action)
 438:   {
 439:     JButton b = createActionComponent(action);
 440:     add(b);
 441:     return b;
 442:   } // add()
 443: 
 444:   /**
 445:    * This method paints the border if the borderPainted property is true.
 446:    *
 447:    * @param graphics The graphics object to paint with.
 448:    */
 449:   protected void paintBorder(Graphics graphics)
 450:   {
 451:     if (paintBorder && isFloatable())
 452:       super.paintBorder(graphics);
 453:   } // paintBorder()
 454: 
 455:   /**
 456:    * This method returns the UI class used to paint this JToolBar.
 457:    *
 458:    * @return The UI class for this JToolBar.
 459:    */
 460:   public ToolBarUI getUI()
 461:   {
 462:     return (ToolBarUI) ui;
 463:   } // getUI()
 464: 
 465:   /**
 466:    * This method sets the UI used with the JToolBar.
 467:    *
 468:    * @param ui The UI used with the JToolBar.
 469:    */
 470:   public void setUI(ToolBarUI ui)
 471:   {
 472:     super.setUI(ui);
 473:   } // setUI()
 474: 
 475:   /**
 476:    * This method resets the UI used to the Look and Feel defaults.
 477:    */
 478:   public void updateUI()
 479:   {
 480:     setUI((ToolBarUI) UIManager.getUI(this));
 481:     revalidate();
 482:     repaint();
 483:   } // updateUI()
 484: 
 485:   /**
 486:    * This method returns the String identifier for the UI class to the used
 487:    * with the JToolBar.
 488:    *
 489:    * @return The String identifier for the UI class.
 490:    */
 491:   public String getUIClassID()
 492:   {
 493:     return "ToolBarUI";
 494:   } // getUIClassID()
 495: 
 496:   /**
 497:    * This method sets the rollover property for the JToolBar. In rollover
 498:    * mode, JButtons inside the JToolBar will only display their borders when
 499:    * the mouse is moving over them.
 500:    *
 501:    * @param b The new rollover property.
 502:    */
 503:   public void setRollover(boolean b)
 504:   {
 505:     if (b != rollover)
 506:       {
 507:     rollover = b;
 508:     firePropertyChange("rollover", ! rollover, rollover);
 509:     revalidate();
 510:     repaint();
 511:       }
 512:   }
 513: 
 514:   /**
 515:    * This method returns the rollover property.
 516:    *
 517:    * @return The rollover property.
 518:    */
 519:   public boolean isRollover()
 520:   {
 521:     return rollover;
 522:   }
 523: 
 524:   /**
 525:    * This method returns the index of the given component.
 526:    *
 527:    * @param component The component to find.
 528:    *
 529:    * @return The index of the given component.
 530:    */
 531:   public int getComponentIndex(Component component)
 532:   {
 533:     Component[] components = getComponents();
 534:     if (components == null)
 535:       return -1;
 536: 
 537:     for (int i = 0; i < components.length; i++)
 538:       if (components[i] == component)
 539:     return i;
 540: 
 541:     return -1;
 542:   } // getComponentIndex()
 543: 
 544:   /**
 545:    * This method returns the component at the given index.
 546:    *
 547:    * @param index The index of the component.
 548:    *
 549:    * @return The component at the given index.
 550:    */
 551:   public Component getComponentAtIndex(int index)
 552:   {
 553:     return getComponent(index);
 554:   } // getComponentAtIndex()
 555: 
 556:   /**
 557:    * This method returns the margin property.
 558:    *
 559:    * @return The margin property.
 560:    */
 561:   public Insets getMargin()
 562:   {
 563:     return margin;
 564:   } // getMargin()
 565: 
 566:   /**
 567:    * This method sets the margin property. The margin property determines the
 568:    * extra space between the children components of the JToolBar and the
 569:    * border.
 570:    *
 571:    * @param margin The margin property.
 572:    */
 573:   public void setMargin(Insets margin)
 574:   {
 575:     if ((this.margin != null && margin == null)
 576:         || (this.margin == null && margin != null)
 577:         || (margin != null && this.margin != null
 578:         && (margin.left != this.margin.left
 579:         || margin.right != this.margin.right || margin.top != this.margin.top
 580:         || margin.bottom != this.margin.bottom)))
 581:       {
 582:     Insets oldMargin = this.margin;
 583:     this.margin = margin;
 584:     firePropertyChange("margin", oldMargin, this.margin);
 585:     revalidate();
 586:     repaint();
 587:       }
 588:   } // setMargin()
 589: 
 590:   /**
 591:    * This method returns the borderPainted property.
 592:    *
 593:    * @return The borderPainted property.
 594:    */
 595:   public boolean isBorderPainted()
 596:   {
 597:     return paintBorder;
 598:   } // isBorderPainted()
 599: 
 600:   /**
 601:    * This method sets the borderPainted property. If set to false, the border
 602:    * will not be painted.
 603:    *
 604:    * @param painted Whether the border will be painted.
 605:    */
 606:   public void setBorderPainted(boolean painted)
 607:   {
 608:     if (painted != paintBorder)
 609:       {
 610:     paintBorder = painted;
 611:     firePropertyChange("borderPainted", ! paintBorder,
 612:                        paintBorder);
 613:     repaint();
 614:       }
 615:   } // setBorderPainted()
 616: 
 617:   /**
 618:    * This method returns the floatable property.
 619:    *
 620:    * @return The floatable property.
 621:    */
 622:   public boolean isFloatable()
 623:   {
 624:     return floatable;
 625:   } // isFloatable()
 626: 
 627:   /**
 628:    * This method sets the floatable property. If set to false, the JToolBar
 629:    * cannot be dragged.
 630:    *
 631:    * @param floatable Whether the JToolBar can be dragged.
 632:    */
 633:   public void setFloatable(boolean floatable)
 634:   {
 635:     if (floatable != this.floatable)
 636:       {
 637:     this.floatable = floatable;
 638:     firePropertyChange("floatable", ! floatable, floatable);
 639:       }
 640:   } // setFloatable()
 641: 
 642:   /**
 643:    * This method returns the orientation of the JToolBar.
 644:    *
 645:    * @return The orientation of the JToolBar.
 646:    */
 647:   public int getOrientation()
 648:   {
 649:     return orientation;
 650:   } // getOrientation()
 651: 
 652:   /**
 653:    * This method sets the layout manager to be used with the JToolBar.
 654:    *
 655:    * @param mgr The Layout Manager used with the JToolBar.
 656:    */
 657:   public void setLayout(LayoutManager mgr)
 658:   {
 659:     super.setLayout(mgr);
 660:     revalidate();
 661:     repaint();
 662:   } // setLayout()
 663: 
 664:   /**
 665:    * This method sets the orientation property for JToolBar.
 666:    *
 667:    * @param orientation The new orientation for JToolBar.
 668:    *
 669:    * @throws IllegalArgumentException If the orientation is not HORIZONTAL or
 670:    *         VERTICAL.
 671:    */
 672:   public void setOrientation(int orientation)
 673:   {
 674:     if (orientation != HORIZONTAL && orientation != VERTICAL)
 675:       throw new IllegalArgumentException(orientation
 676:                                          + " is not a legal orientation");
 677:     if (orientation != this.orientation)
 678:       {
 679:     int oldOrientation = this.orientation;
 680:     this.orientation = orientation;
 681:     firePropertyChange("orientation", oldOrientation, this.orientation);
 682:     revalidate();
 683:     repaint();
 684:       }
 685:   } // setOrientation()
 686: 
 687:   /**
 688:    * This method adds a Separator of default size to the JToolBar.
 689:    */
 690:   public void addSeparator()
 691:   {
 692:     add(new Separator());
 693:   } // addSeparator()
 694: 
 695:   /**
 696:    * This method adds a Separator with the given size to the JToolBar.
 697:    *
 698:    * @param size The size of the Separator.
 699:    */
 700:   public void addSeparator(Dimension size)
 701:   {
 702:     add(new Separator(size));
 703:   } // addSeparator()
 704: 
 705:   /**
 706:    * This method is used to create JButtons which can be added to the JToolBar
 707:    * for the given action.
 708:    *
 709:    * @param action The action to create a JButton for.
 710:    *
 711:    * @return The JButton created from the action.
 712:    */
 713:   protected JButton createActionComponent(Action action)
 714:   {
 715:     return new JButton(action);
 716:   } // createActionComponent()
 717: 
 718:   /**
 719:    * This method creates a pre-configured PropertyChangeListener which updates
 720:    * the control as changes are made to the Action. However, this is no
 721:    * longer the recommended way of adding Actions to Containers. As such,
 722:    * this method returns null.
 723:    *
 724:    * @param button The JButton to configure a PropertyChangeListener for.
 725:    *
 726:    * @return null.
 727:    */
 728:   protected PropertyChangeListener createActionChangeListener(JButton button)
 729:   {
 730:     // XXX: As specified, this returns null. But seems kind of strange, usually deprecated methods don't just return null, verify!
 731:     return null;
 732:   } // createActionChangeListener()
 733: 
 734:   /**
 735:    * This method overrides Container's addImpl method. If a JButton is added,
 736:    * it is disabled.
 737:    *
 738:    * @param component The Component to add.
 739:    * @param constraints The Constraints placed on the component.
 740:    * @param index The index to place the Component at.
 741:    */
 742:   protected void addImpl(Component component, Object constraints, int index)
 743:   {
 744:     // XXX: Sun says disable button but test cases show otherwise.
 745:     super.addImpl(component, constraints, index);
 746: 
 747:     // if we added a Swing Button then adjust this a little
 748:     if (component instanceof AbstractButton)
 749:       {
 750:         AbstractButton b = (AbstractButton) component;
 751:         b.setRolloverEnabled(rollover);
 752:         b.updateUI();
 753:       }
 754: 
 755:   } // addImpl()
 756: 
 757:   /**
 758:    * This method returns a String description of the JToolBar.
 759:    *
 760:    * @return A String description of the JToolBar.
 761:    */
 762:   protected String paramString()
 763:   {
 764:     return "JToolBar";
 765:   } // paramString()
 766: 
 767:   /**
 768:    * getAccessibleContext
 769:    *
 770:    * @return AccessibleContext
 771:    */
 772:   public AccessibleContext getAccessibleContext()
 773:   {
 774:     if (accessibleContext == null)
 775:       accessibleContext = new AccessibleJToolBar();
 776: 
 777:     return accessibleContext;
 778:   }
 779: }