/*
 * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javax.swing;

import java.awt.*;
import java.awt.event.*;
import java.beans.Transient;
import java.util.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.accessibility.*;
import sun.swing.SwingUtilities2;

import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.IOException;

/**
 * A component that lets the user switch between a group of components by
 * clicking on a tab with a given title and/or icon.
 * For examples and information on using tabbed panes see
 * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/tabbedpane.html">How to Use Tabbed Panes</a>,
 * a section in <em>The Java Tutorial</em>.
 * <p>
 * Tabs/components are added to a <code>TabbedPane</code> object by using the
 * <code>addTab</code> and <code>insertTab</code> methods.
 * A tab is represented by an index corresponding
 * to the position it was added in, where the first tab has an index equal to 0
 * and the last tab has an index equal to the tab count minus 1.
 * <p>
 * The <code>TabbedPane</code> uses a <code>SingleSelectionModel</code>
 * to represent the set
 * of tab indices and the currently selected index.  If the tab count
 * is greater than 0, then there will always be a selected index, which
 * by default will be initialized to the first tab.  If the tab count is
 * 0, then the selected index will be -1.
 * <p>
 * The tab title can be rendered by a <code>Component</code>.
 * For example, the following produce similar results:
 * <pre>
 * // In this case the look and feel renders the title for the tab.
 * tabbedPane.addTab("Tab", myComponent);
 * // In this case the custom component is responsible for rendering the
 * // title of the tab.
 * tabbedPane.addTab(null, myComponent);
 * tabbedPane.setTabComponentAt(0, new JLabel("Tab"));
 * </pre>
 * The latter is typically used when you want a more complex user interaction
 * that requires custom components on the tab.  For example, you could
 * provide a custom component that animates or one that has widgets for
 * closing the tab.
 * <p>
 * If you specify a component for a tab, the <code>JTabbedPane</code>
 * will not render any text or icon you have specified for the tab.
 * <p>
 * <strong>Note:</strong>
 * Do not use <code>setVisible</code> directly on a tab component to make it visible,
 * use <code>setSelectedComponent</code> or <code>setSelectedIndex</code> methods instead.
 * <p>
 * <strong>Warning:</strong> Swing is not thread safe. For more
 * information see <a
 * href="package-summary.html#threading">Swing's Threading
 * Policy</a>.
 * <p>
 * <strong>Warning:</strong>
 * Serialized objects of this class will not be compatible with
 * future Swing releases. The current serialization support is
 * appropriate for short term storage or RMI between applications running
 * the same version of Swing.  As of 1.4, support for long term storage
 * of all JavaBeans<sup><font size="-2">TM</font></sup>
 * has been added to the <code>java.beans</code> package.
 * Please see {@link java.beans.XMLEncoder}.
 *
 * @beaninfo
 *      attribute: isContainer true
 *    description: A component which provides a tab folder metaphor for
 *                 displaying one component from a set of components.
 *
 * @author Dave Moore
 * @author Philip Milne
 * @author Amy Fowler
 *
 * @see SingleSelectionModel
 */
public class JTabbedPane extends JComponent
       implements Serializable, Accessible, SwingConstants {

   /**
    * The tab layout policy for wrapping tabs in multiple runs when all
    * tabs will not fit within a single run.
    */
    public static final int WRAP_TAB_LAYOUT = 0;

   /**
    * Tab layout policy for providing a subset of available tabs when all
    * the tabs will not fit within a single run.  If all the tabs do
    * not fit within a single run the look and feel will provide a way
    * to navigate to hidden tabs.
    */
    public static final int SCROLL_TAB_LAYOUT = 1;


    /**
     * @see #getUIClassID
     * @see #readObject
     */
    private static final String uiClassID = "TabbedPaneUI";

    /**
     * Where the tabs are placed.
     * @see #setTabPlacement
     */
    protected int tabPlacement = TOP;

    private int tabLayoutPolicy;

    /** The default selection model */
    protected SingleSelectionModel model;

    private boolean haveRegistered;

    /**
     * The <code>changeListener</code> is the listener we add to the
     * model.
     */
    protected ChangeListener changeListener = null;

    private final java.util.List<Page> pages;

    /* The component that is currently visible */
    private Component visComp = null;

    /**
     * Only one <code>ChangeEvent</code> is needed per <code>TabPane</code>
     * instance since the
     * event's only (read-only) state is the source property.  The source
     * of events generated here is always "this".
     */
    protected transient ChangeEvent changeEvent = null;

    /**
     * Creates an empty <code>TabbedPane</code> with a default
     * tab placement of <code>JTabbedPane.TOP</code>.
     * @see #addTab
     */
    public JTabbedPane() {
        this(TOP, WRAP_TAB_LAYOUT);
    }

    /**
     * Creates an empty <code>TabbedPane</code> with the specified tab placement
     * of either: <code>JTabbedPane.TOP</code>, <code>JTabbedPane.BOTTOM</code>,
     * <code>JTabbedPane.LEFT</code>, or <code>JTabbedPane.RIGHT</code>.
     *
     * @param tabPlacement the placement for the tabs relative to the content
     * @see #addTab
     */
    public JTabbedPane(int tabPlacement) {
        this(tabPlacement, WRAP_TAB_LAYOUT);
    }

    /**
     * Creates an empty <code>TabbedPane</code> with the specified tab placement
     * and tab layout policy.  Tab placement may be either:
     * <code>JTabbedPane.TOP</code>, <code>JTabbedPane.BOTTOM</code>,
     * <code>JTabbedPane.LEFT</code>, or <code>JTabbedPane.RIGHT</code>.
     * Tab layout policy may be either: <code>JTabbedPane.WRAP_TAB_LAYOUT</code>
     * or <code>JTabbedPane.SCROLL_TAB_LAYOUT</code>.
     *
     * @param tabPlacement the placement for the tabs relative to the content
     * @param tabLayoutPolicy the policy for laying out tabs when all tabs will not fit on one run
     * @exception IllegalArgumentException if tab placement or tab layout policy are not
     *            one of the above supported values
     * @see #addTab
     * @since 1.4
     */
    public JTabbedPane(int tabPlacement, int tabLayoutPolicy) {
        setTabPlacement(tabPlacement);
        setTabLayoutPolicy(tabLayoutPolicy);
        pages = new ArrayList<Page>(1);
        setModel(new DefaultSingleSelectionModel());
        updateUI();
    }

    /**
     * Returns the UI object which implements the L&F for this component.
     *
     * @return a <code>TabbedPaneUI</code> object
     * @see #setUI
     */
    public TabbedPaneUI getUI() {
        return (TabbedPaneUI)ui;
    }

    /**
     * Sets the UI object which implements the L&F for this component.
     *
     * @param ui the new UI object
     * @see UIDefaults#getUI
     * @beaninfo
     *        bound: true
     *       hidden: true
     *    attribute: visualUpdate true
     *  description: The UI object that implements the tabbedpane's LookAndFeel
     */
    public void setUI(TabbedPaneUI ui) {
        super.setUI(ui);
        // disabled icons are generated by LF so they should be unset here
        for (int i = 0; i < getTabCount(); i++) {
            Icon icon = pages.get(i).disabledIcon;
            if (icon instanceof UIResource) {
                setDisabledIconAt(i, null);
            }
        }
    }

    /**
     * Resets the UI property to a value from the current look and feel.
     *
     * @see JComponent#updateUI
     */
    public void updateUI() {
        setUI((TabbedPaneUI)UIManager.getUI(this));
    }


    /**
     * Returns the name of the UI class that implements the
     * L&F for this component.
     *
     * @return the string "TabbedPaneUI"
     * @see JComponent#getUIClassID
     * @see UIDefaults#getUI
     */
    public String getUIClassID() {
        return uiClassID;
    }


    /**
     * We pass <code>ModelChanged</code> events along to the listeners with
     * the tabbedpane (instead of the model itself) as the event source.
     */
    protected class ModelListener implements ChangeListener, Serializable {
        public void stateChanged(ChangeEvent e) {
            fireStateChanged();
        }
    }

    /**
     * Subclasses that want to handle <code>ChangeEvents</code> differently
     * can override this to return a subclass of <code>ModelListener</code> or
     * another <code>ChangeListener</code> implementation.
     *
     * @see #fireStateChanged
     */
    protected ChangeListener createChangeListener() {
        return new ModelListener();
    }

    /**
     * Adds a <code>ChangeListener</code> to this tabbedpane.
     *
     * @param l the <code>ChangeListener</code> to add
     * @see #fireStateChanged
     * @see #removeChangeListener
     */
    public void addChangeListener(ChangeListener l) {
        listenerList.add(ChangeListener.class, l);
    }

    /**
     * Removes a <code>ChangeListener</code> from this tabbedpane.
     *
     * @param l the <code>ChangeListener</code> to remove
     * @see #fireStateChanged
     * @see #addChangeListener
     */
    public void removeChangeListener(ChangeListener l) {
        listenerList.remove(ChangeListener.class, l);
    }

   /**
     * Returns an array of all the <code>ChangeListener</code>s added
     * to this <code>JTabbedPane</code> with <code>addChangeListener</code>.
     *
     * @return all of the <code>ChangeListener</code>s added or an empty
     *         array if no listeners have been added
     * @since 1.4
     */
    public ChangeListener[] getChangeListeners() {
        return listenerList.getListeners(ChangeListener.class);
    }

    /**
     * Sends a {@code ChangeEvent}, with this {@code JTabbedPane} as the source,
     * to each registered listener. This method is called each time there is
     * a change to either the selected index or the selected tab in the
     * {@code JTabbedPane}. Usually, the selected index and selected tab change
     * together. However, there are some cases, such as tab addition, where the
     * selected index changes and the same tab remains selected. There are other
     * cases, such as deleting the selected tab, where the index remains the
     * same, but a new tab moves to that index. Events are fired for all of
     * these cases.
     *
     * @see #addChangeListener
     * @see EventListenerList
     */
    protected void fireStateChanged() {
        /* --- Begin code to deal with visibility --- */

        /* This code deals with changing the visibility of components to
         * hide and show the contents for the selected tab. It duplicates
         * logic already present in BasicTabbedPaneUI, logic that is
         * processed during the layout pass. This code exists to allow
         * developers to do things that are quite difficult to accomplish
         * with the previous model of waiting for the layout pass to process
         * visibility changes; such as requesting focus on the new visible
         * component.
         *
         * For the average code, using the typical JTabbedPane methods,
         * all visibility changes will now be processed here. However,
         * the code in BasicTabbedPaneUI still exists, for the purposes
         * of backward compatibility. Therefore, when making changes to
         * this code, ensure that the BasicTabbedPaneUI code is kept in
         * synch.
         */

        int selIndex = getSelectedIndex();

        /* if the selection is now nothing */
        if (selIndex < 0) {
            /* if there was a previous visible component */
            if (visComp != null && visComp.isVisible()) {
                /* make it invisible */
                visComp.setVisible(false);
            }

            /* now there's no visible component */
            visComp = null;

        /* else - the selection is now something */
        } else {
            /* Fetch the component for the new selection */
            Component newComp = getComponentAt(selIndex);

            /* if the new component is non-null and different */
            if (newComp != null && newComp != visComp) {
                boolean shouldChangeFocus = false;

                /* Note: the following (clearing of the old visible component)
                 * is inside this if-statement for good reason: Tabbed pane
                 * should continue to show the previously visible component
                 * if there is no component for the chosen tab.
                 */

                /* if there was a previous visible component */
                if (visComp != null) {
                    shouldChangeFocus =
                        (SwingUtilities.findFocusOwner(visComp) != null);

                    /* if it's still visible */
                    if (visComp.isVisible()) {
                        /* make it invisible */
                        visComp.setVisible(false);
                    }
                }

                if (!newComp.isVisible()) {
                    newComp.setVisible(true);
                }

                if (shouldChangeFocus) {
                    SwingUtilities2.tabbedPaneChangeFocusTo(newComp);
                }

                visComp = newComp;
            } /* else - the visible component shouldn't changed */
        }

        /* --- End code to deal with visibility --- */

        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();
        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length-2; i>=0; i-=2) {
            if (listeners[i]==ChangeListener.class) {
                // Lazily create the event:
                if (changeEvent == null)
                    changeEvent = new ChangeEvent(this);
                ((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
            }
        }
    }

    /**
     * Returns the model associated with this tabbedpane.
     *
     * @see #setModel
     */
    public SingleSelectionModel getModel() {
        return model;
    }

    /**
     * Sets the model to be used with this tabbedpane.
     *
     * @param model the model to be used
     * @see #getModel
     * @beaninfo
     *       bound: true
     * description: The tabbedpane's SingleSelectionModel.
     */
    public void setModel(SingleSelectionModel model) {
        SingleSelectionModel oldModel = getModel();

        if (oldModel != null) {
            oldModel.removeChangeListener(changeListener);
            changeListener = null;
        }

        this.model = model;

        if (model != null) {
            changeListener = createChangeListener();
            model.addChangeListener(changeListener);
        }

        firePropertyChange("model", oldModel, model);
        repaint();
    }

    /**
     * Returns the placement of the tabs for this tabbedpane.
     * @see #setTabPlacement
     */
    public int getTabPlacement() {
        return tabPlacement;
    }

    /**
     * Sets the tab placement for this tabbedpane.
     * Possible values are:<ul>
     * <li><code>JTabbedPane.TOP</code>
     * <li><code>JTabbedPane.BOTTOM</code>
     * <li><code>JTabbedPane.LEFT</code>
     * <li><code>JTabbedPane.RIGHT</code>
     * </ul>
     * The default value, if not set, is <code>SwingConstants.TOP</code>.
     *
     * @param tabPlacement the placement for the tabs relative to the content
     * @exception IllegalArgumentException if tab placement value isn't one
     *                          of the above valid values
     *
     * @beaninfo
     *    preferred: true
     *        bound: true
     *    attribute: visualUpdate true
     *         enum: TOP JTabbedPane.TOP
     *               LEFT JTabbedPane.LEFT
     *               BOTTOM JTabbedPane.BOTTOM
     *               RIGHT JTabbedPane.RIGHT
     *  description: The tabbedpane's tab placement.
     *
     */
    public void setTabPlacement(int tabPlacement) {
        if (tabPlacement != TOP && tabPlacement != LEFT &&
            tabPlacement != BOTTOM && tabPlacement != RIGHT) {
            throw new IllegalArgumentException("illegal tab placement: must be TOP, BOTTOM, LEFT, or RIGHT");
        }
        if (this.tabPlacement != tabPlacement) {
            int oldValue = this.tabPlacement;
            this.tabPlacement = tabPlacement;
            firePropertyChange("tabPlacement", oldValue, tabPlacement);
            revalidate();
            repaint();
        }
    }

    /**
     * Returns the policy used by the tabbedpane to layout the tabs when all the
     * tabs will not fit within a single run.
     * @see #setTabLayoutPolicy
     * @since 1.4
     */
    public int getTabLayoutPolicy() {
        return tabLayoutPolicy;
    }

   /**
     * Sets the policy which the tabbedpane will use in laying out the tabs
     * when all the tabs will not fit within a single run.
     * Possible values are:
     * <ul>
     * <li><code>JTabbedPane.WRAP_TAB_LAYOUT</code>
     * <li><code>JTabbedPane.SCROLL_TAB_LAYOUT</code>
     * </ul>
     *
     * The default value, if not set by the UI, is <code>JTabbedPane.WRAP_TAB_LAYOUT</code>.
     * <p>
     * Some look and feels might only support a subset of the possible
     * layout policies, in which case the value of this property may be
     * ignored.
     *
     * @param tabLayoutPolicy the policy used to layout the tabs
     * @exception IllegalArgumentException if layoutPolicy value isn't one
     *                          of the above valid values
     * @see #getTabLayoutPolicy
     * @since 1.4
     *
     * @beaninfo
     *    preferred: true
     *        bound: true
     *    attribute: visualUpdate true
     *         enum: WRAP_TAB_LAYOUT JTabbedPane.WRAP_TAB_LAYOUT
     *               SCROLL_TAB_LAYOUT JTabbedPane.SCROLL_TAB_LAYOUT
     *  description: The tabbedpane's policy for laying out the tabs
     *
     */
    public void setTabLayoutPolicy(int tabLayoutPolicy) {
        if (tabLayoutPolicy != WRAP_TAB_LAYOUT && tabLayoutPolicy != SCROLL_TAB_LAYOUT) {
            throw new IllegalArgumentException("illegal tab layout policy: must be WRAP_TAB_LAYOUT or SCROLL_TAB_LAYOUT");
        }
        if (this.tabLayoutPolicy != tabLayoutPolicy) {
            int oldValue = this.tabLayoutPolicy;
            this.tabLayoutPolicy = tabLayoutPolicy;
            firePropertyChange("tabLayoutPolicy", oldValue, tabLayoutPolicy);
            revalidate();
            repaint();
        }
    }

    /**
     * Returns the currently selected index for this tabbedpane.
     * Returns -1 if there is no currently selected tab.
     *
     * @return the index of the selected tab
     * @see #setSelectedIndex
     */
    @Transient
    public int getSelectedIndex() {
        return model.getSelectedIndex();
    }

    /**
     * Sets the selected index for this tabbedpane. The index must be
     * a valid tab index or -1, which indicates that no tab should be selected
     * (can also be used when there are no tabs in the tabbedpane).  If a -1
     * value is specified when the tabbedpane contains one or more tabs, then
     * the results will be implementation defined.
     *
     * @param index  the index to be selected
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < -1 || index >= tab count)
     *
     * @see #getSelectedIndex
     * @see SingleSelectionModel#setSelectedIndex
     * @beaninfo
     *   preferred: true
     * description: The tabbedpane's selected tab index.
     */
    public void setSelectedIndex(int index) {
        if (index != -1) {
            checkIndex(index);
        }
        setSelectedIndexImpl(index, true);
    }


    private void setSelectedIndexImpl(int index, boolean doAccessibleChanges) {
        int oldIndex = model.getSelectedIndex();
        Page oldPage = null, newPage = null;
        String oldName = null;

        doAccessibleChanges = doAccessibleChanges && (oldIndex != index);

        if (doAccessibleChanges) {
            if (accessibleContext != null) {
                oldName = accessibleContext.getAccessibleName();
            }

            if (oldIndex >= 0) {
                oldPage = pages.get(oldIndex);
            }

            if (index >= 0) {
                newPage = pages.get(index);
            }
        }

        model.setSelectedIndex(index);

        if (doAccessibleChanges) {
            changeAccessibleSelection(oldPage, oldName, newPage);
        }
    }

    private void changeAccessibleSelection(Page oldPage, String oldName, Page newPage) {
        if (accessibleContext == null) {
            return;
        }

        if (oldPage != null) {
            oldPage.firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
                                       AccessibleState.SELECTED, null);
        }

        if (newPage != null) {
            newPage.firePropertyChange(AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
                                       null, AccessibleState.SELECTED);
        }

        accessibleContext.firePropertyChange(
            AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
            oldName,
            accessibleContext.getAccessibleName());
    }

    /**
     * Returns the currently selected component for this tabbedpane.
     * Returns <code>null</code> if there is no currently selected tab.
     *
     * @return the component corresponding to the selected tab
     * @see #setSelectedComponent
     */
    @Transient
    public Component getSelectedComponent() {
        int index = getSelectedIndex();
        if (index == -1) {
            return null;
        }
        return getComponentAt(index);
    }

    /**
     * Sets the selected component for this tabbedpane.  This
     * will automatically set the <code>selectedIndex</code> to the index
     * corresponding to the specified component.
     *
     * @exception IllegalArgumentException if component not found in tabbed
     *          pane
     * @see #getSelectedComponent
     * @beaninfo
     *   preferred: true
     * description: The tabbedpane's selected component.
     */
    public void setSelectedComponent(Component c) {
        int index = indexOfComponent(c);
        if (index != -1) {
            setSelectedIndex(index);
        } else {
            throw new IllegalArgumentException("component not found in tabbed pane");
        }
    }

    /**
     * Inserts a new tab for the given component, at the given index,
     * represented by the given title and/or icon, either of which may
     * be {@code null}.
     *
     * @param title the title to be displayed on the tab
     * @param icon the icon to be displayed on the tab
     * @param component the component to be displayed when this tab is clicked.
     * @param tip the tooltip to be displayed for this tab
     * @param index the position to insert this new tab
     *       ({@code > 0 and <= getTabCount()})
     *
     * @throws IndexOutOfBoundsException if the index is out of range
     *         ({@code < 0 or > getTabCount()})
     *
     * @see #addTab
     * @see #removeTabAt
     */
    public void insertTab(String title, Icon icon, Component component, String tip, int index) {
        int newIndex = index;

        // If component already exists, remove corresponding
        // tab so that new tab gets added correctly
        // Note: we are allowing component=null because of compatibility,
        // but we really should throw an exception because much of the
        // rest of the JTabbedPane implementation isn't designed to deal
        // with null components for tabs.
        int removeIndex = indexOfComponent(component);
        if (component != null && removeIndex != -1) {
            removeTabAt(removeIndex);
            if (newIndex > removeIndex) {
                newIndex--;
            }
        }

        int selectedIndex = getSelectedIndex();

        pages.add(
            newIndex,
            new Page(this, title != null? title : "", icon, null, component, tip));


        if (component != null) {
            addImpl(component, null, -1);
            component.setVisible(false);
        } else {
            firePropertyChange("indexForNullComponent", -1, index);
        }

        if (pages.size() == 1) {
            setSelectedIndex(0);
        }

        if (selectedIndex >= newIndex) {
            setSelectedIndexImpl(selectedIndex + 1, false);
        }

        if (!haveRegistered && tip != null) {
            ToolTipManager.sharedInstance().registerComponent(this);
            haveRegistered = true;
        }

        if (accessibleContext != null) {
            accessibleContext.firePropertyChange(
                    AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
                    null, component);
        }
        revalidate();
        repaint();
    }

    /**
     * Adds a <code>component</code> and <code>tip</code>
     * represented by a <code>title</code> and/or <code>icon</code>,
     * either of which can be <code>null</code>.
     * Cover method for <code>insertTab</code>.
     *
     * @param title the title to be displayed in this tab
     * @param icon the icon to be displayed in this tab
     * @param component the component to be displayed when this tab is clicked
     * @param tip the tooltip to be displayed for this tab
     *
     * @see #insertTab
     * @see #removeTabAt
     */
    public void addTab(String title, Icon icon, Component component, String tip) {
        insertTab(title, icon, component, tip, pages.size());
    }

    /**
     * Adds a <code>component</code> represented by a <code>title</code>
     * and/or <code>icon</code>, either of which can be <code>null</code>.
     * Cover method for <code>insertTab</code>.
     *
     * @param title the title to be displayed in this tab
     * @param icon the icon to be displayed in this tab
     * @param component the component to be displayed when this tab is clicked
     *
     * @see #insertTab
     * @see #removeTabAt
     */
    public void addTab(String title, Icon icon, Component component) {
        insertTab(title, icon, component, null, pages.size());
    }

    /**
     * Adds a <code>component</code> represented by a <code>title</code>
     * and no icon.
     * Cover method for <code>insertTab</code>.
     *
     * @param title the title to be displayed in this tab
     * @param component the component to be displayed when this tab is clicked
     *
     * @see #insertTab
     * @see #removeTabAt
     */
    public void addTab(String title, Component component) {
        insertTab(title, null, component, null, pages.size());
    }

    /**
     * Adds a <code>component</code> with a tab title defaulting to
     * the name of the component which is the result of calling
     * <code>component.getName</code>.
     * Cover method for <code>insertTab</code>.
     *
     * @param component the component to be displayed when this tab is clicked
     * @return the component
     *
     * @see #insertTab
     * @see #removeTabAt
     */
    public Component add(Component component) {
        if (!(component instanceof UIResource)) {
            addTab(component.getName(), component);
        } else {
            super.add(component);
        }
        return component;
    }

    /**
     * Adds a <code>component</code> with the specified tab title.
     * Cover method for <code>insertTab</code>.
     *
     * @param title the title to be displayed in this tab
     * @param component the component to be displayed when this tab is clicked
     * @return the component
     *
     * @see #insertTab
     * @see #removeTabAt
     */
    public Component add(String title, Component component) {
        if (!(component instanceof UIResource)) {
            addTab(title, component);
        } else {
            super.add(title, component);
        }
        return component;
    }

    /**
     * Adds a <code>component</code> at the specified tab index with a tab
     * title defaulting to the name of the component.
     * Cover method for <code>insertTab</code>.
     *
     * @param component the component to be displayed when this tab is clicked
     * @param index the position to insert this new tab
     * @return the component
     *
     * @see #insertTab
     * @see #removeTabAt
     */
    public Component add(Component component, int index) {
        if (!(component instanceof UIResource)) {
            // Container.add() interprets -1 as "append", so convert
            // the index appropriately to be handled by the vector
            insertTab(component.getName(), null, component, null,
                      index == -1? getTabCount() : index);
        } else {
            super.add(component, index);
        }
        return component;
    }

    /**
     * Adds a <code>component</code> to the tabbed pane.
     * If <code>constraints</code> is a <code>String</code> or an
     * <code>Icon</code>, it will be used for the tab title,
     * otherwise the component's name will be used as the tab title.
     * Cover method for <code>insertTab</code>.
     *
     * @param component the component to be displayed when this tab is clicked
     * @param constraints the object to be displayed in the tab
     *
     * @see #insertTab
     * @see #removeTabAt
     */
    public void add(Component component, Object constraints) {
        if (!(component instanceof UIResource)) {
            if (constraints instanceof String) {
                addTab((String)constraints, component);
            } else if (constraints instanceof Icon) {
                addTab(null, (Icon)constraints, component);
            } else {
                add(component);
            }
        } else {
            super.add(component, constraints);
        }
    }

    /**
     * Adds a <code>component</code> at the specified tab index.
     * If <code>constraints</code> is a <code>String</code> or an
     * <code>Icon</code>, it will be used for the tab title,
     * otherwise the component's name will be used as the tab title.
     * Cover method for <code>insertTab</code>.
     *
     * @param component the component to be displayed when this tab is clicked
     * @param constraints the object to be displayed in the tab
     * @param index the position to insert this new tab
     *
     * @see #insertTab
     * @see #removeTabAt
     */
    public void add(Component component, Object constraints, int index) {
        if (!(component instanceof UIResource)) {

            Icon icon = constraints instanceof Icon? (Icon)constraints : null;
            String title = constraints instanceof String? (String)constraints : null;
            // Container.add() interprets -1 as "append", so convert
            // the index appropriately to be handled by the vector
            insertTab(title, icon, component, null, index == -1? getTabCount() : index);
        } else {
            super.add(component, constraints, index);
        }
    }

    /**
     * Removes the tab at <code>index</code>.
     * After the component associated with <code>index</code> 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 be removed
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     *
     * @see #addTab
     * @see #insertTab
     */
    public void removeTabAt(int index) {
        checkIndex(index);

        Component component = getComponentAt(index);
        boolean shouldChangeFocus = false;
        int selected = getSelectedIndex();
        String oldName = null;

        /* if we're about to remove the visible component */
        if (component == visComp) {
            shouldChangeFocus = (SwingUtilities.findFocusOwner(visComp) != null);
            visComp = null;
        }

        if (accessibleContext != null) {
            /* if we're removing the selected page */
            if (index == selected) {
                /* fire an accessible notification that it's unselected */
                pages.get(index).firePropertyChange(
                    AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
                    AccessibleState.SELECTED, null);

                oldName = accessibleContext.getAccessibleName();
            }

            accessibleContext.firePropertyChange(
                    AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
                    component, null);
        }

        // Force the tabComponent to be cleaned up.
        setTabComponentAt(index, null);
        pages.remove(index);

        // NOTE 4/15/2002 (joutwate):
        // This fix is implemented using client properties since there is
        // currently no IndexPropertyChangeEvent.  Once
        // IndexPropertyChangeEvents have been added this code should be
        // modified to use it.
        putClientProperty("__index_to_remove__", Integer.valueOf(index));

        /* if the selected tab is after the removal */
        if (selected > index) {
            setSelectedIndexImpl(selected - 1, false);

        /* if the selected tab is the last tab */
        } else if (selected >= getTabCount()) {
            setSelectedIndexImpl(selected - 1, false);
            Page newSelected = (selected != 0)
                ? pages.get(selected - 1)
                : null;

            changeAccessibleSelection(null, oldName, newSelected);

        /* selected index hasn't changed, but the associated tab has */
        } else if (index == selected) {
            fireStateChanged();
            changeAccessibleSelection(null, oldName, pages.get(index));
        }

        // We can't assume the tab indices correspond to the
        // container's children array indices, so make sure we
        // remove the correct child!
        if (component != null) {
            Component components[] = getComponents();
            for (int i = components.length; --i >= 0; ) {
                if (components[i] == component) {
                    super.remove(i);
                    component.setVisible(true);
                    break;
                }
            }
        }

        if (shouldChangeFocus) {
            SwingUtilities2.tabbedPaneChangeFocusTo(getSelectedComponent());
        }

        revalidate();
        repaint();
    }

    /**
     * Removes the specified <code>Component</code> from the
     * <code>JTabbedPane</code>. The method does nothing
     * if the <code>component</code> is null.
     *
     * @param component the component to remove from the tabbedpane
     * @see #addTab
     * @see #removeTabAt
     */
    public void remove(Component component) {
        int index = indexOfComponent(component);
        if (index != -1) {
            removeTabAt(index);
        } else {
            // Container#remove(comp) invokes Container#remove(int)
            // so make sure JTabbedPane#remove(int) isn't called here
            Component children[] = getComponents();
            for (int i=0; i < children.length; i++) {
                if (component == children[i]) {
                    super.remove(i);
                    break;
                }
            }
        }
    }

    /**
     * Removes the tab and component which corresponds to the specified index.
     *
     * @param index the index of the component to remove from the
     *          <code>tabbedpane</code>
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     * @see #addTab
     * @see #removeTabAt
     */
    public void remove(int index) {
        removeTabAt(index);
    }

    /**
     * Removes all the tabs and their corresponding components
     * from the <code>tabbedpane</code>.
     *
     * @see #addTab
     * @see #removeTabAt
     */
    public void removeAll() {
        setSelectedIndexImpl(-1, true);

        int tabCount = getTabCount();
        // We invoke removeTabAt for each tab, otherwise we may end up
        // removing Components added by the UI.
        while (tabCount-- > 0) {
            removeTabAt(tabCount);
        }
    }

    /**
     * Returns the number of tabs in this <code>tabbedpane</code>.
     *
     * @return an integer specifying the number of tabbed pages
     */
    public int getTabCount() {
        return pages.size();
    }

    /**
     * Returns the number of tab runs currently used to display
     * the tabs.
     * @return an integer giving the number of rows if the
     *          <code>tabPlacement</code>
     *          is <code>TOP</code> or <code>BOTTOM</code>
     *          and the number of columns if
     *          <code>tabPlacement</code>
     *          is <code>LEFT</code> or <code>RIGHT</code>,
     *          or 0 if there is no UI set on this <code>tabbedpane</code>
     */
    public int getTabRunCount() {
        if (ui != null) {
            return ((TabbedPaneUI)ui).getTabRunCount(this);
        }
        return 0;
    }


// Getters for the Pages

    /**
     * Returns the tab title at <code>index</code>.
     *
     * @param index  the index of the item being queried
     * @return the title at <code>index</code>
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     * @see #setTitleAt
     */
    public String getTitleAt(int index) {
        return pages.get(index).title;
    }

    /**
     * Returns the tab icon at <code>index</code>.
     *
     * @param index  the index of the item being queried
     * @return the icon at <code>index</code>
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     *
     * @see #setIconAt
     */
    public Icon getIconAt(int index) {
        return pages.get(index).icon;
    }

    /**
     * Returns the tab disabled icon at <code>index</code>.
     * If the tab disabled icon doesn't exist at <code>index</code>
     * this will forward the call to the look and feel to construct
     * an appropriate disabled Icon from the corresponding enabled
     * Icon. Some look and feels might not render the disabled Icon,
     * in which case it won't be created.
     *
     * @param index  the index of the item being queried
     * @return the icon at <code>index</code>
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     *
     * @see #setDisabledIconAt
     */
    public Icon getDisabledIconAt(int index) {
        Page page = pages.get(index);
        if (page.disabledIcon == null) {
            page.disabledIcon = UIManager.getLookAndFeel().getDisabledIcon(this, page.icon);
        }
        return page.disabledIcon;
    }

    /**
     * Returns the tab tooltip text at <code>index</code>.
     *
     * @param index  the index of the item being queried
     * @return a string containing the tool tip text at <code>index</code>
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     *
     * @see #setToolTipTextAt
     * @since 1.3
     */
    public String getToolTipTextAt(int index) {
        return pages.get(index).tip;
    }

    /**
     * Returns the tab background color at <code>index</code>.
     *
     * @param index  the index of the item being queried
     * @return the <code>Color</code> of the tab background at
     *          <code>index</code>
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     *
     * @see #setBackgroundAt
     */
    public Color getBackgroundAt(int index) {
        return pages.get(index).getBackground();
    }

    /**
     * Returns the tab foreground color at <code>index</code>.
     *
     * @param index  the index of the item being queried
     * @return the <code>Color</code> of the tab foreground at
     *          <code>index</code>
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     *
     * @see #setForegroundAt
     */
    public Color getForegroundAt(int index) {
        return pages.get(index).getForeground();
    }

    /**
     * Returns whether or not the tab at <code>index</code> is
     * currently enabled.
     *
     * @param index  the index of the item being queried
     * @return true if the tab at <code>index</code> is enabled;
     *          false otherwise
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     *
     * @see #setEnabledAt
     */
    public boolean isEnabledAt(int index) {
        return pages.get(index).isEnabled();
    }

    /**
     * Returns the component at <code>index</code>.
     *
     * @param index  the index of the item being queried
     * @return the <code>Component</code> at <code>index</code>
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     *
     * @see #setComponentAt
     */
    public Component getComponentAt(int index) {
        return pages.get(index).component;
    }

    /**
     * Returns the keyboard mnemonic for accessing the specified tab.
     * The mnemonic is the key which when combined with the look and feel's
     * mouseless modifier (usually Alt) will activate the specified
     * tab.
     *
     * @since 1.4
     * @param tabIndex the index of the tab that the mnemonic refers to
     * @return the key code which represents the mnemonic;
     *         -1 if a mnemonic is not specified for the tab
     * @exception IndexOutOfBoundsException if index is out of range
     *            (<code>tabIndex</code> &lt; 0 ||
     *              <code>tabIndex</code> &gt;= tab count)
     * @see #setDisplayedMnemonicIndexAt(int,int)
     * @see #setMnemonicAt(int,int)
     */
    public int getMnemonicAt(int tabIndex) {
        checkIndex(tabIndex);

        Page page = pages.get(tabIndex);
        return page.getMnemonic();
    }

    /**
     * Returns the character, as an index, that the look and feel should
     * provide decoration for as representing the mnemonic character.
     *
     * @since 1.4
     * @param tabIndex the index of the tab that the mnemonic refers to
     * @return index representing mnemonic character if one exists;
     *    otherwise returns -1
     * @exception IndexOutOfBoundsException if index is out of range
     *            (<code>tabIndex</code> &lt; 0 ||
     *              <code>tabIndex</code> &gt;= tab count)
     * @see #setDisplayedMnemonicIndexAt(int,int)
     * @see #setMnemonicAt(int,int)
     */
    public int getDisplayedMnemonicIndexAt(int tabIndex) {
        checkIndex(tabIndex);

        Page page = pages.get(tabIndex);
        return page.getDisplayedMnemonicIndex();
    }

    /**
     * Returns the tab bounds at <code>index</code>.  If the tab at
     * this index is not currently visible in the UI, then returns
     * <code>null</code>.
     * If there is no UI set on this <code>tabbedpane</code>,
     * then returns <code>null</code>.
     *
     * @param index the index to be queried
     * @return a <code>Rectangle</code> containing the tab bounds at
     *          <code>index</code>, or <code>null</code> if tab at
     *          <code>index</code> is not currently visible in the UI,
     *          or if there is no UI set on this <code>tabbedpane</code>
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index &lt; 0 || index &gt;= tab count)
     */
    public Rectangle getBoundsAt(int index) {
        checkIndex(index);
        if (ui != null) {
            return ((TabbedPaneUI)ui).getTabBounds(this, index);
        }
        return null;
    }


// Setters for the Pages

    /**
     * Sets the title at <code>index</code> to <code>title</code> which
     * can be <code>null</code>.
     * The title is not shown if a tab component for this tab was specified.
     * An internal exception is raised if there is no tab at that index.
     *
     * @param index the tab index where the title should be set
     * @param title the title to be displayed in the tab
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index &lt; 0 || index &gt;= tab count)
     *
     * @see #getTitleAt
     * @see #setTabComponentAt
     * @beaninfo
     *    preferred: true
     *    attribute: visualUpdate true
     *  description: The title at the specified tab index.
     */
    public void setTitleAt(int index, String title) {
        Page page = pages.get(index);
        String oldTitle =page.title;
        page.title = title;

        if (oldTitle != title) {
            firePropertyChange("indexForTitle", -1, index);
        }
        page.updateDisplayedMnemonicIndex();
        if ((oldTitle != title) && (accessibleContext != null)) {
            accessibleContext.firePropertyChange(
                    AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
                    oldTitle, title);
        }
        if (title == null || oldTitle == null ||
            !title.equals(oldTitle)) {
            revalidate();
            repaint();
        }
    }

    /**
     * Sets the icon at <code>index</code> to <code>icon</code> which can be
     * <code>null</code>. This does not set disabled icon at <code>icon</code>.
     * If the new Icon is different than the current Icon and disabled icon
     * is not explicitly set, the LookAndFeel will be asked to generate a disabled
     * Icon. To explicitly set disabled icon, use <code>setDisableIconAt()</code>.
     * The icon is not shown if a tab component for this tab was specified.
     * An internal exception is raised if there is no tab at that index.
     *
     * @param index the tab index where the icon should be set
     * @param icon the icon to be displayed in the tab
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     *
     * @see #setDisabledIconAt
     * @see #getIconAt
     * @see #getDisabledIconAt
     * @see #setTabComponentAt
     * @beaninfo
     *    preferred: true
     *    attribute: visualUpdate true
     *  description: The icon at the specified tab index.
     */
    public void setIconAt(int index, Icon icon) {
        Page page = pages.get(index);
        Icon oldIcon = page.icon;
        if (icon != oldIcon) {
            page.icon = icon;

            /* If the default icon has really changed and we had
             * generated the disabled icon for this page, then
             * clear the disabledIcon field of the page.
             */
            if (page.disabledIcon instanceof UIResource) {
                page.disabledIcon = null;
            }

            // Fire the accessibility Visible data change
            if (accessibleContext != null) {
                accessibleContext.firePropertyChange(
                        AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
                        oldIcon, icon);
            }
            revalidate();
            repaint();
        }
    }

    /**
     * Sets the disabled icon at <code>index</code> to <code>icon</code>
     * which can be <code>null</code>.
     * An internal exception is raised if there is no tab at that index.
     *
     * @param index the tab index where the disabled icon should be set
     * @param disabledIcon the icon to be displayed in the tab when disabled
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index &lt; 0 || index &gt;= tab count)
     *
     * @see #getDisabledIconAt
     * @beaninfo
     *    preferred: true
     *    attribute: visualUpdate true
     *  description: The disabled icon at the specified tab index.
     */
    public void setDisabledIconAt(int index, Icon disabledIcon) {
        Icon oldIcon = pages.get(index).disabledIcon;
        pages.get(index).disabledIcon = disabledIcon;
        if (disabledIcon != oldIcon && !isEnabledAt(index)) {
            revalidate();
            repaint();
        }
    }

    /**
     * Sets the tooltip text at <code>index</code> to <code>toolTipText</code>
     * which can be <code>null</code>.
     * An internal exception is raised if there is no tab at that index.
     *
     * @param index the tab index where the tooltip text should be set
     * @param toolTipText the tooltip text to be displayed for the tab
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index &lt; 0 || index &gt;= tab count)
     *
     * @see #getToolTipTextAt
     * @beaninfo
     *    preferred: true
     *  description: The tooltip text at the specified tab index.
     * @since 1.3
     */
    public void setToolTipTextAt(int index, String toolTipText) {
        String oldToolTipText = pages.get(index).tip;
        pages.get(index).tip = toolTipText;

        if ((oldToolTipText != toolTipText) && (accessibleContext != null)) {
            accessibleContext.firePropertyChange(
                    AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
                    oldToolTipText, toolTipText);
        }
        if (!haveRegistered && toolTipText != null) {
            ToolTipManager.sharedInstance().registerComponent(this);
            haveRegistered = true;
        }
    }

    /**
     * Sets the background color at <code>index</code> to
     * <code>background</code>
     * which can be <code>null</code>, in which case the tab's background color
     * will default to the background color of the <code>tabbedpane</code>.
     * An internal exception is raised if there is no tab at that index.
     * @param index the tab index where the background should be set
     * @param background the color to be displayed in the tab's background
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index &lt; 0 || index &gt;= tab count)
     *
     * @see #getBackgroundAt
     * @beaninfo
     *    preferred: true
     *    attribute: visualUpdate true
     *  description: The background color at the specified tab index.
     */
    public void setBackgroundAt(int index, Color background) {
        Color oldBg = pages.get(index).background;
        pages.get(index).setBackground(background);
        if (background == null || oldBg == null ||
            !background.equals(oldBg)) {
            Rectangle tabBounds = getBoundsAt(index);
            if (tabBounds != null) {
                repaint(tabBounds);
            }
        }
    }

    /**
     * Sets the foreground color at <code>index</code> to
     * <code>foreground</code> which can be
     * <code>null</code>, in which case the tab's foreground color
     * will default to the foreground color of this <code>tabbedpane</code>.
     * An internal exception is raised if there is no tab at that index.
     *
     * @param index the tab index where the foreground should be set
     * @param foreground the color to be displayed as the tab's foreground
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index &lt; 0 || index &gt;= tab count)
     *
     * @see #getForegroundAt
     * @beaninfo
     *    preferred: true
     *    attribute: visualUpdate true
     *  description: The foreground color at the specified tab index.
     */
    public void setForegroundAt(int index, Color foreground) {
        Color oldFg = pages.get(index).foreground;
        pages.get(index).setForeground(foreground);
        if (foreground == null || oldFg == null ||
            !foreground.equals(oldFg)) {
            Rectangle tabBounds = getBoundsAt(index);
            if (tabBounds != null) {
                repaint(tabBounds);
            }
        }
    }

    /**
     * Sets whether or not the tab at <code>index</code> is enabled.
     * An internal exception is raised if there is no tab at that index.
     *
     * @param index the tab index which should be enabled/disabled
     * @param enabled whether or not the tab should be enabled
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index &lt; 0 || index &gt;= tab count)
     *
     * @see #isEnabledAt
     */
    public void setEnabledAt(int index, boolean enabled) {
        boolean oldEnabled = pages.get(index).isEnabled();
        pages.get(index).setEnabled(enabled);
        if (enabled != oldEnabled) {
            revalidate();
            repaint();
        }
    }

    /**
     * Sets the component at <code>index</code> to <code>component</code>.
     * An internal exception is raised if there is no tab at that index.
     *
     * @param index the tab index where this component is being placed
     * @param component the component for the tab
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index &lt; 0 || index &gt;= tab count)
     *
     * @see #getComponentAt
     * @beaninfo
     *    attribute: visualUpdate true
     *  description: The component at the specified tab index.
     */
    public void setComponentAt(int index, Component component) {
        Page page = pages.get(index);
        if (component != page.component) {
            boolean shouldChangeFocus = false;

            if (page.component != null) {
                shouldChangeFocus =
                    (SwingUtilities.findFocusOwner(page.component) != null);

                // REMIND(aim): this is really silly;
                // why not if (page.component.getParent() == this) remove(component)
                synchronized(getTreeLock()) {
                    int count = getComponentCount();
                    Component children[] = getComponents();
                    for (int i = 0; i < count; i++) {
                        if (children[i] == page.component) {
                            super.remove(i);
                        }
                    }
                }
            }

            page.component = component;
            boolean selectedPage = (getSelectedIndex() == index);

            if (selectedPage) {
                this.visComp = component;
            }

            if (component != null) {
                component.setVisible(selectedPage);
                addImpl(component, null, -1);

                if (shouldChangeFocus) {
                    SwingUtilities2.tabbedPaneChangeFocusTo(component);
                }
            } else {
                repaint();
            }

            revalidate();
        }
    }

    /**
     * Provides a hint to the look and feel as to which character in the
     * text should be decorated to represent the mnemonic. Not all look and
     * feels may support this. A value of -1 indicates either there is
     * no mnemonic for this tab, or you do not wish the mnemonic to be
     * displayed for this tab.
     * <p>
     * The value of this is updated as the properties relating to the
     * mnemonic change (such as the mnemonic itself, the text...).
     * You should only ever have to call this if
     * you do not wish the default character to be underlined. For example, if
     * the text at tab index 3 was 'Apple Price', with a mnemonic of 'p',
     * and you wanted the 'P'
     * to be decorated, as 'Apple <u>P</u>rice', you would have to invoke
     * <code>setDisplayedMnemonicIndex(3, 6)</code> after invoking
     * <code>setMnemonicAt(3, KeyEvent.VK_P)</code>.
     * <p>Note that it is the programmer's responsibility to ensure
     * that each tab has a unique mnemonic or unpredictable results may
     * occur.
     *
     * @since 1.4
     * @param tabIndex the index of the tab that the mnemonic refers to
     * @param mnemonicIndex index into the <code>String</code> to underline
     * @exception IndexOutOfBoundsException if <code>tabIndex</code> is
     *            out of range (<code>tabIndex < 0 || tabIndex >= tab
     *            count</code>)
     * @exception IllegalArgumentException will be thrown if
     *            <code>mnemonicIndex</code> is &gt;= length of the tab
     *            title , or &lt; -1
     * @see #setMnemonicAt(int,int)
     * @see #getDisplayedMnemonicIndexAt(int)
     *
     * @beaninfo
     *        bound: true
     *    attribute: visualUpdate true
     *  description: the index into the String to draw the keyboard character
     *               mnemonic at
     */
    public void setDisplayedMnemonicIndexAt(int tabIndex, int mnemonicIndex) {
        checkIndex(tabIndex);

        Page page = pages.get(tabIndex);

        page.setDisplayedMnemonicIndex(mnemonicIndex);
    }

    /**
     * Sets the keyboard mnemonic for accessing the specified tab.
     * The mnemonic is the key which when combined with the look and feel's
     * mouseless modifier (usually Alt) will activate the specified
     * tab.
     * <p>
     * A mnemonic must correspond to a single key on the keyboard
     * and should be specified using one of the <code>VK_XXX</code>
     * keycodes defined in <code>java.awt.event.KeyEvent</code>
     * or one of the extended keycodes obtained through
     * <code>java.awt.event.KeyEvent.getExtendedKeyCodeForChar</code>.
     * Mnemonics are case-insensitive, therefore a key event
     * with the corresponding keycode would cause the button to be
     * activated whether or not the Shift modifier was pressed.
     * <p>
     * This will update the displayed mnemonic property for the specified
     * tab.
     *
     * @since 1.4
     * @param tabIndex the index of the tab that the mnemonic refers to
     * @param mnemonic the key code which represents the mnemonic
     * @exception IndexOutOfBoundsException if <code>tabIndex</code> is out
     *            of range (<code>tabIndex < 0 || tabIndex >= tab count</code>)
     * @see #getMnemonicAt(int)
     * @see #setDisplayedMnemonicIndexAt(int,int)
     *
     * @beaninfo
     *        bound: true
     *    attribute: visualUpdate true
     *  description: The keyboard mnenmonic, as a KeyEvent VK constant,
     *               for the specified tab
     */
    public void setMnemonicAt(int tabIndex, int mnemonic) {
        checkIndex(tabIndex);

        Page page = pages.get(tabIndex);
        page.setMnemonic(mnemonic);

        firePropertyChange("mnemonicAt", null, null);
    }

// end of Page setters

    /**
     * Returns the first tab index with a given <code>title</code>,  or
     * -1 if no tab has this title.
     *
     * @param title the title for the tab
     * @return the first tab index which matches <code>title</code>, or
     *          -1 if no tab has this title
     */
    public int indexOfTab(String title) {
        for(int i = 0; i < getTabCount(); i++) {
            if (getTitleAt(i).equals(title == null? "" : title)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Returns the first tab index with a given <code>icon</code>,
     * or -1 if no tab has this icon.
     *
     * @param icon the icon for the tab
     * @return the first tab index which matches <code>icon</code>,
     *          or -1 if no tab has this icon
     */
    public int indexOfTab(Icon icon) {
        for(int i = 0; i < getTabCount(); i++) {
            Icon tabIcon = getIconAt(i);
            if ((tabIcon != null && tabIcon.equals(icon)) ||
                (tabIcon == null && tabIcon == icon)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Returns the index of the tab for the specified component.
     * Returns -1 if there is no tab for this component.
     *
     * @param component the component for the tab
     * @return the first tab which matches this component, or -1
     *          if there is no tab for this component
     */
    public int indexOfComponent(Component component) {
        for(int i = 0; i < getTabCount(); i++) {
            Component c = getComponentAt(i);
            if ((c != null && c.equals(component)) ||
                (c == null && c == component)) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Returns the tab index corresponding to the tab whose bounds
     * intersect the specified location.  Returns -1 if no tab
     * intersects the location.
     *
     * @param x the x location relative to this tabbedpane
     * @param y the y location relative to this tabbedpane
     * @return the tab index which intersects the location, or
     *         -1 if no tab intersects the location
     * @since 1.4
     */
    public int indexAtLocation(int x, int y) {
        if (ui != null) {
            return ((TabbedPaneUI)ui).tabForCoordinate(this, x, y);
        }
        return -1;
    }


    /**
     * Returns the tooltip text for the component determined by the
     * mouse event location.
     *
     * @param event  the <code>MouseEvent</code> that tells where the
     *          cursor is lingering
     * @return the <code>String</code> containing the tooltip text
     */
    public String getToolTipText(MouseEvent event) {
        if (ui != null) {
            int index = ((TabbedPaneUI)ui).tabForCoordinate(this, event.getX(), event.getY());

            if (index != -1) {
                return pages.get(index).tip;
            }
        }
        return super.getToolTipText(event);
    }

    private void checkIndex(int index) {
        if (index < 0 || index >= pages.size()) {
            throw new IndexOutOfBoundsException("Index: "+index+", Tab count: "+pages.size());
        }
    }


    /**
     * See <code>readObject</code> and <code>writeObject</code> in
     * <code>JComponent</code> for more
     * information about serialization in Swing.
     */
    private void writeObject(ObjectOutputStream s) throws IOException {
        s.defaultWriteObject();
        if (getUIClassID().equals(uiClassID)) {
            byte count = JComponent.getWriteObjCounter(this);
            JComponent.setWriteObjCounter(this, --count);
            if (count == 0 && ui != null) {
                ui.installUI(this);
            }
        }
    }

    /* Called from the <code>JComponent</code>'s
     * <code>EnableSerializationFocusListener</code> to
     * do any Swing-specific pre-serialization configuration.
     */
    void compWriteObjectNotify() {
        super.compWriteObjectNotify();
        // If ToolTipText != null, then the tooltip has already been
        // unregistered by JComponent.compWriteObjectNotify()
        if (getToolTipText() == null && haveRegistered) {
            ToolTipManager.sharedInstance().unregisterComponent(this);
        }
    }

    /**
     * See <code>readObject</code> and <code>writeObject</code> in
     * <code>JComponent</code> for more
     * information about serialization in Swing.
     */
    private void readObject(ObjectInputStream s)
        throws IOException, ClassNotFoundException
    {
        s.defaultReadObject();
        if ((ui != null) && (getUIClassID().equals(uiClassID))) {
            ui.installUI(this);
        }
        // If ToolTipText != null, then the tooltip has already been
        // registered by JComponent.readObject()
        if (getToolTipText() == null && haveRegistered) {
            ToolTipManager.sharedInstance().registerComponent(this);
        }
    }


    /**
     * Returns a string representation of this <code>JTabbedPane</code>.
     * This method
     * is intended to be used only for debugging purposes, and the
     * content and format of the returned string may vary between
     * implementations. The returned string may be empty but may not
     * be <code>null</code>.
     *
     * @return  a string representation of this JTabbedPane.
     */
    protected String paramString() {
        String tabPlacementString;
        if (tabPlacement == TOP) {
            tabPlacementString = "TOP";
        } else if (tabPlacement == BOTTOM) {
            tabPlacementString = "BOTTOM";
        } else if (tabPlacement == LEFT) {
            tabPlacementString = "LEFT";
        } else if (tabPlacement == RIGHT) {
            tabPlacementString = "RIGHT";
        } else tabPlacementString = "";
        String haveRegisteredString = (haveRegistered ?
                                       "true" : "false");

        return super.paramString() +
        ",haveRegistered=" + haveRegisteredString +
        ",tabPlacement=" + tabPlacementString;
    }

/////////////////
// Accessibility support
////////////////

    /**
     * Gets the AccessibleContext associated with this JTabbedPane.
     * For tabbed panes, the AccessibleContext takes the form of an
     * AccessibleJTabbedPane.
     * A new AccessibleJTabbedPane instance is created if necessary.
     *
     * @return an AccessibleJTabbedPane that serves as the
     *         AccessibleContext of this JTabbedPane
     */
    public AccessibleContext getAccessibleContext() {
        if (accessibleContext == null) {
            accessibleContext = new AccessibleJTabbedPane();

            // initialize AccessibleContext for the existing pages
            int count = getTabCount();
            for (int i = 0; i < count; i++) {
                pages.get(i).initAccessibleContext();
            }
        }
        return accessibleContext;
    }

    /**
     * This class implements accessibility support for the
     * <code>JTabbedPane</code> class.  It provides an implementation of the
     * Java Accessibility API appropriate to tabbed pane user-interface
     * elements.
     * <p>
     * <strong>Warning:</strong>
     * Serialized objects of this class will not be compatible with
     * future Swing releases. The current serialization support is
     * appropriate for short term storage or RMI between applications running
     * the same version of Swing.  As of 1.4, support for long term storage
     * of all JavaBeans<sup><font size="-2">TM</font></sup>
     * has been added to the <code>java.beans</code> package.
     * Please see {@link java.beans.XMLEncoder}.
     */
    protected class AccessibleJTabbedPane extends AccessibleJComponent
        implements AccessibleSelection, ChangeListener {

        /**
         * Returns the accessible name of this object, or {@code null} if
         * there is no accessible name.
         *
         * @return the accessible name of this object, nor {@code null}.
         * @since 1.6
         */
        public String getAccessibleName() {
            if (accessibleName != null) {
                return accessibleName;
            }

            String cp = (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);

            if (cp != null) {
                return cp;
            }

            int index = getSelectedIndex();

            if (index >= 0) {
                return pages.get(index).getAccessibleName();
            }

            return super.getAccessibleName();
        }

        /**
         *  Constructs an AccessibleJTabbedPane
         */
        public AccessibleJTabbedPane() {
            super();
            JTabbedPane.this.model.addChangeListener(this);
        }

        public void stateChanged(ChangeEvent e) {
            Object o = e.getSource();
            firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
                               null, o);
        }

        /**
         * Get the role of this object.
         *
         * @return an instance of AccessibleRole describing the role of
         *          the object
         */
        public AccessibleRole getAccessibleRole() {
            return AccessibleRole.PAGE_TAB_LIST;
        }

        /**
         * Returns the number of accessible children in the object.
         *
         * @return the number of accessible children in the object.
         */
        public int getAccessibleChildrenCount() {
            return getTabCount();
        }

        /**
         * Return the specified Accessible child of the object.
         *
         * @param i zero-based index of child
         * @return the Accessible child of the object
         * @exception IllegalArgumentException if index is out of bounds
         */
        public Accessible getAccessibleChild(int i) {
            if (i < 0 || i >= getTabCount()) {
                return null;
            }
            return pages.get(i);
        }

        /**
         * Gets the <code>AccessibleSelection</code> associated with
         * this object.  In the implementation of the Java
         * Accessibility API for this class,
         * returns this object, which is responsible for implementing the
         * <code>AccessibleSelection</code> interface on behalf of itself.
         *
         * @return this object
         */
        public AccessibleSelection getAccessibleSelection() {
           return this;
        }

        /**
         * Returns the <code>Accessible</code> child contained at
         * the local coordinate <code>Point</code>, if one exists.
         * Otherwise returns the currently selected tab.
         *
         * @return the <code>Accessible</code> at the specified
         *    location, if it exists
         */
        public Accessible getAccessibleAt(Point p) {
            int tab = ((TabbedPaneUI) ui).tabForCoordinate(JTabbedPane.this,
                                                           p.x, p.y);
            if (tab == -1) {
                tab = getSelectedIndex();
            }
            return getAccessibleChild(tab);
        }

        public int getAccessibleSelectionCount() {
            return 1;
        }

        public Accessible getAccessibleSelection(int i) {
            int index = getSelectedIndex();
            if (index == -1) {
                return null;
            }
            return pages.get(index);
        }

        public boolean isAccessibleChildSelected(int i) {
            return (i == getSelectedIndex());
        }

        public void addAccessibleSelection(int i) {
           setSelectedIndex(i);
        }

        public void removeAccessibleSelection(int i) {
           // can't do
        }

        public void clearAccessibleSelection() {
           // can't do
        }

        public void selectAllAccessibleSelection() {
           // can't do
        }
    }

    private class Page extends AccessibleContext
        implements Serializable, Accessible, AccessibleComponent {
        String title;
        Color background;
        Color foreground;
        Icon icon;
        Icon disabledIcon;
        JTabbedPane parent;
        Component component;
        String tip;
        boolean enabled = true;
        boolean needsUIUpdate;
        int mnemonic = -1;
        int mnemonicIndex = -1;
        Component tabComponent;

        Page(JTabbedPane parent,
             String title, Icon icon, Icon disabledIcon, Component component, String tip) {
            this.title = title;
            this.icon = icon;
            this.disabledIcon = disabledIcon;
            this.parent = parent;
            this.setAccessibleParent(parent);
            this.component = component;
            this.tip = tip;

            initAccessibleContext();
        }

        /*
         * initializes the AccessibleContext for the page
         */
        void initAccessibleContext() {
            if (JTabbedPane.this.accessibleContext != null &&
                component instanceof Accessible) {
                /*
                 * Do initialization if the AccessibleJTabbedPane
                 * has been instantiated. We do not want to load
                 * Accessibility classes unnecessarily.
                 */
                AccessibleContext ac;
                ac = component.getAccessibleContext();
                if (ac != null) {
                    ac.setAccessibleParent(this);
                }
            }
        }

        void setMnemonic(int mnemonic) {
            this.mnemonic = mnemonic;
            updateDisplayedMnemonicIndex();
        }

        int getMnemonic() {
            return mnemonic;
        }

        /*
         * Sets the page displayed mnemonic index
         */
        void setDisplayedMnemonicIndex(int mnemonicIndex) {
            if (this.mnemonicIndex != mnemonicIndex) {
                if (mnemonicIndex != -1 && (title == null ||
                        mnemonicIndex < 0 ||
                        mnemonicIndex >= title.length())) {
                    throw new IllegalArgumentException(
                                "Invalid mnemonic index: " + mnemonicIndex);
                }
                this.mnemonicIndex = mnemonicIndex;
                JTabbedPane.this.firePropertyChange("displayedMnemonicIndexAt",
                                                    null, null);
            }
        }

        /*
         * Returns the page displayed mnemonic index
         */
        int getDisplayedMnemonicIndex() {
            return this.mnemonicIndex;
        }

        void updateDisplayedMnemonicIndex() {
            setDisplayedMnemonicIndex(
                SwingUtilities.findDisplayedMnemonicIndex(title, mnemonic));
        }

        /////////////////
        // Accessibility support
        ////////////////

        public AccessibleContext getAccessibleContext() {
            return this;
        }


        // AccessibleContext methods

        public String getAccessibleName() {
            if (accessibleName != null) {
                return accessibleName;
            } else if (title != null) {
                return title;
            }
            return null;
        }

        public String getAccessibleDescription() {
            if (accessibleDescription != null) {
                return accessibleDescription;
            } else if (tip != null) {
                return tip;
            }
            return null;
        }

        public AccessibleRole getAccessibleRole() {
            return AccessibleRole.PAGE_TAB;
        }

        public AccessibleStateSet getAccessibleStateSet() {
            AccessibleStateSet states;
            states = parent.getAccessibleContext().getAccessibleStateSet();
            states.add(AccessibleState.SELECTABLE);
            int i = parent.indexOfTab(title);
            if (i == parent.getSelectedIndex()) {
                states.add(AccessibleState.SELECTED);
            }
            return states;
        }

        public int getAccessibleIndexInParent() {
            return parent.indexOfTab(title);
        }

        public int getAccessibleChildrenCount() {
            if (component instanceof Accessible) {
                return 1;
            } else {
                return 0;
            }
        }

        public Accessible getAccessibleChild(int i) {
            if (component instanceof Accessible) {
                return (Accessible) component;
            } else {
                return null;
            }
        }

        public Locale getLocale() {
            return parent.getLocale();
        }

        public AccessibleComponent getAccessibleComponent() {
            return this;
        }


        // AccessibleComponent methods

        public Color getBackground() {
            return background != null? background : parent.getBackground();
        }

        public void setBackground(Color c) {
            background = c;
        }

        public Color getForeground() {
            return foreground != null? foreground : parent.getForeground();
        }

        public void setForeground(Color c) {
            foreground = c;
        }

        public Cursor getCursor() {
            return parent.getCursor();
        }

        public void setCursor(Cursor c) {
            parent.setCursor(c);
        }

        public Font getFont() {
            return parent.getFont();
        }

        public void setFont(Font f) {
            parent.setFont(f);
        }

        public FontMetrics getFontMetrics(Font f) {
            return parent.getFontMetrics(f);
        }

        public boolean isEnabled() {
            return enabled;
        }

        public void setEnabled(boolean b) {
            enabled = b;
        }

        public boolean isVisible() {
            return parent.isVisible();
        }

        public void setVisible(boolean b) {
            parent.setVisible(b);
        }

        public boolean isShowing() {
            return parent.isShowing();
        }

        public boolean contains(Point p) {
            Rectangle r = getBounds();
            return r.contains(p);
        }

        public Point getLocationOnScreen() {
             Point parentLocation = parent.getLocationOnScreen();
             Point componentLocation = getLocation();
             componentLocation.translate(parentLocation.x, parentLocation.y);
             return componentLocation;
        }

        public Point getLocation() {
             Rectangle r = getBounds();
             return new Point(r.x, r.y);
        }

        public void setLocation(Point p) {
            // do nothing
        }

        public Rectangle getBounds() {
            return parent.getUI().getTabBounds(parent,
                                               parent.indexOfTab(title));
        }

        public void setBounds(Rectangle r) {
            // do nothing
        }

        public Dimension getSize() {
            Rectangle r = getBounds();
            return new Dimension(r.width, r.height);
        }

        public void setSize(Dimension d) {
            // do nothing
        }

        public Accessible getAccessibleAt(Point p) {
            if (component instanceof Accessible) {
                return (Accessible) component;
            } else {
                return null;
            }
        }

        public boolean isFocusTraversable() {
            return false;
        }

        public void requestFocus() {
            // do nothing
        }

        public void addFocusListener(FocusListener l) {
            // do nothing
        }

        public void removeFocusListener(FocusListener l) {
            // do nothing
        }

        // TIGER - 4732339
        /**
         * Returns an AccessibleIcon
         *
         * @return the enabled icon if one exists and the page
         * is enabled. Otherwise, returns the disabled icon if
         * one exists and the page is disabled.  Otherwise, null
         * is returned.
         */
        public AccessibleIcon [] getAccessibleIcon() {
            AccessibleIcon accessibleIcon = null;
            if (enabled && icon instanceof ImageIcon) {
                AccessibleContext ac =
                    ((ImageIcon)icon).getAccessibleContext();
                accessibleIcon = (AccessibleIcon)ac;
            } else if (!enabled && disabledIcon instanceof ImageIcon) {
                AccessibleContext ac =
                    ((ImageIcon)disabledIcon).getAccessibleContext();
                accessibleIcon = (AccessibleIcon)ac;
            }
            if (accessibleIcon != null) {
                AccessibleIcon [] returnIcons = new AccessibleIcon[1];
                returnIcons[0] = accessibleIcon;
                return returnIcons;
            } else {
                return null;
            }
        }
    }

    /**
    * Sets the component that is responsible for rendering the
    * title for the specified tab.  A null value means
    * <code>JTabbedPane</code> will render the title and/or icon for
    * the specified tab.  A non-null value means the component will
    * render the title and <code>JTabbedPane</code> will not render
    * the title and/or icon.
    * <p>
    * Note: The component must not be one that the developer has
    *       already added to the tabbed pane.
    *
    * @param index the tab index where the component should be set
    * @param component the component to render the title for the
    *                  specified tab
    * @exception IndexOutOfBoundsException if index is out of range
    *            (index < 0 || index >= tab count)
    * @exception IllegalArgumentException if component has already been
    *            added to this <code>JTabbedPane</code>
    *
    * @see #getTabComponentAt
    * @beaninfo
    *    preferred: true
    *    attribute: visualUpdate true
    *  description: The tab component at the specified tab index.
    * @since 1.6
    */
    public void setTabComponentAt(int index, Component component) {
        if (component != null && indexOfComponent(component) != -1) {
            throw new IllegalArgumentException("Component is already added to this JTabbedPane");
        }
        Component oldValue = getTabComponentAt(index);
        if (component != oldValue) {
            int tabComponentIndex = indexOfTabComponent(component);
            if (tabComponentIndex != -1) {
                setTabComponentAt(tabComponentIndex, null);
            }
            pages.get(index).tabComponent = component;
            firePropertyChange("indexForTabComponent", -1, index);
        }
    }

    /**
     * Returns the tab component at <code>index</code>.
     *
     * @param index  the index of the item being queried
     * @return the tab component at <code>index</code>
     * @exception IndexOutOfBoundsException if index is out of range
     *            (index < 0 || index >= tab count)
     *
     * @see #setTabComponentAt
     * @since 1.6
     */
    public Component getTabComponentAt(int index) {
        return pages.get(index).tabComponent;
    }

    /**
     * Returns the index of the tab for the specified tab component.
     * Returns -1 if there is no tab for this tab component.
     *
     * @param tabComponent the tab component for the tab
     * @return the first tab which matches this tab component, or -1
     *          if there is no tab for this tab component
     * @see #setTabComponentAt
     * @see #getTabComponentAt
     * @since 1.6
     */
     public int indexOfTabComponent(Component tabComponent) {
        for(int i = 0; i < getTabCount(); i++) {
            Component c = getTabComponentAt(i);
            if (c == tabComponent) {
                return i;
            }
        }
        return -1;
    }
}
