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