diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/javax/swing/JTabbedPane.java | |
download | cbb-gcc-4.6.4-upstream.tar.bz2 cbb-gcc-4.6.4-upstream.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/javax/swing/JTabbedPane.java')
-rw-r--r-- | libjava/classpath/javax/swing/JTabbedPane.java | 1728 |
1 files changed, 1728 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/JTabbedPane.java b/libjava/classpath/javax/swing/JTabbedPane.java new file mode 100644 index 000000000..18055e8a9 --- /dev/null +++ b/libjava/classpath/javax/swing/JTabbedPane.java @@ -0,0 +1,1728 @@ +/* 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; + } +} |