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