Frames | No Frames |
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: }