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