Source for javax.swing.JTabbedPane

   1: /* JTabbedPane.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 gnu.classpath.NotImplementedException;
  42: 
  43: import java.awt.Color;
  44: import java.awt.Component;
  45: import java.awt.Point;
  46: import java.awt.Rectangle;
  47: import java.awt.event.MouseEvent;
  48: import java.io.Serializable;
  49: import java.util.Locale;
  50: import java.util.Vector;
  51: 
  52: import javax.accessibility.Accessible;
  53: import javax.accessibility.AccessibleContext;
  54: import javax.accessibility.AccessibleRole;
  55: import javax.accessibility.AccessibleSelection;
  56: import javax.accessibility.AccessibleStateSet;
  57: import javax.swing.event.ChangeEvent;
  58: import javax.swing.event.ChangeListener;
  59: import javax.swing.plaf.TabbedPaneUI;
  60: import javax.swing.plaf.UIResource;
  61: 
  62: /**
  63:  * This is a container for components where only one component is displayed at
  64:  * a given time and the displayed component can be switched by clicking on
  65:  * tabs.
  66:  * 
  67:  * <p>
  68:  * Tabs can be oriented in several ways. They can be above, below, left and
  69:  * right of the component. Tabs can either wrap around (by creating multiple
  70:  * rows of tabs) or they can be scrolled (where only a subset of the  tabs
  71:  * can be seen at once). More tabs can be added by calling the
  72:  * add/addTab/insertTab methods.
  73:  * </p>
  74:  */
  75: public class JTabbedPane extends JComponent implements Serializable,
  76:                                                        Accessible,
  77:                                                        SwingConstants
  78: {
  79:   /**
  80:    * Accessibility support for <code>JTabbedPane</code>.
  81:    */
  82:   // FIXME: This inner class is a complete stub and must be implemented
  83:   // properly.
  84:   protected class AccessibleJTabbedPane extends JComponent.AccessibleJComponent
  85:     implements AccessibleSelection, ChangeListener
  86:   {
  87:     /**
  88:      * The serialization UID.
  89:      */
  90:     private static final long serialVersionUID = 7610530885966830483L;
  91: 
  92:     /**
  93:      * Creates a new AccessibleJTabbedPane object.
  94:      */
  95:     public AccessibleJTabbedPane()
  96:     {
  97:       super();
  98:     }
  99: 
 100:     /**
 101:      * Receives notification when the selection state of the
 102:      * <code>JTabbedPane</code> changes.
 103:      *
 104:      * @param e the change event describing the change
 105:      */
 106:     public void stateChanged(ChangeEvent e)
 107:       throws NotImplementedException
 108:     {
 109:       // Implement this properly.
 110:     }
 111: 
 112:     /**
 113:      * Returns the accessible role of the <code>JTabbedPane</code>, which is
 114:      * {@link AccessibleRole#PAGE_TAB_LIST}.
 115:      *
 116:      * @return the accessible role of the <code>JTabbedPane</code>
 117:      */
 118:     public AccessibleRole getAccessibleRole()
 119:       throws NotImplementedException
 120:     {
 121:       return null;
 122:     }
 123: 
 124:     /**
 125:      * Returns the number of accessible child components of the
 126:      * <code>JTabbedPane</code>.
 127:      *
 128:      * @return the number of accessible child components of the
 129:      *         <code>JTabbedPane</code>
 130:      */
 131:     public int getAccessibleChildrenCount()
 132:       throws NotImplementedException
 133:     {
 134:       return 0;
 135:     }
 136: 
 137:     /**
 138:      * Returns the accessible child component at the specified index.
 139:      *
 140:      * @param i the index of the child component to fetch
 141:      *
 142:      * @return the accessible child component at the specified index
 143:      */
 144:     public Accessible getAccessibleChild(int i)
 145:     {
 146:       // Testing shows that the reference implementation returns instances
 147:       // of page here.
 148:       Accessible child = null;
 149:       if (i >= 0 && i < tabs.size())
 150:         child = (Page) tabs.get(i);
 151:       return child;
 152:     }
 153: 
 154:     /**
 155:      * Returns the current selection state of the <code>JTabbedPane</code>
 156:      * as AccessibleSelection object.
 157:      *
 158:      * @return the current selection state of the <code>JTabbedPane</code>
 159:      */
 160:     public AccessibleSelection getAccessibleSelection()
 161:       throws NotImplementedException
 162:     {
 163:       return null;
 164:     }
 165: 
 166:     /**
 167:      * Returns the accessible child component at the specified coordinates.
 168:      * If there is no child component at this location, then return the
 169:      * currently selected tab.
 170:      *
 171:      * @param p the coordinates at which to look up the child component
 172:      *
 173:      * @return the accessible child component at the specified coordinates or
 174:      *         the currently selected tab if there is no child component at
 175:      *         this location
 176:      */
 177:     public Accessible getAccessibleAt(Point p)
 178:       throws NotImplementedException
 179:     {
 180:       return null;
 181:     }
 182: 
 183:     /**
 184:      * The number of selected child components of the
 185:      * <code>JTabbedPane</code>. This will be <code>0</code> if the
 186:      * <code>JTabbedPane</code> has no children, or <code>1</code> otherwise,
 187:      * since there is always exactly one tab selected. 
 188:      *
 189:      * @return number of selected child components of the
 190:      *         <code>JTabbedPane</code>
 191:      */
 192:     public int getAccessibleSelectionCount()
 193:       throws NotImplementedException
 194:     {
 195:       return 0;
 196:     }
 197: 
 198:     /**
 199:      * DOCUMENT ME!
 200:      *
 201:      * @param i DOCUMENT ME!
 202:      *
 203:      * @return DOCUMENT ME!
 204:      */
 205:     public Accessible getAccessibleSelection(int i)
 206:       throws NotImplementedException
 207:     {
 208:       return null;
 209:     }
 210: 
 211:     /**
 212:      * DOCUMENT ME!
 213:      *
 214:      * @param i DOCUMENT ME!
 215:      *
 216:      * @return DOCUMENT ME!
 217:      */
 218:     public boolean isAccessibleChildSelected(int i)
 219:       throws NotImplementedException
 220:     {
 221:       return false;
 222:     }
 223: 
 224:     /**
 225:      * DOCUMENT ME!
 226:      *
 227:      * @param i DOCUMENT ME!
 228:      */
 229:     public void addAccessibleSelection(int i)
 230:       throws NotImplementedException
 231:     {
 232:       // TODO: Implement this properly.
 233:     }
 234: 
 235:     /**
 236:      * DOCUMENT ME!
 237:      *
 238:      * @param i DOCUMENT ME!
 239:      */
 240:     public void removeAccessibleSelection(int i)
 241:       throws NotImplementedException
 242:     {
 243:       // TODO: Implement this properly.
 244:     }
 245: 
 246:     /**
 247:      * DOCUMENT ME!
 248:      */
 249:     public void clearAccessibleSelection()
 250:       throws NotImplementedException
 251:     {
 252:       // TODO: Implement this properly.
 253:     }
 254: 
 255:     /**
 256:      * DOCUMENT ME!
 257:      */
 258:     public void selectAllAccessibleSelection()
 259:       throws NotImplementedException
 260:     {
 261:       // TODO: Implement this properly.
 262:     }
 263:   }
 264: 
 265:   /**
 266:    * A helper class that listens for changes to the model.
 267:    */
 268:   protected class ModelListener implements ChangeListener, Serializable
 269:   {
 270:     /** DOCUMENT ME! */
 271:     private static final long serialVersionUID = 497359819958114132L;
 272: 
 273:     /**
 274:      * Creates a new ModelListener object.
 275:      */
 276:     protected ModelListener()
 277:     {
 278:       // Nothing to do here.
 279:     }
 280: 
 281:     /**
 282:      * This method is called whenever the model  is changed.
 283:      *
 284:      * @param e The ChangeEvent that is passed from the model.
 285:      */
 286:     public void stateChanged(ChangeEvent e)
 287:     {
 288:       // Propagate to our listeners.
 289:       fireStateChanged();
 290:     }
 291:   }
 292: 
 293:   /**
 294:    * A private class that holds all the information  for each tab.
 295:    */
 296:   private class Page
 297:     extends AccessibleContext
 298:     implements Accessible
 299:   {
 300:     /** The tooltip string. */
 301:     private String tip;
 302: 
 303:     /** The component associated with the tab. */
 304:     private Component component;
 305: 
 306:     /** The active icon associated with the tab. */
 307:     private transient Icon icon;
 308: 
 309:     /** The disabled icon associated with the tab. */
 310:     private transient Icon disabledIcon;
 311: 
 312:     /** The tab's enabled status. */
 313:     private transient boolean enabled = true;
 314: 
 315:     /** The string painted on the tab. */
 316:     private transient String title;
 317: 
 318:     /** The background color of the tab. */
 319:     private transient Color bg;
 320: 
 321:     /** The foreground color of the tab. */
 322:     private transient Color fg;
 323: 
 324:     /** The mnemonic associated with the tab. */
 325:     private transient int mnemonicKey;
 326: 
 327:     /** The index of the underlined character in the string. */
 328:     private transient int underlinedChar = -1;
 329: 
 330:     /**
 331:      * Creates a new data storage for the tab.
 332:      *
 333:      * @param title The string displayed on the tab.
 334:      * @param icon The active icon displayed on the tab.
 335:      * @param component The component associated with the tab.
 336:      * @param tip The tooltip associated with the tab.
 337:      */
 338:     protected Page(String title, Icon icon, Component component, String tip)
 339:     {
 340:       this.title = title;
 341:       this.icon = icon;
 342:       this.component = component;
 343:       this.tip = tip;
 344:     }
 345: 
 346:     /**
 347:      * This method returns the component associated with the tab.
 348:      *
 349:      * @return The component associated with the tab.
 350:      */
 351:     public Component getComponent()
 352:     {
 353:       return component;
 354:     }
 355: 
 356:     /**
 357:      * This method sets the component associated with the tab.
 358:      *
 359:      * @param c The component associated with the tab.
 360:      */
 361:     public void setComponent(Component c)
 362:     {
 363:       int i = indexOfComponent(component);
 364:       insertTab(title, icon, c, tip, i);
 365:       component = c;
 366:       removeTabAt(i);
 367:     }
 368: 
 369:     /**
 370:      * This method returns the tooltip string.
 371:      *
 372:      * @return The tooltip string.
 373:      */
 374:     public String getTip()
 375:     {
 376:       return tip;
 377:     }
 378: 
 379:     /**
 380:      * This method sets the tooltip string.
 381:      *
 382:      * @param tip The tooltip string.
 383:      */
 384:     public void setTip(String tip)
 385:     {
 386:       this.tip = tip;
 387:     }
 388: 
 389:     /**
 390:      * This method returns the background color.
 391:      *
 392:      * @return The background color.
 393:      */
 394:     public Color getBackground()
 395:     {
 396:       Color background;
 397:       if (bg == null)
 398:         background = JTabbedPane.this.getBackground();
 399:       else
 400:         background = bg;
 401:       return background;
 402:     }
 403: 
 404:     /**
 405:      * This method sets the background color.
 406:      *
 407:      * @param background The background color.
 408:      */
 409:     public void setBackground(Color background)
 410:     {
 411:       bg = background;
 412:     }
 413: 
 414:     /**
 415:      * This method returns the foreground color.
 416:      *
 417:      * @return The foreground color.
 418:      */
 419:     public Color getForeground()
 420:     {
 421:       Color foreground;
 422:       if (fg == null)
 423:         foreground = JTabbedPane.this.getForeground();
 424:       else
 425:         foreground = fg;
 426:       return foreground;
 427:     }
 428: 
 429:     /**
 430:      * This method sets the foreground color.
 431:      *
 432:      * @param foreground The foreground color.
 433:      */
 434:     public void setForeground(Color foreground)
 435:     {
 436:       fg = foreground;
 437:     }
 438: 
 439:     /**
 440:      * This method returns the title associated with the tab.
 441:      *
 442:      * @return The title of the tab.
 443:      */
 444:     public String getTitle()
 445:     {
 446:       return title;
 447:     }
 448: 
 449:     /** DOCUMENT ME! */
 450:     private static final long serialVersionUID = 1614381073220130939L;
 451: 
 452:     /**
 453:      * This method sets the title of the tab.
 454:      *
 455:      * @param text The title of the tab.
 456:      */
 457:     public void setTitle(String text)
 458:     {
 459:       title = text;
 460:       if (title != null && title.length() <= underlinedChar)
 461:     setDisplayedMnemonicIndex(title.length() - 1);
 462:     }
 463: 
 464:     /**
 465:      * This method returns the active icon.
 466:      *
 467:      * @return The active icon.
 468:      */
 469:     public Icon getIcon()
 470:     {
 471:       return icon;
 472:     }
 473: 
 474:     /**
 475:      * This method sets the active icon.
 476:      *
 477:      * @param icon The active icon.
 478:      */
 479:     public void setIcon(Icon icon)
 480:     {
 481:       this.icon = icon;
 482:     }
 483: 
 484:     /**
 485:      * This method returns the disabled icon.
 486:      *
 487:      * @return The disabled icon.
 488:      */
 489:     public Icon getDisabledIcon()
 490:     {
 491:       if (disabledIcon == null && icon instanceof ImageIcon)
 492:     setDisabledIcon(icon);
 493:       return disabledIcon;
 494:     }
 495: 
 496:     /**
 497:      * This method sets the disabled icon.
 498:      *
 499:      * @param disabledIcon The disabled icon.
 500:      */
 501:     public void setDisabledIcon(Icon disabledIcon)
 502:     {
 503:       this.disabledIcon = disabledIcon;
 504:     }
 505: 
 506:     /**
 507:      * This method returns whether the tab is enabled.
 508:      *
 509:      * @return Whether the tab is enabled.
 510:      */
 511:     public boolean isEnabled()
 512:     {
 513:       return enabled;
 514:     }
 515: 
 516:     /**
 517:      * This method sets whether the tab is enabled.
 518:      *
 519:      * @param enabled Whether this tab is enabled.
 520:      */
 521:     public void setEnabled(boolean enabled)
 522:     {
 523:       this.enabled = enabled;
 524:     }
 525: 
 526:     /**
 527:      * This method returns the mnemonic.
 528:      *
 529:      * @return The mnemonic.
 530:      */
 531:     public int getMnemonic()
 532:     {
 533:       return mnemonicKey;
 534:     }
 535: 
 536:     /**
 537:      * This method sets the mnemonic. If the title is set, it will update the
 538:      * mnemonicIndex.
 539:      *
 540:      * @param key The mnemonic.
 541:      */
 542:     public void setMnemonic(int key)
 543:     {
 544:       setMnemonic((char) key);
 545:     }
 546: 
 547:     /**
 548:      * This method sets the mnemonic. If the title is set, it will update the
 549:      * mnemonicIndex.
 550:      *
 551:      * @param aChar The mnemonic.
 552:      */
 553:     public void setMnemonic(char aChar)
 554:     {
 555:       mnemonicKey = aChar;
 556:       if (title != null)
 557:     setDisplayedMnemonicIndex(title.indexOf(mnemonicKey));
 558:     }
 559: 
 560:     /**
 561:      * This method returns the mnemonicIndex.
 562:      *
 563:      * @return The mnemonicIndex.
 564:      */
 565:     public int getDisplayedMnemonicIndex()
 566:     {
 567:       return underlinedChar;
 568:     }
 569: 
 570:     /**
 571:      * This method sets the mnemonicIndex.
 572:      *
 573:      * @param index The mnemonicIndex.
 574:      *
 575:      * @throws IllegalArgumentException If index less than -1 || index greater
 576:      *         or equal to title.length.
 577:      */
 578:     public void setDisplayedMnemonicIndex(int index)
 579:       throws IllegalArgumentException
 580:     {
 581:       if (index < -1 || title != null && index >= title.length())
 582:     throw new IllegalArgumentException();
 583: 
 584:       if (title == null || mnemonicKey == 0 || (index > -1 && title.charAt(index) != mnemonicKey))
 585:     index = -1;
 586: 
 587:       underlinedChar = index;
 588:     }
 589: 
 590:     /**
 591:      * Returns the accessible context, which is this object itself.
 592:      *
 593:      * @return the accessible context, which is this object itself
 594:      */
 595:     public AccessibleContext getAccessibleContext()
 596:     {
 597:       return this;
 598:     }
 599: 
 600:     /**
 601:      * Returns the accessible role of this tab, which is always
 602:      * {@link AccessibleRole#PAGE_TAB}.
 603:      *
 604:      * @return the accessible role of this tab
 605:      */
 606:     public AccessibleRole getAccessibleRole()
 607:     {
 608:       return AccessibleRole.PAGE_TAB;
 609:     }
 610: 
 611:     public AccessibleStateSet getAccessibleStateSet()
 612:       throws NotImplementedException
 613:     {
 614:       // FIXME: Implement this properly.
 615:       return null;
 616:     }
 617: 
 618:     public int getAccessibleIndexInParent()
 619:       throws NotImplementedException
 620:     {
 621:       // FIXME: Implement this properly.
 622:       return 0;
 623:     }
 624: 
 625:     /**
 626:      * Returns the number of accessible children, which is always one (the
 627:      * component of this tab).
 628:      *
 629:      * @return the number of accessible children
 630:      */
 631:     public int getAccessibleChildrenCount()
 632:     {
 633:       return 1;
 634:     }
 635: 
 636:     /**
 637:      * Returns the accessible child of this tab, which is the component
 638:      * displayed by the tab.
 639:      *
 640:      * @return the accessible child of this tab
 641:      */
 642:     public Accessible getAccessibleChild(int i)
 643:     {
 644:       // A quick test shows that this method always returns the component
 645:       // displayed by the tab, regardless of the index.
 646:       return (Accessible) component;
 647:     }
 648: 
 649:     /**
 650:      * Returns the locale of this accessible object.
 651:      *
 652:      * @return the locale of this accessible object
 653:      */
 654:     public Locale getLocale()
 655:     {
 656:       // TODO: Is this ok?
 657:       return Locale.getDefault();
 658:     }
 659:   }
 660: 
 661:   private static final long serialVersionUID = 1614381073220130939L;
 662: 
 663:   /** The changeEvent used to fire changes to listeners. */
 664:   protected ChangeEvent changeEvent;
 665: 
 666:   /** The listener that listens to the model. */
 667:   protected ChangeListener changeListener;
 668: 
 669:   /** The model that describes this JTabbedPane. */
 670:   protected SingleSelectionModel model;
 671: 
 672:   /** Indicates that the TabbedPane is in scrolling mode. */
 673:   public static final int SCROLL_TAB_LAYOUT = 1;
 674: 
 675:   /** Indicates that the TabbedPane is in wrap mode. */
 676:   public static final int WRAP_TAB_LAYOUT = 0;
 677: 
 678:   /** The current tabPlacement of the TabbedPane. */
 679:   protected int tabPlacement = SwingConstants.TOP;
 680: 
 681:   /** The current tabLayoutPolicy of the TabbedPane. */
 682:   private transient int layoutPolicy;
 683: 
 684:   /** The list of tabs associated with the TabbedPane. */
 685:   transient Vector tabs = new Vector();
 686: 
 687:   /**
 688:    * Creates a new JTabbedPane object with tabs on top and using wrap tab
 689:    * layout.
 690:    */
 691:   public JTabbedPane()
 692:   {
 693:     this(SwingConstants.TOP, WRAP_TAB_LAYOUT);
 694:   }
 695: 
 696:   /**
 697:    * Creates a new JTabbedPane object using wrap tab layout  and the given
 698:    * <code>tabPlacement</code>, where <code>tabPlacement</code> can be one
 699:    * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or
 700:    * {@link #RIGHT}.
 701:    *
 702:    * @param tabPlacement where the tabs will be placed
 703:    */
 704:   public JTabbedPane(int tabPlacement)
 705:   {
 706:     this(tabPlacement, WRAP_TAB_LAYOUT);
 707:   }
 708: 
 709:   /**
 710:    * Creates a new JTabbedPane object with the given <code>tabPlacement</code>
 711:    * and <code>tabLayoutPolicy</code>. The <code>tabPlacement</code> can be one
 712:    * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or
 713:    * {@link #RIGHT}. The <code>tabLayoutPolicy</code> can be either
 714:    * {@link #SCROLL_TAB_LAYOUT} or {@link #WRAP_TAB_LAYOUT}.
 715:    *
 716:    * @param tabPlacement where the tabs will be placed
 717:    * @param tabLayoutPolicy the way tabs will be placed
 718:    *
 719:    * @throws IllegalArgumentException If tabLayoutPolicy or tabPlacement are
 720:    *         not valid.
 721:    */
 722:   public JTabbedPane(int tabPlacement, int tabLayoutPolicy)
 723:   {
 724:     if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT
 725:         && tabPlacement != LEFT)
 726:       throw new IllegalArgumentException("tabPlacement is not valid.");
 727:     if (tabLayoutPolicy != SCROLL_TAB_LAYOUT
 728:         && tabLayoutPolicy != WRAP_TAB_LAYOUT)
 729:       throw new IllegalArgumentException("tabLayoutPolicy is not valid.");
 730:     this.tabPlacement = tabPlacement;
 731:     layoutPolicy = tabLayoutPolicy;
 732:     
 733:     changeEvent = new ChangeEvent(this);
 734:     changeListener = createChangeListener();
 735: 
 736:     model = new DefaultSingleSelectionModel();
 737:     model.addChangeListener(changeListener);
 738: 
 739:     updateUI();
 740:   }
 741: 
 742:   /**
 743:    * This method returns the UI used to display the JTabbedPane.
 744:    *
 745:    * @return The UI used to display the JTabbedPane.
 746:    */
 747:   public TabbedPaneUI getUI()
 748:   {
 749:     return (TabbedPaneUI) ui;
 750:   }
 751: 
 752:   /**
 753:    * This method sets the UI used to display the JTabbedPane.
 754:    *
 755:    * @param ui The UI used to display the JTabbedPane.
 756:    */
 757:   public void setUI(TabbedPaneUI ui)
 758:   {
 759:     super.setUI(ui);
 760:   }
 761: 
 762:   /**
 763:    * This method restores the UI to the defaults given by the UIManager.
 764:    */
 765:   public void updateUI()
 766:   {
 767:     setUI((TabbedPaneUI) UIManager.getUI(this));
 768:   }
 769: 
 770:   /**
 771:    * This method returns a string identifier that  is used to determine which
 772:    * UI will be used with  the JTabbedPane.
 773:    *
 774:    * @return A string identifier for the UI.
 775:    */
 776:   public String getUIClassID()
 777:   {
 778:     return "TabbedPaneUI";
 779:   }
 780: 
 781:   /**
 782:    * This method creates a ChangeListener that is used to  listen to the model
 783:    * for events.
 784:    *
 785:    * @return A ChangeListener to listen to the model.
 786:    */
 787:   protected ChangeListener createChangeListener()
 788:   {
 789:     return new ModelListener();
 790:   }
 791: 
 792:   /**
 793:    * This method adds a ChangeListener to the JTabbedPane.
 794:    *
 795:    * @param l The ChangeListener to add.
 796:    */
 797:   public void addChangeListener(ChangeListener l)
 798:   {
 799:     listenerList.add(ChangeListener.class, l);
 800:   }
 801: 
 802:   /**
 803:    * This method removes a ChangeListener to the JTabbedPane.
 804:    *
 805:    * @param l The ChangeListener to remove.
 806:    */
 807:   public void removeChangeListener(ChangeListener l)
 808:   {
 809:     listenerList.remove(ChangeListener.class, l);
 810:   }
 811: 
 812:   /**
 813:    * This method fires a ChangeEvent to all the JTabbedPane's ChangeListeners.
 814:    */
 815:   protected void fireStateChanged()
 816:   {
 817:     Object[] changeListeners = listenerList.getListenerList();
 818:     if (changeEvent == null)
 819:       changeEvent = new ChangeEvent(this);
 820:     for (int i = changeListeners.length - 2; i >= 0; i -= 2)
 821:       {
 822:     if (changeListeners[i] == ChangeListener.class)
 823:       ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
 824:       }
 825:   }
 826: 
 827:   /**
 828:    * This method returns all ChangeListeners registered with the JTabbedPane.
 829:    *
 830:    * @return The ChangeListeners registered with the JTabbedPane.
 831:    */
 832:   public ChangeListener[] getChangeListeners()
 833:   {
 834:     return (ChangeListener[]) super.getListeners(ChangeListener.class);
 835:   }
 836: 
 837:   /**
 838:    * This method returns the model used with the JTabbedPane.
 839:    *
 840:    * @return The JTabbedPane's model.
 841:    */
 842:   public SingleSelectionModel getModel()
 843:   {
 844:     return model;
 845:   }
 846: 
 847:   /**
 848:    * This method changes the model property of the JTabbedPane.
 849:    *
 850:    * @param model The new model to use with the JTabbedPane.
 851:    */
 852:   public void setModel(SingleSelectionModel model)
 853:   {
 854:     if (model != this.model)
 855:       {
 856:     SingleSelectionModel oldModel = this.model;
 857:     this.model.removeChangeListener(changeListener);
 858:     this.model = model;
 859:     this.model.addChangeListener(changeListener);
 860:     firePropertyChange("model", oldModel, this.model);
 861:       }
 862:   }
 863: 
 864:   /**
 865:    * This method returns the tabPlacement.
 866:    *
 867:    * @return The tabPlacement used with the JTabbedPane.
 868:    */
 869:   public int getTabPlacement()
 870:   {
 871:     return tabPlacement;
 872:   }
 873: 
 874:   /**
 875:    * This method changes the tabPlacement property of the JTabbedPane.
 876:    *
 877:    * @param tabPlacement The tabPlacement to use.
 878:    *
 879:    * @throws IllegalArgumentException If tabPlacement is not one of TOP,
 880:    *         BOTTOM, LEFT, or RIGHT.
 881:    */
 882:   public void setTabPlacement(int tabPlacement)
 883:   {
 884:     if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT
 885:         && tabPlacement != LEFT)
 886:       throw new IllegalArgumentException("tabPlacement is not valid.");
 887:     if (tabPlacement != this.tabPlacement)
 888:       {
 889:     int oldPlacement = this.tabPlacement;
 890:     this.tabPlacement = tabPlacement;
 891:     firePropertyChange("tabPlacement", oldPlacement, this.tabPlacement);
 892:       }
 893:   }
 894: 
 895:   /**
 896:    * This method returns the tabLayoutPolicy.
 897:    *
 898:    * @return The tabLayoutPolicy.
 899:    */
 900:   public int getTabLayoutPolicy()
 901:   {
 902:     return layoutPolicy;
 903:   }
 904: 
 905:   /**
 906:    * This method changes the tabLayoutPolicy property of the JTabbedPane.
 907:    *
 908:    * @param tabLayoutPolicy The tabLayoutPolicy to use.
 909:    *
 910:    * @throws IllegalArgumentException If tabLayoutPolicy is not one of
 911:    *         SCROLL_TAB_LAYOUT or WRAP_TAB_LAYOUT.
 912:    */
 913:   public void setTabLayoutPolicy(int tabLayoutPolicy)
 914:   {
 915:     if (tabLayoutPolicy != SCROLL_TAB_LAYOUT
 916:         && tabLayoutPolicy != WRAP_TAB_LAYOUT)
 917:       throw new IllegalArgumentException("tabLayoutPolicy is not valid.");
 918:     if (tabLayoutPolicy != layoutPolicy)
 919:       {
 920:     int oldPolicy = layoutPolicy;
 921:     layoutPolicy = tabLayoutPolicy;
 922:     firePropertyChange("tabLayoutPolicy", oldPolicy, layoutPolicy);
 923:       }
 924:   }
 925: 
 926:   /**
 927:    * This method returns the index of the tab that is currently selected.
 928:    *
 929:    * @return The index of the selected tab.
 930:    */
 931:   public int getSelectedIndex()
 932:   {
 933:     return model.getSelectedIndex();
 934:   }
 935: 
 936:   /**
 937:    * This method checks the index.
 938:    *
 939:    * @param index The index to check.
 940:    * @param start DOCUMENT ME!
 941:    * @param end DOCUMENT ME!
 942:    *
 943:    * @throws IndexOutOfBoundsException DOCUMENT ME!
 944:    */
 945:   private void checkIndex(int index, int start, int end)
 946:   {
 947:     if (index < start || index >= end)
 948:       throw new IndexOutOfBoundsException("Index < " + start + " || Index >= "
 949:                                           + end);
 950:   }
 951: 
 952:   /**
 953:    * This method sets the selected index. This method will hide the old
 954:    * component and show the new component.
 955:    *
 956:    * @param index The index to set it at.
 957:    */
 958:   public void setSelectedIndex(int index)
 959:   {
 960:     checkIndex(index, -1, tabs.size());
 961:     if (index != getSelectedIndex())
 962:       {
 963:     if (getSelectedIndex() != -1 && getSelectedComponent() != null)
 964:       getSelectedComponent().hide();
 965:     if (index != -1 && getComponentAt(index) != null)
 966:       getComponentAt(index).show();
 967:     model.setSelectedIndex(index);
 968:       }
 969:   }
 970: 
 971:   /**
 972:    * This method returns the component at the selected index.
 973:    *
 974:    * @return The component at the selected index.
 975:    */
 976:   public Component getSelectedComponent()
 977:   {
 978:     int selectedIndex = getSelectedIndex();
 979:     Component selected = null;
 980:     if (selectedIndex >= 0)
 981:       selected = getComponentAt(selectedIndex);
 982:     return selected;
 983:   }
 984: 
 985:   /**
 986:    * This method sets the component at the selected index.
 987:    *
 988:    * @param c The component associated with the selected index.
 989:    */
 990:   public void setSelectedComponent(Component c)
 991:   {
 992:     if (c.getParent() == this)
 993:       setSelectedIndex(indexOfComponent(c));
 994:     else
 995:       setComponentAt(getSelectedIndex(), c);
 996:   }
 997: 
 998:   /**
 999:    * This method inserts tabs into JTabbedPane. This includes adding the
1000:    * component to the JTabbedPane and hiding it.
1001:    *
1002:    * @param title the title of the tab; may be <code>null</code>
1003:    * @param icon the tab's icon; may be <code>null</code>
1004:    * @param component the component associated with the tab
1005:    * @param tip the tooltip for the tab
1006:    * @param index the index to insert the tab at
1007:    */
1008:   public void insertTab(String title, Icon icon, Component component,
1009:                         String tip, int index)
1010:   {
1011:     if (title == null)
1012:       title = "";
1013:     Page p = new Page(title, icon, component, tip);
1014:     tabs.insertElementAt(p, index);
1015: 
1016:     // Hide the component so we don't see it. Do it before we parent it
1017:     // so we don't trigger a repaint.
1018:     if (component != null)
1019:       {
1020:     component.hide();
1021:     super.add(component);
1022:       }
1023: 
1024:     if (getSelectedIndex() == -1)
1025:       setSelectedIndex(0);
1026: 
1027:     revalidate();
1028:     repaint();
1029:   }
1030: 
1031:   /**
1032:    * This method adds a tab to the JTabbedPane.
1033:    *
1034:    * @param title the title of the tab; may be <code>null</code>
1035:    * @param icon the icon for the tab; may be <code>null</code>
1036:    * @param component the associated component
1037:    * @param tip the associated tooltip
1038:    */
1039:   public void addTab(String title, Icon icon, Component component, String tip)
1040:   {
1041:     insertTab(title, icon, component, tip, tabs.size());
1042:   }
1043: 
1044:   /**
1045:    * This method adds a tab to the JTabbedPane.
1046:    *
1047:    * @param title the title of the tab; may be <code>null</code>
1048:    * @param icon the icon for the tab; may be <code>null</code>
1049:    * @param component the associated component
1050:    */
1051:   public void addTab(String title, Icon icon, Component component)
1052:   {
1053:     insertTab(title, icon, component, null, tabs.size());
1054:   }
1055: 
1056:   /**
1057:    * This method adds a tab to the JTabbedPane.
1058:    *
1059:    * @param title the title of the tab; may be <code>null</code>
1060:    * @param component the associated component
1061:    */
1062:   public void addTab(String title, Component component)
1063:   {
1064:     insertTab(title, null, component, null, tabs.size());
1065:   }
1066: 
1067:   /**
1068:    * This method adds a tab to the JTabbedPane. The title of the tab is the
1069:    * Component's name. If the Component is an instance of UIResource, it
1070:    * doesn't add the tab and instead add the component directly to the
1071:    * JTabbedPane.
1072:    *
1073:    * @param component The associated component.
1074:    *
1075:    * @return The Component that was added.
1076:    */
1077:   public Component add(Component component)
1078:   {
1079:     if (component instanceof UIResource)
1080:       super.add(component);
1081:     else
1082:       insertTab(component.getName(), null, component, null, tabs.size());
1083:     
1084:     return component;
1085:   }
1086: 
1087:   /**
1088:    * This method adds a tab to the JTabbedPane. If the Component is an
1089:    * instance of UIResource, it doesn't add the tab and instead add the
1090:    * component directly to the JTabbedPane.
1091:    *
1092:    * @param title the title of the tab; may be <code>null</code>
1093:    * @param component the associated component
1094:    *
1095:    * @return The Component that was added.
1096:    */
1097:   public Component add(String title, Component component)
1098:   {
1099:     if (component instanceof UIResource)
1100:       super.add(component);
1101:     else
1102:       insertTab(title, null, component, null, tabs.size());
1103:     return component;
1104:   }
1105: 
1106:   /**
1107:    * This method adds a tab to the JTabbedPane. If the Component is an
1108:    * instance of UIResource, it doesn't add the tab and instead add the
1109:    * component directly to the JTabbedPane.
1110:    *
1111:    * @param component The associated component.
1112:    * @param index The index to insert the tab at.
1113:    *
1114:    * @return The Component that was added.
1115:    */
1116:   public Component add(Component component, int index)
1117:   {
1118:     if (component instanceof UIResource)
1119:       super.add(component);
1120:     else
1121:       insertTab(component.getName(), null, component, null, index);
1122:     return component;
1123:   }
1124: 
1125:   /**
1126:    * This method adds a tab to the JTabbedPane. If the Component is an
1127:    * instance of UIResource, it doesn't add the tab and instead add the
1128:    * component directly to the JTabbedPane. If the constraints object is an
1129:    * icon, it will be used as the tab's icon. If the constraints object is a
1130:    * string, we will use it as the title.
1131:    *
1132:    * @param component The associated component.
1133:    * @param constraints The constraints object.
1134:    */
1135:   public void add(Component component, Object constraints)
1136:   {
1137:     add(component, constraints, tabs.size());
1138:   }
1139: 
1140:   /**
1141:    * This method adds a tab to the JTabbedPane. If the Component is an
1142:    * instance of UIResource, it doesn't add the tab and instead add the
1143:    * component directly to the JTabbedPane. If the constraints object is an
1144:    * icon, it will be used as the tab's icon. If the constraints object is a
1145:    * string, we will use it as the title.
1146:    *
1147:    * @param component The associated component.
1148:    * @param constraints The constraints object.
1149:    * @param index The index to insert the tab at.
1150:    */
1151:   public void add(Component component, Object constraints, int index)
1152:   {
1153:     if (component instanceof UIResource)
1154:       super.add(component);
1155:     else
1156:       {
1157:     if (constraints instanceof String)
1158:       insertTab((String) constraints, null, component, null, index);
1159:     else
1160:       insertTab(component.getName(),
1161:                 (constraints instanceof Icon) ? (Icon) constraints : null,
1162:                 component, null, index);
1163:       }
1164:   }
1165: 
1166:   /**
1167:    * Removes the tab at index. After the component associated with 
1168:    * index is removed, its visibility is reset to true to ensure it 
1169:    * will be visible if added to other containers.
1170:    *
1171:    * @param index The index of the tab to remove.
1172:    */
1173:   public void removeTabAt(int index)
1174:   {
1175:     checkIndex(index, 0, tabs.size());
1176: 
1177:     // We need to adjust the selection if we remove a tab that comes
1178:     // before the selected tab or if the selected tab is removed.
1179:     // This decrements the selected index by 1 if any of this is the case.
1180:     // Note that this covers all cases:
1181:     // - When the selected tab comes after the removed tab, this simply
1182:     //   adjusts the selection so that after the removal the selected tab
1183:     //   is still the same.
1184:     // - When we remove the currently selected tab, then the tab before the
1185:     //   selected tab gets selected.
1186:     // - When the last tab is removed, then we have an index==0, which gets
1187:     //   decremented to -1, which means no selection, which is 100% perfect.
1188:     int selectedIndex = getSelectedIndex();
1189:     if (selectedIndex >= index)
1190:       setSelectedIndex(selectedIndex - 1);
1191: 
1192:     Component comp = getComponentAt(index);
1193: 
1194:     // Remove the tab object.
1195:     tabs.remove(index);
1196: 
1197:     // Remove the component. I think we cannot assume that the tab order
1198:     // is equal to the component order, so we iterate over the children
1199:     // here to find the and remove the correct component.
1200:     if (comp != null)
1201:       {
1202:         Component[] children = getComponents();
1203:         for (int i = children.length - 1; i >= 0; --i)
1204:           {
1205:             if (children[i] == comp)
1206:               {
1207:                 super.remove(i);
1208:                 comp.setVisible(true);
1209:                 break;
1210:               }
1211:           }
1212:       }
1213:     revalidate();
1214:     repaint();
1215:   }
1216: 
1217:   /**
1218:    * Removes the specified Component from the JTabbedPane.
1219:    *
1220:    * @param component The Component to remove.
1221:    */
1222:   public void remove(Component component)
1223:   {
1224:     super.remove(component);
1225:   }
1226: 
1227:   /**
1228:    * Removes the tab and component which corresponds to the specified index.
1229:    *
1230:    * @param index The index of the tab to remove.
1231:    */
1232:   public void remove(int index)
1233:   {
1234:     super.remove(index);
1235:     removeTabAt(index);
1236:   }
1237: 
1238:   /**
1239:    * This method removes all tabs and associated components from the
1240:    * JTabbedPane.
1241:    */
1242:   public void removeAll()
1243:   {
1244:     setSelectedIndex(-1);
1245:     for (int i = getTabCount() - 1; i >= 0; i--)
1246:       removeTabAt(i);
1247:   }
1248: 
1249:   /**
1250:    * This method returns how many tabs are in the JTabbedPane.
1251:    *
1252:    * @return The number of tabs in the JTabbedPane.
1253:    */
1254:   public int getTabCount()
1255:   {
1256:     return tabs.size();
1257:   }
1258: 
1259:   /**
1260:    * This method returns the number of runs used  to paint the JTabbedPane.
1261:    *
1262:    * @return The number of runs.
1263:    */
1264:   public int getTabRunCount()
1265:   {
1266:     return ((TabbedPaneUI) ui).getTabRunCount(this);
1267:   }
1268: 
1269:   /**
1270:    * This method returns the tab title given the index.
1271:    *
1272:    * @param index The index of the tab.
1273:    *
1274:    * @return The title for the tab.
1275:    */
1276:   public String getTitleAt(int index)
1277:   {
1278:     checkIndex(index, 0, tabs.size());
1279:     return ((Page) tabs.elementAt(index)).getTitle();
1280:   }
1281: 
1282:   /**
1283:    * This method returns the active icon given the index.
1284:    *
1285:    * @param index The index of the tab.
1286:    *
1287:    * @return The active icon for the tab.
1288:    */
1289:   public Icon getIconAt(int index)
1290:   {
1291:     checkIndex(index, 0, tabs.size());
1292:     return ((Page) tabs.elementAt(index)).getIcon();
1293:   }
1294: 
1295:   /**
1296:    * This method returns the disabled icon given the index.
1297:    *
1298:    * @param index The index of the tab.
1299:    *
1300:    * @return The disabled icon for the tab.
1301:    */
1302:   public Icon getDisabledIconAt(int index)
1303:   {
1304:     checkIndex(index, 0, tabs.size());
1305:     return ((Page) tabs.elementAt(index)).getDisabledIcon();
1306:   }
1307: 
1308:   /**
1309:    * This method returns the tooltip string for the tab.
1310:    *
1311:    * @param index The index of the tab.
1312:    *
1313:    * @return The tooltip string for the tab.
1314:    */
1315:   public String getToolTipTextAt(int index)
1316:   {
1317:     checkIndex(index, 0, tabs.size());
1318:     return ((Page) tabs.elementAt(index)).getTip();
1319:   }
1320: 
1321:   /**
1322:    * This method returns the foreground color for the tab.
1323:    *
1324:    * @param index The index of the tab.
1325:    *
1326:    * @return The foreground color for the tab.
1327:    */
1328:   public Color getForegroundAt(int index)
1329:   {
1330:     checkIndex(index, 0, tabs.size());
1331:     return ((Page) tabs.elementAt(index)).getForeground();
1332:   }
1333: 
1334:   /**
1335:    * This method returns the background color for the tab.
1336:    *
1337:    * @param index The index of the tab.
1338:    *
1339:    * @return The background color for the tab.
1340:    */
1341:   public Color getBackgroundAt(int index)
1342:   {
1343:     checkIndex(index, 0, tabs.size());
1344:     return ((Page) tabs.elementAt(index)).getBackground();
1345:   }
1346: 
1347:   /**
1348:    * This method returns the component associated with the tab.
1349:    *
1350:    * @param index The index of the tab.
1351:    *
1352:    * @return The component associated with the tab.
1353:    */
1354:   public Component getComponentAt(int index)
1355:   {
1356:     checkIndex(index, 0, tabs.size());
1357:     return ((Page) tabs.elementAt(index)).getComponent();
1358:   }
1359: 
1360:   /**
1361:    * This method returns whether this tab is enabled. Disabled tabs cannot be
1362:    * selected.
1363:    *
1364:    * @param index The index of the tab.
1365:    *
1366:    * @return Whether the tab is enabled.
1367:    */
1368:   public boolean isEnabledAt(int index)
1369:   {
1370:     checkIndex(index, 0, tabs.size());
1371:     return ((Page) tabs.elementAt(index)).isEnabled();
1372:   }
1373: 
1374:   /**
1375:    * This method returns the mnemonic for the tab.
1376:    *
1377:    * @param tabIndex The index of the tab.
1378:    *
1379:    * @return The mnemonic for the tab.
1380:    */
1381:   public int getMnemonicAt(int tabIndex)
1382:   {
1383:     checkIndex(tabIndex, 0, tabs.size());
1384:     return ((Page) tabs.elementAt(tabIndex)).getMnemonic();
1385:   }
1386: 
1387:   /**
1388:    * This method returns the mnemonic index for the tab.
1389:    *
1390:    * @param tabIndex The index of the tab.
1391:    *
1392:    * @return The mnemonic index for the tab.
1393:    */
1394:   public int getDisplayedMnemonicIndexAt(int tabIndex)
1395:   {
1396:     checkIndex(tabIndex, 0, tabs.size());
1397:     return ((Page) tabs.elementAt(tabIndex)).getDisplayedMnemonicIndex();
1398:   }
1399: 
1400:   /**
1401:    * This method returns the bounds of the tab given the index.
1402:    *
1403:    * @param index The index of the tab.
1404:    *
1405:    * @return A rectangle describing the bounds of the tab.
1406:    */
1407:   public Rectangle getBoundsAt(int index)
1408:   {
1409:     checkIndex(index, 0, tabs.size());
1410:     return ((TabbedPaneUI) ui).getTabBounds(this, index);
1411:   }
1412: 
1413:   /**
1414:    * This method sets the title of the tab.
1415:    *
1416:    * @param index The index of the tab.
1417:    * @param title The new title.
1418:    */
1419:   public void setTitleAt(int index, String title)
1420:   {
1421:     checkIndex(index, 0, tabs.size());
1422:     ((Page) tabs.elementAt(index)).setTitle(title);
1423:   }
1424: 
1425:   /**
1426:    * This method sets the icon of the tab.
1427:    *
1428:    * @param index The index of the tab.
1429:    * @param icon The new icon.
1430:    */
1431:   public void setIconAt(int index, Icon icon)
1432:   {
1433:     checkIndex(index, 0, tabs.size());
1434:     ((Page) tabs.elementAt(index)).setIcon(icon);
1435:   }
1436: 
1437:   /**
1438:    * This method sets the disabled icon of the tab.
1439:    *
1440:    * @param index The index of the tab.
1441:    * @param disabledIcon The new disabled icon.
1442:    */
1443:   public void setDisabledIconAt(int index, Icon disabledIcon)
1444:   {
1445:     checkIndex(index, 0, tabs.size());
1446:     ((Page) tabs.elementAt(index)).setDisabledIcon(disabledIcon);
1447:   }
1448: 
1449:   /**
1450:    * This method sets the tooltip text of the tab.
1451:    *
1452:    * @param index The index of the tab.
1453:    * @param toolTipText The tooltip text.
1454:    */
1455:   public void setToolTipTextAt(int index, String toolTipText)
1456:   {
1457:     checkIndex(index, 0, tabs.size());
1458:     ((Page) tabs.elementAt(index)).setTip(toolTipText);
1459:   }
1460: 
1461:   /**
1462:    * This method sets the background color of the tab.
1463:    *
1464:    * @param index The index of the tab.
1465:    * @param background The background color of the tab.
1466:    */
1467:   public void setBackgroundAt(int index, Color background)
1468:   {
1469:     checkIndex(index, 0, tabs.size());
1470:     ((Page) tabs.elementAt(index)).setBackground(background);
1471:   }
1472: 
1473:   /**
1474:    * This method sets the foreground color of the tab.
1475:    *
1476:    * @param index The index of the tab.
1477:    * @param foreground The foreground color of the tab.
1478:    */
1479:   public void setForegroundAt(int index, Color foreground)
1480:   {
1481:     checkIndex(index, 0, tabs.size());
1482:     ((Page) tabs.elementAt(index)).setForeground(foreground);
1483:   }
1484: 
1485:   /**
1486:    * This method sets whether the tab is enabled.
1487:    *
1488:    * @param index The index of the tab.
1489:    * @param enabled Whether the tab is enabled.
1490:    */
1491:   public void setEnabledAt(int index, boolean enabled)
1492:   {
1493:     checkIndex(index, 0, tabs.size());
1494:     ((Page) tabs.elementAt(index)).setEnabled(enabled);
1495:   }
1496: 
1497:   /**
1498:    * This method sets the component associated with the tab.
1499:    *
1500:    * @param index The index of the tab.
1501:    * @param component The component associated with the tab.
1502:    */
1503:   public void setComponentAt(int index, Component component)
1504:   {
1505:     checkIndex(index, 0, tabs.size());
1506:     ((Page) tabs.elementAt(index)).setComponent(component);
1507:   }
1508: 
1509:   /**
1510:    * This method sets the displayed mnemonic index of the tab.
1511:    *
1512:    * @param tabIndex The index of the tab.
1513:    * @param mnemonicIndex The mnemonic index.
1514:    */
1515:   public void setDisplayedMnemonicIndexAt(int tabIndex, int mnemonicIndex)
1516:   {
1517:     checkIndex(tabIndex, 0, tabs.size());
1518:     ((Page) tabs.elementAt(tabIndex)).setDisplayedMnemonicIndex(mnemonicIndex);
1519:   }
1520: 
1521:   /**
1522:    * This method sets the mnemonic for the tab.
1523:    *
1524:    * @param tabIndex The index of the tab.
1525:    * @param mnemonic The mnemonic.
1526:    */
1527:   public void setMnemonicAt(int tabIndex, int mnemonic)
1528:   {
1529:     checkIndex(tabIndex, 0, tabs.size());
1530:     ((Page) tabs.elementAt(tabIndex)).setMnemonic(mnemonic);
1531:   }
1532: 
1533:   /**
1534:    * This method finds the index of a tab given the title.
1535:    *
1536:    * @param title The title that belongs to a tab.
1537:    *
1538:    * @return The index of the tab that has the title or -1 if not found.
1539:    */
1540:   public int indexOfTab(String title)
1541:   {
1542:     int index = -1;
1543:     for (int i = 0; i < tabs.size(); i++)
1544:       {
1545:     if (((Page) tabs.elementAt(i)).getTitle().equals(title))
1546:       {
1547:         index = i;
1548:         break;
1549:       }
1550:       }
1551:     return index;
1552:   }
1553: 
1554:   /**
1555:    * This method finds the index of a tab given the icon.
1556:    *
1557:    * @param icon The icon that belongs to a tab.
1558:    *
1559:    * @return The index of the tab that has the icon or -1 if not found.
1560:    */
1561:   public int indexOfTab(Icon icon)
1562:   {
1563:     int index = -1;
1564:     for (int i = 0; i < tabs.size(); i++)
1565:       {
1566:     if (((Page) tabs.elementAt(i)).getIcon() == icon)
1567:       {
1568:         index = i;
1569:         break;
1570:       }
1571:       }
1572:     return index;
1573:   }
1574: 
1575:   /**
1576:    * This method finds the index of a tab given the component.
1577:    *
1578:    * @param component A component associated with a tab.
1579:    *
1580:    * @return The index of the tab that has this component or -1 if not found.
1581:    */
1582:   public int indexOfComponent(Component component)
1583:   {
1584:     int index = -1;
1585:     for (int i = 0; i < tabs.size(); i++)
1586:       {
1587:     if (((Page) tabs.elementAt(i)).getComponent() == component)
1588:       {
1589:         index = i;
1590:         break;
1591:       }
1592:       }
1593:     return index;
1594:   }
1595: 
1596:   /**
1597:    * This method returns a tab index given an (x,y) location. The origin of
1598:    * the (x,y) pair will be the JTabbedPane's top left position. The  tab
1599:    * returned will be the one that contains the point. This method is
1600:    * delegated to the UI.
1601:    *
1602:    * @param x The x coordinate of the point.
1603:    * @param y The y coordinate of the point.
1604:    *
1605:    * @return The index of the tab that contains the point.
1606:    */
1607:   public int indexAtLocation(int x, int y)
1608:   {
1609:     return ((TabbedPaneUI) ui).tabForCoordinate(this, x, y);
1610:   }
1611: 
1612:   /**
1613:    * This method returns the tooltip text given a mouse event.
1614:    *
1615:    * @param event The mouse event.
1616:    *
1617:    * @return The tool tip text that is associated with this mouse event.
1618:    */
1619:   public String getToolTipText(MouseEvent event)
1620:   {
1621:     int index = indexAtLocation(event.getX(), event.getY());
1622:     return ((Page) tabs.elementAt(index)).getTip();
1623:   }
1624: 
1625:   /**
1626:    * This method returns a string representation of this JTabbedPane. It is
1627:    * mainly used for debugging purposes.
1628:    *
1629:    * @return A string representation of this JTabbedPane.
1630:    */
1631:   protected String paramString()
1632:   {
1633:     return "JTabbedPane";
1634:   }
1635: 
1636:   /**
1637:    * DOCUMENT ME!
1638:    *
1639:    * @return DOCUMENT ME!
1640:    */
1641:   public AccessibleContext getAccessibleContext()
1642:   {
1643:     if (accessibleContext == null)
1644:       accessibleContext = new AccessibleJTabbedPane();
1645:     return accessibleContext;
1646:   }
1647: }