| /* JTabbedPane.java -- | 
 |    Copyright (C) 2002, 2004, 2005, 2006,  Free Software Foundation, Inc. | 
 |  | 
 | This file is part of GNU Classpath. | 
 |  | 
 | GNU Classpath is free software; you can redistribute it and/or modify | 
 | it under the terms of the GNU General Public License as published by | 
 | the Free Software Foundation; either version 2, or (at your option) | 
 | any later version. | 
 |  | 
 | GNU Classpath is distributed in the hope that it will be useful, but | 
 | WITHOUT ANY WARRANTY; without even the implied warranty of | 
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
 | General Public License for more details. | 
 |  | 
 | You should have received a copy of the GNU General Public License | 
 | along with GNU Classpath; see the file COPYING.  If not, write to the | 
 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | 
 | 02110-1301 USA. | 
 |  | 
 | Linking this library statically or dynamically with other modules is | 
 | making a combined work based on this library.  Thus, the terms and | 
 | conditions of the GNU General Public License cover the whole | 
 | combination. | 
 |  | 
 | As a special exception, the copyright holders of this library give you | 
 | permission to link this library with independent modules to produce an | 
 | executable, regardless of the license terms of these independent | 
 | modules, and to copy and distribute the resulting executable under | 
 | terms of your choice, provided that you also meet, for each linked | 
 | independent module, the terms and conditions of the license of that | 
 | module.  An independent module is a module which is not derived from | 
 | or based on this library.  If you modify this library, you may extend | 
 | this exception to your version of the library, but you are not | 
 | obligated to do so.  If you do not wish to do so, delete this | 
 | exception statement from your version. */ | 
 |  | 
 |  | 
 | package javax.swing; | 
 |  | 
 | import gnu.java.lang.CPStringBuilder; | 
 |  | 
 | import java.awt.Color; | 
 | import java.awt.Component; | 
 | import java.awt.Point; | 
 | import java.awt.Rectangle; | 
 | import java.awt.event.MouseEvent; | 
 | import java.io.Serializable; | 
 | import java.util.Locale; | 
 | import java.util.Vector; | 
 |  | 
 | import javax.accessibility.Accessible; | 
 | import javax.accessibility.AccessibleContext; | 
 | import javax.accessibility.AccessibleRole; | 
 | import javax.accessibility.AccessibleSelection; | 
 | import javax.accessibility.AccessibleState; | 
 | import javax.accessibility.AccessibleStateSet; | 
 | import javax.swing.event.ChangeEvent; | 
 | import javax.swing.event.ChangeListener; | 
 | import javax.swing.plaf.TabbedPaneUI; | 
 | import javax.swing.plaf.UIResource; | 
 |  | 
 | /** | 
 |  * This is a container for components where only one component is displayed at | 
 |  * a given time and the displayed component can be switched by clicking on | 
 |  * tabs. | 
 |  * | 
 |  * <p> | 
 |  * Tabs can be oriented in several ways. They can be above, below, left and | 
 |  * right of the component. Tabs can either wrap around (by creating multiple | 
 |  * rows of tabs) or they can be scrolled (where only a subset of the  tabs | 
 |  * can be seen at once). More tabs can be added by calling the | 
 |  * add/addTab/insertTab methods. | 
 |  * </p> | 
 |  */ | 
 | public class JTabbedPane extends JComponent implements Serializable, | 
 |                                                        Accessible, | 
 |                                                        SwingConstants | 
 | { | 
 |   /** | 
 |    * Accessibility support for <code>JTabbedPane</code>. | 
 |    */ | 
 |   protected class AccessibleJTabbedPane extends JComponent.AccessibleJComponent | 
 |     implements AccessibleSelection, ChangeListener | 
 |   { | 
 |     /** | 
 |      * The serialization UID. | 
 |      */ | 
 |     private static final long serialVersionUID = 7610530885966830483L; | 
 |  | 
 |     /** | 
 |      * Creates a new AccessibleJTabbedPane object. | 
 |      */ | 
 |     public AccessibleJTabbedPane() | 
 |     { | 
 |       super(); | 
 |     } | 
 |  | 
 |     /** | 
 |      * Receives notification when the selection state of the | 
 |      * <code>JTabbedPane</code> changes and fires appropriate property change | 
 |      * events to interested listeners. | 
 |      * | 
 |      * @param e the change event describing the change | 
 |      */ | 
 |     public void stateChanged(ChangeEvent e) | 
 |     { | 
 |       // I couldn't figure out what else should be done here. | 
 |       Object source = e.getSource(); | 
 |       firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY, | 
 |                          null, source); | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the accessible role of the <code>JTabbedPane</code>, which is | 
 |      * {@link AccessibleRole#PAGE_TAB_LIST}. | 
 |      * | 
 |      * @return the accessible role of the <code>JTabbedPane</code> | 
 |      */ | 
 |     public AccessibleRole getAccessibleRole() | 
 |     { | 
 |       return AccessibleRole.PAGE_TAB_LIST; | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the number of accessible child components of the | 
 |      * <code>JTabbedPane</code>. | 
 |      * | 
 |      * @return the number of accessible child components of the | 
 |      *         <code>JTabbedPane</code> | 
 |      */ | 
 |     public int getAccessibleChildrenCount() | 
 |     { | 
 |       return getTabCount(); | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the accessible child component at the specified index. | 
 |      * | 
 |      * @param i the index of the child component to fetch | 
 |      * | 
 |      * @return the accessible child component at the specified index | 
 |      */ | 
 |     public Accessible getAccessibleChild(int i) | 
 |     { | 
 |       // Testing shows that the reference implementation returns instances | 
 |       // of page here. | 
 |       Accessible child = null; | 
 |       if (i >= 0 && i < tabs.size()) | 
 |         child = (Page) tabs.get(i); | 
 |       return child; | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the current selection state of the <code>JTabbedPane</code> | 
 |      * as AccessibleSelection object. | 
 |      * | 
 |      * @return the current selection state of the <code>JTabbedPane</code> | 
 |      */ | 
 |     public AccessibleSelection getAccessibleSelection() | 
 |     { | 
 |       return this; | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the accessible child component at the specified coordinates. | 
 |      * If there is no child component at this location, then return the | 
 |      * currently selected tab. | 
 |      * | 
 |      * @param p the coordinates at which to look up the child component | 
 |      * | 
 |      * @return the accessible child component at the specified coordinates or | 
 |      *         the currently selected tab if there is no child component at | 
 |      *         this location | 
 |      */ | 
 |     public Accessible getAccessibleAt(Point p) | 
 |     { | 
 |       int tabIndex = indexAtLocation(p.x, p.y); | 
 |       if (tabIndex >= 0) | 
 |         return getAccessibleChild(tabIndex); | 
 |       else | 
 |         return getAccessibleSelection(0); | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the number of selected child components of the | 
 |      * <code>JTabbedPane</code>. The reference implementation appears | 
 |      * to return <code>1</code> always and we do the same. | 
 |      * | 
 |      * @return <code>1</code> | 
 |      */ | 
 |     public int getAccessibleSelectionCount() | 
 |     { | 
 |       return 1; | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the selected tab, or <code>null</code> if there is no | 
 |      * selection. | 
 |      * | 
 |      * @param i  the selection index (ignored here). | 
 |      * | 
 |      * @return The selected tab, or <code>null</code>. | 
 |      */ | 
 |     public Accessible getAccessibleSelection(int i) | 
 |     { | 
 |       Accessible result = null; | 
 |       int selected = getSelectedIndex(); | 
 |       if (selected >= 0) | 
 |         result = (Page) tabs.get(selected); | 
 |       return result; | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns <code>true</code> if the specified child is selected, | 
 |      * and <code>false</code> otherwise. | 
 |      * | 
 |      * @param i the child index. | 
 |      * | 
 |      * @return A boolean. | 
 |      */ | 
 |     public boolean isAccessibleChildSelected(int i) | 
 |     { | 
 |       return i == getSelectedIndex(); | 
 |     } | 
 |  | 
 |     /** | 
 |      * Selects the specified tab. | 
 |      * | 
 |      * @param i  the index of the item to select. | 
 |      */ | 
 |     public void addAccessibleSelection(int i) | 
 |     { | 
 |       setSelectedIndex(i); | 
 |     } | 
 |  | 
 |     /** | 
 |      * Does nothing - it makes no sense to remove a selection for a | 
 |      * tabbed pane, since one tab must always be selected. | 
 |      * | 
 |      * @param i  the item index. | 
 |      * | 
 |      * @see #addAccessibleSelection(int) | 
 |      */ | 
 |     public void removeAccessibleSelection(int i) | 
 |     { | 
 |       // do nothing | 
 |     } | 
 |  | 
 |     /** | 
 |      * Does nothing - it makes no sense to clear the selection for | 
 |      * a tabbed pane, since one tab must always be selected. | 
 |      * | 
 |      * @see #addAccessibleSelection(int) | 
 |      */ | 
 |     public void clearAccessibleSelection() | 
 |     { | 
 |       // do nothing | 
 |     } | 
 |  | 
 |     /** | 
 |      * Does nothing - it makes no sense to select all for a tabbed | 
 |      * pane, since only one tab can be selected at a time. | 
 |      * | 
 |      * @see #addAccessibleSelection(int) | 
 |      */ | 
 |     public void selectAllAccessibleSelection() | 
 |     { | 
 |       // do nothing | 
 |     } | 
 |   } | 
 |  | 
 |   /** | 
 |    * A helper class that listens for changes to the model. | 
 |    */ | 
 |   protected class ModelListener implements ChangeListener, Serializable | 
 |   { | 
 |     private static final long serialVersionUID = 497359819958114132L; | 
 |  | 
 |     /** | 
 |      * Creates a new ModelListener object. | 
 |      */ | 
 |     protected ModelListener() | 
 |     { | 
 |       // Nothing to do here. | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method is called whenever the model  is changed. | 
 |      * | 
 |      * @param e The ChangeEvent that is passed from the model. | 
 |      */ | 
 |     public void stateChanged(ChangeEvent e) | 
 |     { | 
 |       // Propagate to our listeners. | 
 |       fireStateChanged(); | 
 |     } | 
 |   } | 
 |  | 
 |   /** | 
 |    * A private class that holds all the information  for each tab. | 
 |    */ | 
 |   private class Page | 
 |     extends AccessibleContext | 
 |     implements Accessible | 
 |   { | 
 |     /** The tooltip string. */ | 
 |     private String tip; | 
 |  | 
 |     /** The component associated with the tab. */ | 
 |     private Component component; | 
 |  | 
 |     /** The active icon associated with the tab. */ | 
 |     private transient Icon icon; | 
 |  | 
 |     /** The disabled icon associated with the tab. */ | 
 |     private transient Icon disabledIcon; | 
 |  | 
 |     /** The tab's enabled status. */ | 
 |     private transient boolean enabled = true; | 
 |  | 
 |     /** The string painted on the tab. */ | 
 |     private transient String title; | 
 |  | 
 |     /** The background color of the tab. */ | 
 |     private transient Color bg; | 
 |  | 
 |     /** The foreground color of the tab. */ | 
 |     private transient Color fg; | 
 |  | 
 |     /** The mnemonic associated with the tab. */ | 
 |     private transient int mnemonicKey; | 
 |  | 
 |     /** The index of the underlined character in the string. */ | 
 |     private transient int underlinedChar = -1; | 
 |  | 
 |     /** | 
 |      * Creates a new data storage for the tab. | 
 |      * | 
 |      * @param title The string displayed on the tab. | 
 |      * @param icon The active icon displayed on the tab. | 
 |      * @param component The component associated with the tab. | 
 |      * @param tip The tooltip associated with the tab. | 
 |      */ | 
 |     protected Page(String title, Icon icon, Component component, String tip) | 
 |     { | 
 |       this.title = title; | 
 |       this.icon = icon; | 
 |       this.component = component; | 
 |       this.tip = tip; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method returns the component associated with the tab. | 
 |      * | 
 |      * @return The component associated with the tab. | 
 |      */ | 
 |     public Component getComponent() | 
 |     { | 
 |       return component; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method sets the component associated with the tab. | 
 |      * | 
 |      * @param c The component associated with the tab. | 
 |      */ | 
 |     public void setComponent(Component c) | 
 |     { | 
 |       int i = indexOfComponent(component); | 
 |       insertTab(title, icon, c, tip, i); | 
 |       component = c; | 
 |       removeTabAt(i); | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method returns the tooltip string. | 
 |      * | 
 |      * @return The tooltip string. | 
 |      */ | 
 |     public String getTip() | 
 |     { | 
 |       return tip; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method sets the tooltip string. | 
 |      * | 
 |      * @param tip The tooltip string. | 
 |      */ | 
 |     public void setTip(String tip) | 
 |     { | 
 |       this.tip = tip; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method returns the background color. | 
 |      * | 
 |      * @return The background color. | 
 |      */ | 
 |     public Color getBackground() | 
 |     { | 
 |       Color background; | 
 |       if (bg == null) | 
 |         background = JTabbedPane.this.getBackground(); | 
 |       else | 
 |         background = bg; | 
 |       return background; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method sets the background color. | 
 |      * | 
 |      * @param background The background color. | 
 |      */ | 
 |     public void setBackground(Color background) | 
 |     { | 
 |       bg = background; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method returns the foreground color. | 
 |      * | 
 |      * @return The foreground color. | 
 |      */ | 
 |     public Color getForeground() | 
 |     { | 
 |       Color foreground; | 
 |       if (fg == null) | 
 |         foreground = JTabbedPane.this.getForeground(); | 
 |       else | 
 |         foreground = fg; | 
 |       return foreground; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method sets the foreground color. | 
 |      * | 
 |      * @param foreground The foreground color. | 
 |      */ | 
 |     public void setForeground(Color foreground) | 
 |     { | 
 |       fg = foreground; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method returns the title associated with the tab. | 
 |      * | 
 |      * @return The title of the tab. | 
 |      */ | 
 |     public String getTitle() | 
 |     { | 
 |       return title; | 
 |     } | 
 |  | 
 |     private static final long serialVersionUID = 1614381073220130939L; | 
 |  | 
 |     /** | 
 |      * This method sets the title of the tab. | 
 |      * | 
 |      * @param text The title of the tab. | 
 |      */ | 
 |     public void setTitle(String text) | 
 |     { | 
 |       title = text; | 
 |       if (title != null && title.length() <= underlinedChar) | 
 |         setDisplayedMnemonicIndex(title.length() - 1); | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method returns the active icon. | 
 |      * | 
 |      * @return The active icon. | 
 |      */ | 
 |     public Icon getIcon() | 
 |     { | 
 |       return icon; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method sets the active icon. | 
 |      * | 
 |      * @param icon The active icon. | 
 |      */ | 
 |     public void setIcon(Icon icon) | 
 |     { | 
 |       this.icon = icon; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method returns the disabled icon. | 
 |      * | 
 |      * @return The disabled icon. | 
 |      */ | 
 |     public Icon getDisabledIcon() | 
 |     { | 
 |       if (disabledIcon == null && icon instanceof ImageIcon) | 
 |         setDisabledIcon(icon); | 
 |       return disabledIcon; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method sets the disabled icon. | 
 |      * | 
 |      * @param disabledIcon The disabled icon. | 
 |      */ | 
 |     public void setDisabledIcon(Icon disabledIcon) | 
 |     { | 
 |       this.disabledIcon = disabledIcon; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method returns whether the tab is enabled. | 
 |      * | 
 |      * @return Whether the tab is enabled. | 
 |      */ | 
 |     public boolean isEnabled() | 
 |     { | 
 |       return enabled; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method sets whether the tab is enabled. | 
 |      * | 
 |      * @param enabled Whether this tab is enabled. | 
 |      */ | 
 |     public void setEnabled(boolean enabled) | 
 |     { | 
 |       this.enabled = enabled; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method returns the mnemonic. | 
 |      * | 
 |      * @return The mnemonic. | 
 |      */ | 
 |     public int getMnemonic() | 
 |     { | 
 |       return mnemonicKey; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method sets the mnemonic. If the title is set, it will update the | 
 |      * mnemonicIndex. | 
 |      * | 
 |      * @param key The mnemonic. | 
 |      */ | 
 |     public void setMnemonic(int key) | 
 |     { | 
 |       setMnemonic((char) key); | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method sets the mnemonic. If the title is set, it will update the | 
 |      * mnemonicIndex. | 
 |      * | 
 |      * @param aChar The mnemonic. | 
 |      */ | 
 |     public void setMnemonic(char aChar) | 
 |     { | 
 |       mnemonicKey = aChar; | 
 |       if (title != null) | 
 |         setDisplayedMnemonicIndex(title.indexOf(mnemonicKey)); | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method returns the mnemonicIndex. | 
 |      * | 
 |      * @return The mnemonicIndex. | 
 |      */ | 
 |     public int getDisplayedMnemonicIndex() | 
 |     { | 
 |       return underlinedChar; | 
 |     } | 
 |  | 
 |     /** | 
 |      * This method sets the mnemonicIndex. | 
 |      * | 
 |      * @param index The mnemonicIndex. | 
 |      * | 
 |      * @throws IllegalArgumentException If index less than -1 || index greater | 
 |      *         or equal to title.length. | 
 |      */ | 
 |     public void setDisplayedMnemonicIndex(int index) | 
 |       throws IllegalArgumentException | 
 |     { | 
 |       if (index < -1 || title != null && index >= title.length()) | 
 |         throw new IllegalArgumentException(); | 
 |  | 
 |       if (title == null || mnemonicKey == 0 || (index > -1 && title.charAt(index) != mnemonicKey)) | 
 |         index = -1; | 
 |  | 
 |       underlinedChar = index; | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the accessible context, which is this object itself. | 
 |      * | 
 |      * @return the accessible context, which is this object itself | 
 |      */ | 
 |     public AccessibleContext getAccessibleContext() | 
 |     { | 
 |       return this; | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the accessible name for this tab. | 
 |      * | 
 |      * @return The accessible name. | 
 |      */ | 
 |     public String getAccessibleName() | 
 |     { | 
 |       if (accessibleName != null) | 
 |         return accessibleName; | 
 |       else | 
 |         return title; | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the accessible role of this tab, which is always | 
 |      * {@link AccessibleRole#PAGE_TAB}. | 
 |      * | 
 |      * @return the accessible role of this tab | 
 |      */ | 
 |     public AccessibleRole getAccessibleRole() | 
 |     { | 
 |       return AccessibleRole.PAGE_TAB; | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the accessible state set of this object. | 
 |      * | 
 |      * @return the accessible state set of this object | 
 |      */ | 
 |     public AccessibleStateSet getAccessibleStateSet() | 
 |     { | 
 |       AccessibleContext parentCtx = JTabbedPane.this.getAccessibleContext(); | 
 |       AccessibleStateSet state = parentCtx.getAccessibleStateSet(); | 
 |       state.add(AccessibleState.SELECTABLE); | 
 |       if (component == getSelectedComponent()) | 
 |         state.add(AccessibleState.SELECTED); | 
 |       return state; | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the index of this tab inside its parent. | 
 |      * | 
 |      * @return the index of this tab inside its parent | 
 |      */ | 
 |     public int getAccessibleIndexInParent() | 
 |     { | 
 |       // TODO: Not sure if the title is unambiguous, but I can't figure | 
 |       // another way of doing this. | 
 |       return indexOfTab(title); | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the number of accessible children, which is always one (the | 
 |      * component of this tab). | 
 |      * | 
 |      * @return the number of accessible children | 
 |      */ | 
 |     public int getAccessibleChildrenCount() | 
 |     { | 
 |       return 1; | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the accessible child of this tab, which is the component | 
 |      * displayed by the tab. | 
 |      * | 
 |      * @return the accessible child of this tab | 
 |      */ | 
 |     public Accessible getAccessibleChild(int i) | 
 |     { | 
 |       // A quick test shows that this method always returns the component | 
 |       // displayed by the tab, regardless of the index. | 
 |       return (Accessible) component; | 
 |     } | 
 |  | 
 |     /** | 
 |      * Returns the locale of this accessible object. | 
 |      * | 
 |      * @return the locale of this accessible object | 
 |      */ | 
 |     public Locale getLocale() | 
 |     { | 
 |       // TODO: Is this ok? | 
 |       return Locale.getDefault(); | 
 |     } | 
 |   } | 
 |  | 
 |   private static final long serialVersionUID = 1614381073220130939L; | 
 |  | 
 |   /** The changeEvent used to fire changes to listeners. */ | 
 |   protected ChangeEvent changeEvent; | 
 |  | 
 |   /** The listener that listens to the model. */ | 
 |   protected ChangeListener changeListener; | 
 |  | 
 |   /** The model that describes this JTabbedPane. */ | 
 |   protected SingleSelectionModel model; | 
 |  | 
 |   /** Indicates that the TabbedPane is in scrolling mode. */ | 
 |   public static final int SCROLL_TAB_LAYOUT = 1; | 
 |  | 
 |   /** Indicates that the TabbedPane is in wrap mode. */ | 
 |   public static final int WRAP_TAB_LAYOUT = 0; | 
 |  | 
 |   /** The current tabPlacement of the TabbedPane. */ | 
 |   protected int tabPlacement = SwingConstants.TOP; | 
 |  | 
 |   /** The current tabLayoutPolicy of the TabbedPane. */ | 
 |   private transient int layoutPolicy; | 
 |  | 
 |   /** The list of tabs associated with the TabbedPane. */ | 
 |   transient Vector tabs = new Vector(); | 
 |  | 
 |   /** | 
 |    * Creates a new JTabbedPane object with tabs on top and using wrap tab | 
 |    * layout. | 
 |    */ | 
 |   public JTabbedPane() | 
 |   { | 
 |     this(SwingConstants.TOP, WRAP_TAB_LAYOUT); | 
 |   } | 
 |  | 
 |   /** | 
 |    * Creates a new JTabbedPane object using wrap tab layout  and the given | 
 |    * <code>tabPlacement</code>, where <code>tabPlacement</code> can be one | 
 |    * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or | 
 |    * {@link #RIGHT}. | 
 |    * | 
 |    * @param tabPlacement where the tabs will be placed | 
 |    */ | 
 |   public JTabbedPane(int tabPlacement) | 
 |   { | 
 |     this(tabPlacement, WRAP_TAB_LAYOUT); | 
 |   } | 
 |  | 
 |   /** | 
 |    * Creates a new JTabbedPane object with the given <code>tabPlacement</code> | 
 |    * and <code>tabLayoutPolicy</code>. The <code>tabPlacement</code> can be one | 
 |    * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or | 
 |    * {@link #RIGHT}. The <code>tabLayoutPolicy</code> can be either | 
 |    * {@link #SCROLL_TAB_LAYOUT} or {@link #WRAP_TAB_LAYOUT}. | 
 |    * | 
 |    * @param tabPlacement where the tabs will be placed | 
 |    * @param tabLayoutPolicy the way tabs will be placed | 
 |    * | 
 |    * @throws IllegalArgumentException If tabLayoutPolicy or tabPlacement are | 
 |    *         not valid. | 
 |    */ | 
 |   public JTabbedPane(int tabPlacement, int tabLayoutPolicy) | 
 |   { | 
 |     if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT | 
 |         && tabPlacement != LEFT) | 
 |       throw new IllegalArgumentException("tabPlacement is not valid."); | 
 |     if (tabLayoutPolicy != SCROLL_TAB_LAYOUT | 
 |         && tabLayoutPolicy != WRAP_TAB_LAYOUT) | 
 |       throw new IllegalArgumentException("tabLayoutPolicy is not valid."); | 
 |     this.tabPlacement = tabPlacement; | 
 |     layoutPolicy = tabLayoutPolicy; | 
 |  | 
 |     setModel(new DefaultSingleSelectionModel()); | 
 |  | 
 |     updateUI(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the UI used to display the JTabbedPane. | 
 |    * | 
 |    * @return The UI used to display the JTabbedPane. | 
 |    */ | 
 |   public TabbedPaneUI getUI() | 
 |   { | 
 |     return (TabbedPaneUI) ui; | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method sets the UI used to display the JTabbedPane. | 
 |    * | 
 |    * @param ui The UI used to display the JTabbedPane. | 
 |    */ | 
 |   public void setUI(TabbedPaneUI ui) | 
 |   { | 
 |     super.setUI(ui); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method restores the UI to the defaults given by the UIManager. | 
 |    */ | 
 |   public void updateUI() | 
 |   { | 
 |     setUI((TabbedPaneUI) UIManager.getUI(this)); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns a string identifier that  is used to determine which | 
 |    * UI will be used with  the JTabbedPane. | 
 |    * | 
 |    * @return A string identifier for the UI. | 
 |    */ | 
 |   public String getUIClassID() | 
 |   { | 
 |     return "TabbedPaneUI"; | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method creates a ChangeListener that is used to  listen to the model | 
 |    * for events. | 
 |    * | 
 |    * @return A ChangeListener to listen to the model. | 
 |    */ | 
 |   protected ChangeListener createChangeListener() | 
 |   { | 
 |     return new ModelListener(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method adds a ChangeListener to the JTabbedPane. | 
 |    * | 
 |    * @param l The ChangeListener to add. | 
 |    */ | 
 |   public void addChangeListener(ChangeListener l) | 
 |   { | 
 |     listenerList.add(ChangeListener.class, l); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method removes a ChangeListener to the JTabbedPane. | 
 |    * | 
 |    * @param l The ChangeListener to remove. | 
 |    */ | 
 |   public void removeChangeListener(ChangeListener l) | 
 |   { | 
 |     listenerList.remove(ChangeListener.class, l); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method fires a ChangeEvent to all the JTabbedPane's ChangeListeners. | 
 |    */ | 
 |   protected void fireStateChanged() | 
 |   { | 
 |     Object[] changeListeners = listenerList.getListenerList(); | 
 |     if (changeEvent == null) | 
 |       changeEvent = new ChangeEvent(this); | 
 |     for (int i = changeListeners.length - 2; i >= 0; i -= 2) | 
 |       { | 
 |         if (changeListeners[i] == ChangeListener.class) | 
 |           ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent); | 
 |       } | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns all ChangeListeners registered with the JTabbedPane. | 
 |    * | 
 |    * @return The ChangeListeners registered with the JTabbedPane. | 
 |    */ | 
 |   public ChangeListener[] getChangeListeners() | 
 |   { | 
 |     return (ChangeListener[]) super.getListeners(ChangeListener.class); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the model used with the JTabbedPane. | 
 |    * | 
 |    * @return The JTabbedPane's model. | 
 |    */ | 
 |   public SingleSelectionModel getModel() | 
 |   { | 
 |     return model; | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method changes the model property of the JTabbedPane. | 
 |    * | 
 |    * @param m The new model to use with the JTabbedPane. | 
 |    */ | 
 |   public void setModel(SingleSelectionModel m) | 
 |   { | 
 |     if (m != model) | 
 |       { | 
 |         SingleSelectionModel oldModel = this.model; | 
 |         if (oldModel != null && changeListener != null) | 
 |           oldModel.removeChangeListener(changeListener); | 
 |  | 
 |         model = m; | 
 |  | 
 |         if (model != null) | 
 |           { | 
 |             if (changeListener == null) | 
 |               changeListener = createChangeListener(); | 
 |             model.addChangeListener(changeListener); | 
 |           } | 
 |         firePropertyChange("model", oldModel, this.model); | 
 |       } | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the tabPlacement. | 
 |    * | 
 |    * @return The tabPlacement used with the JTabbedPane. | 
 |    */ | 
 |   public int getTabPlacement() | 
 |   { | 
 |     return tabPlacement; | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method changes the tabPlacement property of the JTabbedPane. | 
 |    * | 
 |    * @param tabPlacement The tabPlacement to use. | 
 |    * | 
 |    * @throws IllegalArgumentException If tabPlacement is not one of TOP, | 
 |    *         BOTTOM, LEFT, or RIGHT. | 
 |    */ | 
 |   public void setTabPlacement(int tabPlacement) | 
 |   { | 
 |     if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT | 
 |         && tabPlacement != LEFT) | 
 |       throw new IllegalArgumentException("tabPlacement is not valid."); | 
 |     if (tabPlacement != this.tabPlacement) | 
 |       { | 
 |         int oldPlacement = this.tabPlacement; | 
 |         this.tabPlacement = tabPlacement; | 
 |         firePropertyChange("tabPlacement", oldPlacement, this.tabPlacement); | 
 |       } | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the tabLayoutPolicy. | 
 |    * | 
 |    * @return The tabLayoutPolicy. | 
 |    */ | 
 |   public int getTabLayoutPolicy() | 
 |   { | 
 |     return layoutPolicy; | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method changes the tabLayoutPolicy property of the JTabbedPane. | 
 |    * | 
 |    * @param tabLayoutPolicy The tabLayoutPolicy to use. | 
 |    * | 
 |    * @throws IllegalArgumentException If tabLayoutPolicy is not one of | 
 |    *         SCROLL_TAB_LAYOUT or WRAP_TAB_LAYOUT. | 
 |    */ | 
 |   public void setTabLayoutPolicy(int tabLayoutPolicy) | 
 |   { | 
 |     if (tabLayoutPolicy != SCROLL_TAB_LAYOUT | 
 |         && tabLayoutPolicy != WRAP_TAB_LAYOUT) | 
 |       throw new IllegalArgumentException("tabLayoutPolicy is not valid."); | 
 |     if (tabLayoutPolicy != layoutPolicy) | 
 |       { | 
 |         int oldPolicy = layoutPolicy; | 
 |         layoutPolicy = tabLayoutPolicy; | 
 |         firePropertyChange("tabLayoutPolicy", oldPolicy, layoutPolicy); | 
 |       } | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the index of the tab that is currently selected. | 
 |    * | 
 |    * @return The index of the selected tab. | 
 |    */ | 
 |   public int getSelectedIndex() | 
 |   { | 
 |     return model.getSelectedIndex(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method checks the index. | 
 |    * | 
 |    * @param index The index to check. | 
 |    * @param start DOCUMENT ME! | 
 |    * @param end DOCUMENT ME! | 
 |    * | 
 |    * @throws IndexOutOfBoundsException DOCUMENT ME! | 
 |    */ | 
 |   private void checkIndex(int index, int start, int end) | 
 |   { | 
 |     if (index < start || index >= end) | 
 |       throw new IndexOutOfBoundsException("Index < " + start + " || Index >= " | 
 |                                           + end); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method sets the selected index. This method will hide the old | 
 |    * component and show the new component. | 
 |    * | 
 |    * @param index The index to set it at. | 
 |    */ | 
 |   public void setSelectedIndex(int index) | 
 |   { | 
 |     checkIndex(index, -1, tabs.size()); | 
 |     if (index != getSelectedIndex()) | 
 |       { | 
 |         // Hiding and showing the involved components | 
 |         // is done by the JTabbedPane's UI. | 
 |         model.setSelectedIndex(index); | 
 |       } | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the component at the selected index. | 
 |    * | 
 |    * @return The component at the selected index. | 
 |    */ | 
 |   public Component getSelectedComponent() | 
 |   { | 
 |     int selectedIndex = getSelectedIndex(); | 
 |     Component selected = null; | 
 |     if (selectedIndex >= 0) | 
 |       selected = getComponentAt(selectedIndex); | 
 |     return selected; | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method sets the component at the selected index. | 
 |    * | 
 |    * @param c The component associated with the selected index. | 
 |    */ | 
 |   public void setSelectedComponent(Component c) | 
 |   { | 
 |     if (c.getParent() == this) | 
 |       setSelectedIndex(indexOfComponent(c)); | 
 |     else | 
 |       setComponentAt(getSelectedIndex(), c); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method inserts tabs into JTabbedPane. This includes adding the | 
 |    * component to the JTabbedPane and hiding it. | 
 |    * | 
 |    * @param title the title of the tab; may be <code>null</code> | 
 |    * @param icon the tab's icon; may be <code>null</code> | 
 |    * @param component the component associated with the tab | 
 |    * @param tip the tooltip for the tab | 
 |    * @param index the index to insert the tab at | 
 |    */ | 
 |   public void insertTab(String title, Icon icon, Component component, | 
 |                         String tip, int index) | 
 |   { | 
 |     if (title == null) | 
 |       title = ""; | 
 |     Page p = new Page(title, icon, component, tip); | 
 |     tabs.insertElementAt(p, index); | 
 |  | 
 |     // Hide the component so we don't see it. Do it before we parent it | 
 |     // so we don't trigger a repaint. | 
 |     if (component != null) | 
 |       { | 
 |         component.hide(); | 
 |         super.add(component); | 
 |       } | 
 |  | 
 |     if (getSelectedIndex() == -1) | 
 |       { | 
 |         setSelectedIndex(0); | 
 |         fireStateChanged(); | 
 |       } | 
 |  | 
 |     revalidate(); | 
 |     repaint(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method adds a tab to the JTabbedPane. | 
 |    * | 
 |    * @param title the title of the tab; may be <code>null</code> | 
 |    * @param icon the icon for the tab; may be <code>null</code> | 
 |    * @param component the associated component | 
 |    * @param tip the associated tooltip | 
 |    */ | 
 |   public void addTab(String title, Icon icon, Component component, String tip) | 
 |   { | 
 |     insertTab(title, icon, component, tip, tabs.size()); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method adds a tab to the JTabbedPane. | 
 |    * | 
 |    * @param title the title of the tab; may be <code>null</code> | 
 |    * @param icon the icon for the tab; may be <code>null</code> | 
 |    * @param component the associated component | 
 |    */ | 
 |   public void addTab(String title, Icon icon, Component component) | 
 |   { | 
 |     insertTab(title, icon, component, null, tabs.size()); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method adds a tab to the JTabbedPane. | 
 |    * | 
 |    * @param title the title of the tab; may be <code>null</code> | 
 |    * @param component the associated component | 
 |    */ | 
 |   public void addTab(String title, Component component) | 
 |   { | 
 |     insertTab(title, null, component, null, tabs.size()); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method adds a tab to the JTabbedPane. The title of the tab is the | 
 |    * Component's name. If the Component is an instance of UIResource, it | 
 |    * doesn't add the tab and instead add the component directly to the | 
 |    * JTabbedPane. | 
 |    * | 
 |    * @param component The associated component. | 
 |    * | 
 |    * @return The Component that was added. | 
 |    */ | 
 |   public Component add(Component component) | 
 |   { | 
 |     if (component instanceof UIResource) | 
 |       super.add(component); | 
 |     else | 
 |       insertTab(component.getName(), null, component, null, tabs.size()); | 
 |  | 
 |     return component; | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method adds a tab to the JTabbedPane. If the Component is an | 
 |    * instance of UIResource, it doesn't add the tab and instead add the | 
 |    * component directly to the JTabbedPane. | 
 |    * | 
 |    * @param title the title of the tab; may be <code>null</code> | 
 |    * @param component the associated component | 
 |    * | 
 |    * @return The Component that was added. | 
 |    */ | 
 |   public Component add(String title, Component component) | 
 |   { | 
 |     if (component instanceof UIResource) | 
 |       super.add(component); | 
 |     else | 
 |       insertTab(title, null, component, null, tabs.size()); | 
 |     return component; | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method adds a tab to the JTabbedPane. If the Component is an | 
 |    * instance of UIResource, it doesn't add the tab and instead add the | 
 |    * component directly to the JTabbedPane. | 
 |    * | 
 |    * @param component The associated component. | 
 |    * @param index The index to insert the tab at. | 
 |    * | 
 |    * @return The Component that was added. | 
 |    */ | 
 |   public Component add(Component component, int index) | 
 |   { | 
 |     if (component instanceof UIResource) | 
 |       super.add(component); | 
 |     else | 
 |       insertTab(component.getName(), null, component, null, index); | 
 |     return component; | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method adds a tab to the JTabbedPane. If the Component is an | 
 |    * instance of UIResource, it doesn't add the tab and instead add the | 
 |    * component directly to the JTabbedPane. If the constraints object is an | 
 |    * icon, it will be used as the tab's icon. If the constraints object is a | 
 |    * string, we will use it as the title. | 
 |    * | 
 |    * @param component The associated component. | 
 |    * @param constraints The constraints object. | 
 |    */ | 
 |   public void add(Component component, Object constraints) | 
 |   { | 
 |     add(component, constraints, tabs.size()); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method adds a tab to the JTabbedPane. If the Component is an | 
 |    * instance of UIResource, it doesn't add the tab and instead add the | 
 |    * component directly to the JTabbedPane. If the constraints object is an | 
 |    * icon, it will be used as the tab's icon. If the constraints object is a | 
 |    * string, we will use it as the title. | 
 |    * | 
 |    * @param component The associated component. | 
 |    * @param constraints The constraints object. | 
 |    * @param index The index to insert the tab at. | 
 |    */ | 
 |   public void add(Component component, Object constraints, int index) | 
 |   { | 
 |     if (component instanceof UIResource) | 
 |       super.add(component); | 
 |     else | 
 |       { | 
 |         if (constraints instanceof String) | 
 |           insertTab((String) constraints, null, component, null, index); | 
 |         else | 
 |           insertTab(component.getName(), | 
 |                     (constraints instanceof Icon) ? (Icon) constraints : null, | 
 |                     component, null, index); | 
 |       } | 
 |   } | 
 |  | 
 |   /** | 
 |    * Removes the tab at index. After the component associated with | 
 |    * index is removed, its visibility is reset to true to ensure it | 
 |    * will be visible if added to other containers. | 
 |    * | 
 |    * @param index The index of the tab to remove. | 
 |    */ | 
 |   public void removeTabAt(int index) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |  | 
 |     // We need to adjust the selection if we remove a tab that comes | 
 |     // before the selected tab or if the selected tab is removed. | 
 |     // This decrements the selected index by 1 if any of this is the case. | 
 |     // Note that this covers all cases: | 
 |     // - When the selected tab comes after the removed tab, this simply | 
 |     //   adjusts the selection so that after the removal the selected tab | 
 |     //   is still the same. | 
 |     // - When we remove the currently selected tab, then the tab before the | 
 |     //   selected tab gets selected. | 
 |     // - When the last tab is removed, then we have an index==0, which gets | 
 |     //   decremented to -1, which means no selection, which is 100% perfect. | 
 |     int selectedIndex = getSelectedIndex(); | 
 |     if (selectedIndex >= index) | 
 |       setSelectedIndex(selectedIndex - 1); | 
 |  | 
 |     Component comp = getComponentAt(index); | 
 |  | 
 |     // Remove the tab object. | 
 |     tabs.remove(index); | 
 |  | 
 |     // Remove the component. I think we cannot assume that the tab order | 
 |     // is equal to the component order, so we iterate over the children | 
 |     // here to find the and remove the correct component. | 
 |     if (comp != null) | 
 |       { | 
 |         Component[] children = getComponents(); | 
 |         for (int i = children.length - 1; i >= 0; --i) | 
 |           { | 
 |             if (children[i] == comp) | 
 |               { | 
 |                 super.remove(i); | 
 |                 comp.setVisible(true); | 
 |                 break; | 
 |               } | 
 |           } | 
 |       } | 
 |     revalidate(); | 
 |     repaint(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * Removes the specified Component from the JTabbedPane. | 
 |    * | 
 |    * @param component The Component to remove. | 
 |    */ | 
 |   public void remove(Component component) | 
 |   { | 
 |     // Since components implementing UIResource | 
 |     // are not added as regular tabs by the add() | 
 |     // methods we have to take special care when | 
 |     // removing these object. Especially | 
 |     // Container.remove(Component) cannot be used | 
 |     // because it will call JTabbedPane.remove(int) | 
 |     // later which is overridden and can only | 
 |     // handle tab components. | 
 |     // This implementation can even cope with a | 
 |     // situation that someone called insertTab() | 
 |     // with a component that implements UIResource. | 
 |     int index = indexOfComponent(component); | 
 |  | 
 |     // If the component is not a tab component | 
 |     // find out its Container-given index | 
 |     // and call that class' implementation | 
 |     // directly. | 
 |     if (index == -1) | 
 |       { | 
 |         Component[] cs = getComponents(); | 
 |         for (int i = 0; i< cs.length; i++) | 
 |           if (cs[i] == component) | 
 |             super.remove(i); | 
 |       } | 
 |     else | 
 |       removeTabAt(index); | 
 |   } | 
 |  | 
 |   /** | 
 |    * Removes the tab and component which corresponds to the specified index. | 
 |    * | 
 |    * @param index The index of the tab to remove. | 
 |    */ | 
 |   public void remove(int index) | 
 |   { | 
 |     removeTabAt(index); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method removes all tabs and associated components from the | 
 |    * JTabbedPane. | 
 |    */ | 
 |   public void removeAll() | 
 |   { | 
 |     setSelectedIndex(-1); | 
 |     for (int i = getTabCount() - 1; i >= 0; i--) | 
 |       removeTabAt(i); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns how many tabs are in the JTabbedPane. | 
 |    * | 
 |    * @return The number of tabs in the JTabbedPane. | 
 |    */ | 
 |   public int getTabCount() | 
 |   { | 
 |     return tabs.size(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the number of runs used  to paint the JTabbedPane. | 
 |    * | 
 |    * @return The number of runs. | 
 |    */ | 
 |   public int getTabRunCount() | 
 |   { | 
 |     return ((TabbedPaneUI) ui).getTabRunCount(this); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the tab title given the index. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * | 
 |    * @return The title for the tab. | 
 |    */ | 
 |   public String getTitleAt(int index) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     return ((Page) tabs.elementAt(index)).getTitle(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the active icon given the index. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * | 
 |    * @return The active icon for the tab. | 
 |    */ | 
 |   public Icon getIconAt(int index) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     return ((Page) tabs.elementAt(index)).getIcon(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the disabled icon given the index. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * | 
 |    * @return The disabled icon for the tab. | 
 |    */ | 
 |   public Icon getDisabledIconAt(int index) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     return ((Page) tabs.elementAt(index)).getDisabledIcon(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the tooltip string for the tab. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * | 
 |    * @return The tooltip string for the tab. | 
 |    */ | 
 |   public String getToolTipTextAt(int index) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     return ((Page) tabs.elementAt(index)).getTip(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the foreground color for the tab. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * | 
 |    * @return The foreground color for the tab. | 
 |    */ | 
 |   public Color getForegroundAt(int index) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     return ((Page) tabs.elementAt(index)).getForeground(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the background color for the tab. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * | 
 |    * @return The background color for the tab. | 
 |    */ | 
 |   public Color getBackgroundAt(int index) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     return ((Page) tabs.elementAt(index)).getBackground(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the component associated with the tab. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * | 
 |    * @return The component associated with the tab. | 
 |    */ | 
 |   public Component getComponentAt(int index) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     return ((Page) tabs.elementAt(index)).getComponent(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns whether this tab is enabled. Disabled tabs cannot be | 
 |    * selected. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * | 
 |    * @return Whether the tab is enabled. | 
 |    */ | 
 |   public boolean isEnabledAt(int index) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     return ((Page) tabs.elementAt(index)).isEnabled(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the mnemonic for the tab. | 
 |    * | 
 |    * @param tabIndex The index of the tab. | 
 |    * | 
 |    * @return The mnemonic for the tab. | 
 |    */ | 
 |   public int getMnemonicAt(int tabIndex) | 
 |   { | 
 |     checkIndex(tabIndex, 0, tabs.size()); | 
 |     return ((Page) tabs.elementAt(tabIndex)).getMnemonic(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the mnemonic index for the tab. | 
 |    * | 
 |    * @param tabIndex The index of the tab. | 
 |    * | 
 |    * @return The mnemonic index for the tab. | 
 |    */ | 
 |   public int getDisplayedMnemonicIndexAt(int tabIndex) | 
 |   { | 
 |     checkIndex(tabIndex, 0, tabs.size()); | 
 |     return ((Page) tabs.elementAt(tabIndex)).getDisplayedMnemonicIndex(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the bounds of the tab given the index. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * | 
 |    * @return A rectangle describing the bounds of the tab. | 
 |    */ | 
 |   public Rectangle getBoundsAt(int index) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     return ((TabbedPaneUI) ui).getTabBounds(this, index); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method sets the title of the tab. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * @param title The new title. | 
 |    */ | 
 |   public void setTitleAt(int index, String title) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     ((Page) tabs.elementAt(index)).setTitle(title); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method sets the icon of the tab. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * @param icon The new icon. | 
 |    */ | 
 |   public void setIconAt(int index, Icon icon) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     ((Page) tabs.elementAt(index)).setIcon(icon); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method sets the disabled icon of the tab. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * @param disabledIcon The new disabled icon. | 
 |    */ | 
 |   public void setDisabledIconAt(int index, Icon disabledIcon) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     ((Page) tabs.elementAt(index)).setDisabledIcon(disabledIcon); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method sets the tooltip text of the tab. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * @param toolTipText The tooltip text. | 
 |    */ | 
 |   public void setToolTipTextAt(int index, String toolTipText) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     ((Page) tabs.elementAt(index)).setTip(toolTipText); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method sets the background color of the tab. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * @param background The background color of the tab. | 
 |    */ | 
 |   public void setBackgroundAt(int index, Color background) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     ((Page) tabs.elementAt(index)).setBackground(background); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method sets the foreground color of the tab. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * @param foreground The foreground color of the tab. | 
 |    */ | 
 |   public void setForegroundAt(int index, Color foreground) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     ((Page) tabs.elementAt(index)).setForeground(foreground); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method sets whether the tab is enabled. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * @param enabled Whether the tab is enabled. | 
 |    */ | 
 |   public void setEnabledAt(int index, boolean enabled) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     ((Page) tabs.elementAt(index)).setEnabled(enabled); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method sets the component associated with the tab. | 
 |    * | 
 |    * @param index The index of the tab. | 
 |    * @param component The component associated with the tab. | 
 |    */ | 
 |   public void setComponentAt(int index, Component component) | 
 |   { | 
 |     checkIndex(index, 0, tabs.size()); | 
 |     ((Page) tabs.elementAt(index)).setComponent(component); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method sets the displayed mnemonic index of the tab. | 
 |    * | 
 |    * @param tabIndex The index of the tab. | 
 |    * @param mnemonicIndex The mnemonic index. | 
 |    */ | 
 |   public void setDisplayedMnemonicIndexAt(int tabIndex, int mnemonicIndex) | 
 |   { | 
 |     checkIndex(tabIndex, 0, tabs.size()); | 
 |     ((Page) tabs.elementAt(tabIndex)).setDisplayedMnemonicIndex(mnemonicIndex); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method sets the mnemonic for the tab. | 
 |    * | 
 |    * @param tabIndex The index of the tab. | 
 |    * @param mnemonic The mnemonic. | 
 |    */ | 
 |   public void setMnemonicAt(int tabIndex, int mnemonic) | 
 |   { | 
 |     checkIndex(tabIndex, 0, tabs.size()); | 
 |     ((Page) tabs.elementAt(tabIndex)).setMnemonic(mnemonic); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method finds the index of a tab given the title. | 
 |    * | 
 |    * @param title The title that belongs to a tab. | 
 |    * | 
 |    * @return The index of the tab that has the title or -1 if not found. | 
 |    */ | 
 |   public int indexOfTab(String title) | 
 |   { | 
 |     int index = -1; | 
 |     for (int i = 0; i < tabs.size(); i++) | 
 |       { | 
 |         if (((Page) tabs.elementAt(i)).getTitle().equals(title)) | 
 |           { | 
 |             index = i; | 
 |             break; | 
 |           } | 
 |       } | 
 |     return index; | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method finds the index of a tab given the icon. | 
 |    * | 
 |    * @param icon The icon that belongs to a tab. | 
 |    * | 
 |    * @return The index of the tab that has the icon or -1 if not found. | 
 |    */ | 
 |   public int indexOfTab(Icon icon) | 
 |   { | 
 |     int index = -1; | 
 |     for (int i = 0; i < tabs.size(); i++) | 
 |       { | 
 |         if (((Page) tabs.elementAt(i)).getIcon() == icon) | 
 |           { | 
 |             index = i; | 
 |             break; | 
 |           } | 
 |       } | 
 |     return index; | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method finds the index of a tab given the component. | 
 |    * | 
 |    * @param component A component associated with a tab. | 
 |    * | 
 |    * @return The index of the tab that has this component or -1 if not found. | 
 |    */ | 
 |   public int indexOfComponent(Component component) | 
 |   { | 
 |     int index = -1; | 
 |     for (int i = 0; i < tabs.size(); i++) | 
 |       { | 
 |         if (((Page) tabs.elementAt(i)).getComponent() == component) | 
 |           { | 
 |             index = i; | 
 |             break; | 
 |           } | 
 |       } | 
 |     return index; | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns a tab index given an (x,y) location. The origin of | 
 |    * the (x,y) pair will be the JTabbedPane's top left position. The  tab | 
 |    * returned will be the one that contains the point. This method is | 
 |    * delegated to the UI. | 
 |    * | 
 |    * @param x The x coordinate of the point. | 
 |    * @param y The y coordinate of the point. | 
 |    * | 
 |    * @return The index of the tab that contains the point. | 
 |    */ | 
 |   public int indexAtLocation(int x, int y) | 
 |   { | 
 |     return ((TabbedPaneUI) ui).tabForCoordinate(this, x, y); | 
 |   } | 
 |  | 
 |   /** | 
 |    * This method returns the tooltip text given a mouse event. | 
 |    * | 
 |    * @param event The mouse event. | 
 |    * | 
 |    * @return The tool tip text that is associated with this mouse event. | 
 |    */ | 
 |   public String getToolTipText(MouseEvent event) | 
 |   { | 
 |     int index = indexAtLocation(event.getX(), event.getY()); | 
 |     return ((Page) tabs.elementAt(index)).getTip(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * Returns a string describing the attributes for the | 
 |    * <code>JTabbedPane</code> component, for use in debugging.  The return | 
 |    * value is guaranteed to be non-<code>null</code>, but the format of the | 
 |    * string may vary between implementations. | 
 |    * | 
 |    * @return A string describing the attributes of the | 
 |    *     <code>JTabbedPane</code>. | 
 |    */ | 
 |   protected String paramString() | 
 |   { | 
 |     CPStringBuilder sb = new CPStringBuilder(super.paramString()); | 
 |     sb.append(",tabPlacement="); | 
 |     if (tabPlacement == TOP) | 
 |       sb.append("TOP"); | 
 |     if (tabPlacement == BOTTOM) | 
 |       sb.append("BOTTOM"); | 
 |     if (tabPlacement == LEFT) | 
 |       sb.append("LEFT"); | 
 |     if (tabPlacement == RIGHT) | 
 |       sb.append("RIGHT"); | 
 |     return sb.toString(); | 
 |   } | 
 |  | 
 |   /** | 
 |    * Returns the object that provides accessibility features for this | 
 |    * <code>JTabbedPane</code> component. | 
 |    * | 
 |    * @return The accessible context (an instance of | 
 |    *         {@link AccessibleJTabbedPane}). | 
 |    */ | 
 |   public AccessibleContext getAccessibleContext() | 
 |   { | 
 |     if (accessibleContext == null) | 
 |       { | 
 |         AccessibleJTabbedPane ctx = new AccessibleJTabbedPane(); | 
 |         addChangeListener(ctx); | 
 |         accessibleContext = ctx; | 
 |       } | 
 |  | 
 |     return accessibleContext; | 
 |   } | 
 | } |