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