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