2 Copyright (C) 2002, 2004, 2005, 2006, Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
41 import java.awt.Color;
42 import java.awt.Component;
43 import java.awt.Point;
44 import java.awt.Rectangle;
45 import java.awt.event.MouseEvent;
46 import java.io.Serializable;
47 import java.util.Locale;
48 import java.util.Vector;
50 import javax.accessibility.Accessible;
51 import javax.accessibility.AccessibleContext;
52 import javax.accessibility.AccessibleRole;
53 import javax.accessibility.AccessibleSelection;
54 import javax.accessibility.AccessibleState;
55 import javax.accessibility.AccessibleStateSet;
56 import javax.swing.event.ChangeEvent;
57 import javax.swing.event.ChangeListener;
58 import javax.swing.plaf.TabbedPaneUI;
59 import javax.swing.plaf.UIResource;
62 * This is a container for components where only one component is displayed at
63 * a given time and the displayed component can be switched by clicking on
67 * Tabs can be oriented in several ways. They can be above, below, left and
68 * right of the component. Tabs can either wrap around (by creating multiple
69 * rows of tabs) or they can be scrolled (where only a subset of the tabs
70 * can be seen at once). More tabs can be added by calling the
71 * add/addTab/insertTab methods.
74 public class JTabbedPane extends JComponent implements Serializable,
79 * Accessibility support for <code>JTabbedPane</code>.
81 protected class AccessibleJTabbedPane extends JComponent.AccessibleJComponent
82 implements AccessibleSelection, ChangeListener
85 * The serialization UID.
87 private static final long serialVersionUID = 7610530885966830483L;
90 * Creates a new AccessibleJTabbedPane object.
92 public AccessibleJTabbedPane()
98 * Receives notification when the selection state of the
99 * <code>JTabbedPane</code> changes and fires appropriate property change
100 * events to interested listeners.
102 * @param e the change event describing the change
104 public void stateChanged(ChangeEvent e)
106 // I couldn't figure out what else should be done here.
107 Object source = e.getSource();
108 firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY,
113 * Returns the accessible role of the <code>JTabbedPane</code>, which is
114 * {@link AccessibleRole#PAGE_TAB_LIST}.
116 * @return the accessible role of the <code>JTabbedPane</code>
118 public AccessibleRole getAccessibleRole()
120 return AccessibleRole.PAGE_TAB_LIST;
124 * Returns the number of accessible child components of the
125 * <code>JTabbedPane</code>.
127 * @return the number of accessible child components of the
128 * <code>JTabbedPane</code>
130 public int getAccessibleChildrenCount()
132 return getTabCount();
136 * Returns the accessible child component at the specified index.
138 * @param i the index of the child component to fetch
140 * @return the accessible child component at the specified index
142 public Accessible getAccessibleChild(int i)
144 // Testing shows that the reference implementation returns instances
146 Accessible child = null;
147 if (i >= 0 && i < tabs.size())
148 child = (Page) tabs.get(i);
153 * Returns the current selection state of the <code>JTabbedPane</code>
154 * as AccessibleSelection object.
156 * @return the current selection state of the <code>JTabbedPane</code>
158 public AccessibleSelection getAccessibleSelection()
164 * Returns the accessible child component at the specified coordinates.
165 * If there is no child component at this location, then return the
166 * currently selected tab.
168 * @param p the coordinates at which to look up the child component
170 * @return the accessible child component at the specified coordinates or
171 * the currently selected tab if there is no child component at
174 public Accessible getAccessibleAt(Point p)
176 int tabIndex = indexAtLocation(p.x, p.y);
178 return getAccessibleChild(tabIndex);
180 return getAccessibleSelection(0);
184 * Returns the number of selected child components of the
185 * <code>JTabbedPane</code>. The reference implementation appears
186 * to return <code>1</code> always and we do the same.
188 * @return <code>1</code>
190 public int getAccessibleSelectionCount()
196 * Returns the selected tab, or <code>null</code> if there is no
199 * @param i the selection index (ignored here).
201 * @return The selected tab, or <code>null</code>.
203 public Accessible getAccessibleSelection(int i)
205 Accessible result = null;
206 int selected = getSelectedIndex();
208 result = (Page) tabs.get(selected);
213 * Returns <code>true</code> if the specified child is selected,
214 * and <code>false</code> otherwise.
216 * @param i the child index.
220 public boolean isAccessibleChildSelected(int i)
222 return i == getSelectedIndex();
226 * Selects the specified tab.
228 * @param i the index of the item to select.
230 public void addAccessibleSelection(int i)
236 * Does nothing - it makes no sense to remove a selection for a
237 * tabbed pane, since one tab must always be selected.
239 * @param i the item index.
241 * @see #addAccessibleSelection(int)
243 public void removeAccessibleSelection(int i)
249 * Does nothing - it makes no sense to clear the selection for
250 * a tabbed pane, since one tab must always be selected.
252 * @see #addAccessibleSelection(int)
254 public void clearAccessibleSelection()
260 * Does nothing - it makes no sense to select all for a tabbed
261 * pane, since only one tab can be selected at a time.
263 * @see #addAccessibleSelection(int)
265 public void selectAllAccessibleSelection()
272 * A helper class that listens for changes to the model.
274 protected class ModelListener implements ChangeListener, Serializable
276 private static final long serialVersionUID = 497359819958114132L;
279 * Creates a new ModelListener object.
281 protected ModelListener()
283 // Nothing to do here.
287 * This method is called whenever the model is changed.
289 * @param e The ChangeEvent that is passed from the model.
291 public void stateChanged(ChangeEvent e)
293 // Propagate to our listeners.
299 * A private class that holds all the information for each tab.
302 extends AccessibleContext
303 implements Accessible
305 /** The tooltip string. */
308 /** The component associated with the tab. */
309 private Component component;
311 /** The active icon associated with the tab. */
312 private transient Icon icon;
314 /** The disabled icon associated with the tab. */
315 private transient Icon disabledIcon;
317 /** The tab's enabled status. */
318 private transient boolean enabled = true;
320 /** The string painted on the tab. */
321 private transient String title;
323 /** The background color of the tab. */
324 private transient Color bg;
326 /** The foreground color of the tab. */
327 private transient Color fg;
329 /** The mnemonic associated with the tab. */
330 private transient int mnemonicKey;
332 /** The index of the underlined character in the string. */
333 private transient int underlinedChar = -1;
336 * Creates a new data storage for the tab.
338 * @param title The string displayed on the tab.
339 * @param icon The active icon displayed on the tab.
340 * @param component The component associated with the tab.
341 * @param tip The tooltip associated with the tab.
343 protected Page(String title, Icon icon, Component component, String tip)
347 this.component = component;
352 * This method returns the component associated with the tab.
354 * @return The component associated with the tab.
356 public Component getComponent()
362 * This method sets the component associated with the tab.
364 * @param c The component associated with the tab.
366 public void setComponent(Component c)
368 int i = indexOfComponent(component);
369 insertTab(title, icon, c, tip, i);
375 * This method returns the tooltip string.
377 * @return The tooltip string.
379 public String getTip()
385 * This method sets the tooltip string.
387 * @param tip The tooltip string.
389 public void setTip(String tip)
395 * This method returns the background color.
397 * @return The background color.
399 public Color getBackground()
403 background = JTabbedPane.this.getBackground();
410 * This method sets the background color.
412 * @param background The background color.
414 public void setBackground(Color background)
420 * This method returns the foreground color.
422 * @return The foreground color.
424 public Color getForeground()
428 foreground = JTabbedPane.this.getForeground();
435 * This method sets the foreground color.
437 * @param foreground The foreground color.
439 public void setForeground(Color foreground)
445 * This method returns the title associated with the tab.
447 * @return The title of the tab.
449 public String getTitle()
454 private static final long serialVersionUID = 1614381073220130939L;
457 * This method sets the title of the tab.
459 * @param text The title of the tab.
461 public void setTitle(String text)
464 if (title != null && title.length() <= underlinedChar)
465 setDisplayedMnemonicIndex(title.length() - 1);
469 * This method returns the active icon.
471 * @return The active icon.
473 public Icon getIcon()
479 * This method sets the active icon.
481 * @param icon The active icon.
483 public void setIcon(Icon icon)
489 * This method returns the disabled icon.
491 * @return The disabled icon.
493 public Icon getDisabledIcon()
495 if (disabledIcon == null && icon instanceof ImageIcon)
496 setDisabledIcon(icon);
501 * This method sets the disabled icon.
503 * @param disabledIcon The disabled icon.
505 public void setDisabledIcon(Icon disabledIcon)
507 this.disabledIcon = disabledIcon;
511 * This method returns whether the tab is enabled.
513 * @return Whether the tab is enabled.
515 public boolean isEnabled()
521 * This method sets whether the tab is enabled.
523 * @param enabled Whether this tab is enabled.
525 public void setEnabled(boolean enabled)
527 this.enabled = enabled;
531 * This method returns the mnemonic.
533 * @return The mnemonic.
535 public int getMnemonic()
541 * This method sets the mnemonic. If the title is set, it will update the
544 * @param key The mnemonic.
546 public void setMnemonic(int key)
548 setMnemonic((char) key);
552 * This method sets the mnemonic. If the title is set, it will update the
555 * @param aChar The mnemonic.
557 public void setMnemonic(char aChar)
561 setDisplayedMnemonicIndex(title.indexOf(mnemonicKey));
565 * This method returns the mnemonicIndex.
567 * @return The mnemonicIndex.
569 public int getDisplayedMnemonicIndex()
571 return underlinedChar;
575 * This method sets the mnemonicIndex.
577 * @param index The mnemonicIndex.
579 * @throws IllegalArgumentException If index less than -1 || index greater
580 * or equal to title.length.
582 public void setDisplayedMnemonicIndex(int index)
583 throws IllegalArgumentException
585 if (index < -1 || title != null && index >= title.length())
586 throw new IllegalArgumentException();
588 if (title == null || mnemonicKey == 0 || (index > -1 && title.charAt(index) != mnemonicKey))
591 underlinedChar = index;
595 * Returns the accessible context, which is this object itself.
597 * @return the accessible context, which is this object itself
599 public AccessibleContext getAccessibleContext()
605 * Returns the accessible name for this tab.
607 * @return The accessible name.
609 public String getAccessibleName()
611 if (accessibleName != null)
612 return accessibleName;
618 * Returns the accessible role of this tab, which is always
619 * {@link AccessibleRole#PAGE_TAB}.
621 * @return the accessible role of this tab
623 public AccessibleRole getAccessibleRole()
625 return AccessibleRole.PAGE_TAB;
629 * Returns the accessible state set of this object.
631 * @return the accessible state set of this object
633 public AccessibleStateSet getAccessibleStateSet()
635 AccessibleContext parentCtx = JTabbedPane.this.getAccessibleContext();
636 AccessibleStateSet state = parentCtx.getAccessibleStateSet();
637 state.add(AccessibleState.SELECTABLE);
638 if (component == getSelectedComponent())
639 state.add(AccessibleState.SELECTED);
644 * Returns the index of this tab inside its parent.
646 * @return the index of this tab inside its parent
648 public int getAccessibleIndexInParent()
650 // TODO: Not sure if the title is unambiguous, but I can't figure
651 // another way of doing this.
652 return indexOfTab(title);
656 * Returns the number of accessible children, which is always one (the
657 * component of this tab).
659 * @return the number of accessible children
661 public int getAccessibleChildrenCount()
667 * Returns the accessible child of this tab, which is the component
668 * displayed by the tab.
670 * @return the accessible child of this tab
672 public Accessible getAccessibleChild(int i)
674 // A quick test shows that this method always returns the component
675 // displayed by the tab, regardless of the index.
676 return (Accessible) component;
680 * Returns the locale of this accessible object.
682 * @return the locale of this accessible object
684 public Locale getLocale()
687 return Locale.getDefault();
691 private static final long serialVersionUID = 1614381073220130939L;
693 /** The changeEvent used to fire changes to listeners. */
694 protected ChangeEvent changeEvent;
696 /** The listener that listens to the model. */
697 protected ChangeListener changeListener;
699 /** The model that describes this JTabbedPane. */
700 protected SingleSelectionModel model;
702 /** Indicates that the TabbedPane is in scrolling mode. */
703 public static final int SCROLL_TAB_LAYOUT = 1;
705 /** Indicates that the TabbedPane is in wrap mode. */
706 public static final int WRAP_TAB_LAYOUT = 0;
708 /** The current tabPlacement of the TabbedPane. */
709 protected int tabPlacement = SwingConstants.TOP;
711 /** The current tabLayoutPolicy of the TabbedPane. */
712 private transient int layoutPolicy;
714 /** The list of tabs associated with the TabbedPane. */
715 transient Vector tabs = new Vector();
718 * Creates a new JTabbedPane object with tabs on top and using wrap tab
723 this(SwingConstants.TOP, WRAP_TAB_LAYOUT);
727 * Creates a new JTabbedPane object using wrap tab layout and the given
728 * <code>tabPlacement</code>, where <code>tabPlacement</code> can be one
729 * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or
732 * @param tabPlacement where the tabs will be placed
734 public JTabbedPane(int tabPlacement)
736 this(tabPlacement, WRAP_TAB_LAYOUT);
740 * Creates a new JTabbedPane object with the given <code>tabPlacement</code>
741 * and <code>tabLayoutPolicy</code>. The <code>tabPlacement</code> can be one
742 * of the following values: {@link #TOP}, {@link #BOTTOM}, {@link #LEFT} or
743 * {@link #RIGHT}. The <code>tabLayoutPolicy</code> can be either
744 * {@link #SCROLL_TAB_LAYOUT} or {@link #WRAP_TAB_LAYOUT}.
746 * @param tabPlacement where the tabs will be placed
747 * @param tabLayoutPolicy the way tabs will be placed
749 * @throws IllegalArgumentException If tabLayoutPolicy or tabPlacement are
752 public JTabbedPane(int tabPlacement, int tabLayoutPolicy)
754 if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT
755 && tabPlacement != LEFT)
756 throw new IllegalArgumentException("tabPlacement is not valid.");
757 if (tabLayoutPolicy != SCROLL_TAB_LAYOUT
758 && tabLayoutPolicy != WRAP_TAB_LAYOUT)
759 throw new IllegalArgumentException("tabLayoutPolicy is not valid.");
760 this.tabPlacement = tabPlacement;
761 layoutPolicy = tabLayoutPolicy;
763 changeEvent = new ChangeEvent(this);
764 changeListener = createChangeListener();
766 model = new DefaultSingleSelectionModel();
767 model.addChangeListener(changeListener);
773 * This method returns the UI used to display the JTabbedPane.
775 * @return The UI used to display the JTabbedPane.
777 public TabbedPaneUI getUI()
779 return (TabbedPaneUI) ui;
783 * This method sets the UI used to display the JTabbedPane.
785 * @param ui The UI used to display the JTabbedPane.
787 public void setUI(TabbedPaneUI ui)
793 * This method restores the UI to the defaults given by the UIManager.
795 public void updateUI()
797 setUI((TabbedPaneUI) UIManager.getUI(this));
801 * This method returns a string identifier that is used to determine which
802 * UI will be used with the JTabbedPane.
804 * @return A string identifier for the UI.
806 public String getUIClassID()
808 return "TabbedPaneUI";
812 * This method creates a ChangeListener that is used to listen to the model
815 * @return A ChangeListener to listen to the model.
817 protected ChangeListener createChangeListener()
819 return new ModelListener();
823 * This method adds a ChangeListener to the JTabbedPane.
825 * @param l The ChangeListener to add.
827 public void addChangeListener(ChangeListener l)
829 listenerList.add(ChangeListener.class, l);
833 * This method removes a ChangeListener to the JTabbedPane.
835 * @param l The ChangeListener to remove.
837 public void removeChangeListener(ChangeListener l)
839 listenerList.remove(ChangeListener.class, l);
843 * This method fires a ChangeEvent to all the JTabbedPane's ChangeListeners.
845 protected void fireStateChanged()
847 Object[] changeListeners = listenerList.getListenerList();
848 if (changeEvent == null)
849 changeEvent = new ChangeEvent(this);
850 for (int i = changeListeners.length - 2; i >= 0; i -= 2)
852 if (changeListeners[i] == ChangeListener.class)
853 ((ChangeListener) changeListeners[i + 1]).stateChanged(changeEvent);
858 * This method returns all ChangeListeners registered with the JTabbedPane.
860 * @return The ChangeListeners registered with the JTabbedPane.
862 public ChangeListener[] getChangeListeners()
864 return (ChangeListener[]) super.getListeners(ChangeListener.class);
868 * This method returns the model used with the JTabbedPane.
870 * @return The JTabbedPane's model.
872 public SingleSelectionModel getModel()
878 * This method changes the model property of the JTabbedPane.
880 * @param model The new model to use with the JTabbedPane.
882 public void setModel(SingleSelectionModel model)
884 if (model != this.model)
886 SingleSelectionModel oldModel = this.model;
887 this.model.removeChangeListener(changeListener);
889 this.model.addChangeListener(changeListener);
890 firePropertyChange("model", oldModel, this.model);
895 * This method returns the tabPlacement.
897 * @return The tabPlacement used with the JTabbedPane.
899 public int getTabPlacement()
905 * This method changes the tabPlacement property of the JTabbedPane.
907 * @param tabPlacement The tabPlacement to use.
909 * @throws IllegalArgumentException If tabPlacement is not one of TOP,
910 * BOTTOM, LEFT, or RIGHT.
912 public void setTabPlacement(int tabPlacement)
914 if (tabPlacement != TOP && tabPlacement != BOTTOM && tabPlacement != RIGHT
915 && tabPlacement != LEFT)
916 throw new IllegalArgumentException("tabPlacement is not valid.");
917 if (tabPlacement != this.tabPlacement)
919 int oldPlacement = this.tabPlacement;
920 this.tabPlacement = tabPlacement;
921 firePropertyChange("tabPlacement", oldPlacement, this.tabPlacement);
926 * This method returns the tabLayoutPolicy.
928 * @return The tabLayoutPolicy.
930 public int getTabLayoutPolicy()
936 * This method changes the tabLayoutPolicy property of the JTabbedPane.
938 * @param tabLayoutPolicy The tabLayoutPolicy to use.
940 * @throws IllegalArgumentException If tabLayoutPolicy is not one of
941 * SCROLL_TAB_LAYOUT or WRAP_TAB_LAYOUT.
943 public void setTabLayoutPolicy(int tabLayoutPolicy)
945 if (tabLayoutPolicy != SCROLL_TAB_LAYOUT
946 && tabLayoutPolicy != WRAP_TAB_LAYOUT)
947 throw new IllegalArgumentException("tabLayoutPolicy is not valid.");
948 if (tabLayoutPolicy != layoutPolicy)
950 int oldPolicy = layoutPolicy;
951 layoutPolicy = tabLayoutPolicy;
952 firePropertyChange("tabLayoutPolicy", oldPolicy, layoutPolicy);
957 * This method returns the index of the tab that is currently selected.
959 * @return The index of the selected tab.
961 public int getSelectedIndex()
963 return model.getSelectedIndex();
967 * This method checks the index.
969 * @param index The index to check.
970 * @param start DOCUMENT ME!
971 * @param end DOCUMENT ME!
973 * @throws IndexOutOfBoundsException DOCUMENT ME!
975 private void checkIndex(int index, int start, int end)
977 if (index < start || index >= end)
978 throw new IndexOutOfBoundsException("Index < " + start + " || Index >= "
983 * This method sets the selected index. This method will hide the old
984 * component and show the new component.
986 * @param index The index to set it at.
988 public void setSelectedIndex(int index)
990 checkIndex(index, -1, tabs.size());
991 if (index != getSelectedIndex())
993 model.setSelectedIndex(index);
998 * This method returns the component at the selected index.
1000 * @return The component at the selected index.
1002 public Component getSelectedComponent()
1004 int selectedIndex = getSelectedIndex();
1005 Component selected = null;
1006 if (selectedIndex >= 0)
1007 selected = getComponentAt(selectedIndex);
1012 * This method sets the component at the selected index.
1014 * @param c The component associated with the selected index.
1016 public void setSelectedComponent(Component c)
1018 if (c.getParent() == this)
1019 setSelectedIndex(indexOfComponent(c));
1021 setComponentAt(getSelectedIndex(), c);
1025 * This method inserts tabs into JTabbedPane. This includes adding the
1026 * component to the JTabbedPane and hiding it.
1028 * @param title the title of the tab; may be <code>null</code>
1029 * @param icon the tab's icon; may be <code>null</code>
1030 * @param component the component associated with the tab
1031 * @param tip the tooltip for the tab
1032 * @param index the index to insert the tab at
1034 public void insertTab(String title, Icon icon, Component component,
1035 String tip, int index)
1039 Page p = new Page(title, icon, component, tip);
1040 tabs.insertElementAt(p, index);
1042 // Hide the component so we don't see it. Do it before we parent it
1043 // so we don't trigger a repaint.
1044 if (component != null)
1047 super.add(component);
1050 if (getSelectedIndex() == -1)
1051 setSelectedIndex(0);
1058 * This method adds a tab to the JTabbedPane.
1060 * @param title the title of the tab; may be <code>null</code>
1061 * @param icon the icon for the tab; may be <code>null</code>
1062 * @param component the associated component
1063 * @param tip the associated tooltip
1065 public void addTab(String title, Icon icon, Component component, String tip)
1067 insertTab(title, icon, component, tip, tabs.size());
1071 * This method adds a tab to the JTabbedPane.
1073 * @param title the title of the tab; may be <code>null</code>
1074 * @param icon the icon for the tab; may be <code>null</code>
1075 * @param component the associated component
1077 public void addTab(String title, Icon icon, Component component)
1079 insertTab(title, icon, component, null, tabs.size());
1083 * This method adds a tab to the JTabbedPane.
1085 * @param title the title of the tab; may be <code>null</code>
1086 * @param component the associated component
1088 public void addTab(String title, Component component)
1090 insertTab(title, null, component, null, tabs.size());
1094 * This method adds a tab to the JTabbedPane. The title of the tab is the
1095 * Component's name. If the Component is an instance of UIResource, it
1096 * doesn't add the tab and instead add the component directly to the
1099 * @param component The associated component.
1101 * @return The Component that was added.
1103 public Component add(Component component)
1105 if (component instanceof UIResource)
1106 super.add(component);
1108 insertTab(component.getName(), null, component, null, tabs.size());
1114 * This method adds a tab to the JTabbedPane. If the Component is an
1115 * instance of UIResource, it doesn't add the tab and instead add the
1116 * component directly to the JTabbedPane.
1118 * @param title the title of the tab; may be <code>null</code>
1119 * @param component the associated component
1121 * @return The Component that was added.
1123 public Component add(String title, Component component)
1125 if (component instanceof UIResource)
1126 super.add(component);
1128 insertTab(title, null, component, null, tabs.size());
1133 * This method adds a tab to the JTabbedPane. If the Component is an
1134 * instance of UIResource, it doesn't add the tab and instead add the
1135 * component directly to the JTabbedPane.
1137 * @param component The associated component.
1138 * @param index The index to insert the tab at.
1140 * @return The Component that was added.
1142 public Component add(Component component, int index)
1144 if (component instanceof UIResource)
1145 super.add(component);
1147 insertTab(component.getName(), null, component, null, index);
1152 * This method adds a tab to the JTabbedPane. If the Component is an
1153 * instance of UIResource, it doesn't add the tab and instead add the
1154 * component directly to the JTabbedPane. If the constraints object is an
1155 * icon, it will be used as the tab's icon. If the constraints object is a
1156 * string, we will use it as the title.
1158 * @param component The associated component.
1159 * @param constraints The constraints object.
1161 public void add(Component component, Object constraints)
1163 add(component, constraints, tabs.size());
1167 * This method adds a tab to the JTabbedPane. If the Component is an
1168 * instance of UIResource, it doesn't add the tab and instead add the
1169 * component directly to the JTabbedPane. If the constraints object is an
1170 * icon, it will be used as the tab's icon. If the constraints object is a
1171 * string, we will use it as the title.
1173 * @param component The associated component.
1174 * @param constraints The constraints object.
1175 * @param index The index to insert the tab at.
1177 public void add(Component component, Object constraints, int index)
1179 if (component instanceof UIResource)
1180 super.add(component);
1183 if (constraints instanceof String)
1184 insertTab((String) constraints, null, component, null, index);
1186 insertTab(component.getName(),
1187 (constraints instanceof Icon) ? (Icon) constraints : null,
1188 component, null, index);
1193 * Removes the tab at index. After the component associated with
1194 * index is removed, its visibility is reset to true to ensure it
1195 * will be visible if added to other containers.
1197 * @param index The index of the tab to remove.
1199 public void removeTabAt(int index)
1201 checkIndex(index, 0, tabs.size());
1203 // We need to adjust the selection if we remove a tab that comes
1204 // before the selected tab or if the selected tab is removed.
1205 // This decrements the selected index by 1 if any of this is the case.
1206 // Note that this covers all cases:
1207 // - When the selected tab comes after the removed tab, this simply
1208 // adjusts the selection so that after the removal the selected tab
1209 // is still the same.
1210 // - When we remove the currently selected tab, then the tab before the
1211 // selected tab gets selected.
1212 // - When the last tab is removed, then we have an index==0, which gets
1213 // decremented to -1, which means no selection, which is 100% perfect.
1214 int selectedIndex = getSelectedIndex();
1215 if (selectedIndex >= index)
1216 setSelectedIndex(selectedIndex - 1);
1218 Component comp = getComponentAt(index);
1220 // Remove the tab object.
1223 // Remove the component. I think we cannot assume that the tab order
1224 // is equal to the component order, so we iterate over the children
1225 // here to find the and remove the correct component.
1228 Component[] children = getComponents();
1229 for (int i = children.length - 1; i >= 0; --i)
1231 if (children[i] == comp)
1234 comp.setVisible(true);
1244 * Removes the specified Component from the JTabbedPane.
1246 * @param component The Component to remove.
1248 public void remove(Component component)
1250 super.remove(component);
1254 * Removes the tab and component which corresponds to the specified index.
1256 * @param index The index of the tab to remove.
1258 public void remove(int index)
1260 super.remove(index);
1265 * This method removes all tabs and associated components from the
1268 public void removeAll()
1270 setSelectedIndex(-1);
1271 for (int i = getTabCount() - 1; i >= 0; i--)
1276 * This method returns how many tabs are in the JTabbedPane.
1278 * @return The number of tabs in the JTabbedPane.
1280 public int getTabCount()
1286 * This method returns the number of runs used to paint the JTabbedPane.
1288 * @return The number of runs.
1290 public int getTabRunCount()
1292 return ((TabbedPaneUI) ui).getTabRunCount(this);
1296 * This method returns the tab title given the index.
1298 * @param index The index of the tab.
1300 * @return The title for the tab.
1302 public String getTitleAt(int index)
1304 checkIndex(index, 0, tabs.size());
1305 return ((Page) tabs.elementAt(index)).getTitle();
1309 * This method returns the active icon given the index.
1311 * @param index The index of the tab.
1313 * @return The active icon for the tab.
1315 public Icon getIconAt(int index)
1317 checkIndex(index, 0, tabs.size());
1318 return ((Page) tabs.elementAt(index)).getIcon();
1322 * This method returns the disabled icon given the index.
1324 * @param index The index of the tab.
1326 * @return The disabled icon for the tab.
1328 public Icon getDisabledIconAt(int index)
1330 checkIndex(index, 0, tabs.size());
1331 return ((Page) tabs.elementAt(index)).getDisabledIcon();
1335 * This method returns the tooltip string for the tab.
1337 * @param index The index of the tab.
1339 * @return The tooltip string for the tab.
1341 public String getToolTipTextAt(int index)
1343 checkIndex(index, 0, tabs.size());
1344 return ((Page) tabs.elementAt(index)).getTip();
1348 * This method returns the foreground color for the tab.
1350 * @param index The index of the tab.
1352 * @return The foreground color for the tab.
1354 public Color getForegroundAt(int index)
1356 checkIndex(index, 0, tabs.size());
1357 return ((Page) tabs.elementAt(index)).getForeground();
1361 * This method returns the background color for the tab.
1363 * @param index The index of the tab.
1365 * @return The background color for the tab.
1367 public Color getBackgroundAt(int index)
1369 checkIndex(index, 0, tabs.size());
1370 return ((Page) tabs.elementAt(index)).getBackground();
1374 * This method returns the component associated with the tab.
1376 * @param index The index of the tab.
1378 * @return The component associated with the tab.
1380 public Component getComponentAt(int index)
1382 checkIndex(index, 0, tabs.size());
1383 return ((Page) tabs.elementAt(index)).getComponent();
1387 * This method returns whether this tab is enabled. Disabled tabs cannot be
1390 * @param index The index of the tab.
1392 * @return Whether the tab is enabled.
1394 public boolean isEnabledAt(int index)
1396 checkIndex(index, 0, tabs.size());
1397 return ((Page) tabs.elementAt(index)).isEnabled();
1401 * This method returns the mnemonic for the tab.
1403 * @param tabIndex The index of the tab.
1405 * @return The mnemonic for the tab.
1407 public int getMnemonicAt(int tabIndex)
1409 checkIndex(tabIndex, 0, tabs.size());
1410 return ((Page) tabs.elementAt(tabIndex)).getMnemonic();
1414 * This method returns the mnemonic index for the tab.
1416 * @param tabIndex The index of the tab.
1418 * @return The mnemonic index for the tab.
1420 public int getDisplayedMnemonicIndexAt(int tabIndex)
1422 checkIndex(tabIndex, 0, tabs.size());
1423 return ((Page) tabs.elementAt(tabIndex)).getDisplayedMnemonicIndex();
1427 * This method returns the bounds of the tab given the index.
1429 * @param index The index of the tab.
1431 * @return A rectangle describing the bounds of the tab.
1433 public Rectangle getBoundsAt(int index)
1435 checkIndex(index, 0, tabs.size());
1436 return ((TabbedPaneUI) ui).getTabBounds(this, index);
1440 * This method sets the title of the tab.
1442 * @param index The index of the tab.
1443 * @param title The new title.
1445 public void setTitleAt(int index, String title)
1447 checkIndex(index, 0, tabs.size());
1448 ((Page) tabs.elementAt(index)).setTitle(title);
1452 * This method sets the icon of the tab.
1454 * @param index The index of the tab.
1455 * @param icon The new icon.
1457 public void setIconAt(int index, Icon icon)
1459 checkIndex(index, 0, tabs.size());
1460 ((Page) tabs.elementAt(index)).setIcon(icon);
1464 * This method sets the disabled icon of the tab.
1466 * @param index The index of the tab.
1467 * @param disabledIcon The new disabled icon.
1469 public void setDisabledIconAt(int index, Icon disabledIcon)
1471 checkIndex(index, 0, tabs.size());
1472 ((Page) tabs.elementAt(index)).setDisabledIcon(disabledIcon);
1476 * This method sets the tooltip text of the tab.
1478 * @param index The index of the tab.
1479 * @param toolTipText The tooltip text.
1481 public void setToolTipTextAt(int index, String toolTipText)
1483 checkIndex(index, 0, tabs.size());
1484 ((Page) tabs.elementAt(index)).setTip(toolTipText);
1488 * This method sets the background color of the tab.
1490 * @param index The index of the tab.
1491 * @param background The background color of the tab.
1493 public void setBackgroundAt(int index, Color background)
1495 checkIndex(index, 0, tabs.size());
1496 ((Page) tabs.elementAt(index)).setBackground(background);
1500 * This method sets the foreground color of the tab.
1502 * @param index The index of the tab.
1503 * @param foreground The foreground color of the tab.
1505 public void setForegroundAt(int index, Color foreground)
1507 checkIndex(index, 0, tabs.size());
1508 ((Page) tabs.elementAt(index)).setForeground(foreground);
1512 * This method sets whether the tab is enabled.
1514 * @param index The index of the tab.
1515 * @param enabled Whether the tab is enabled.
1517 public void setEnabledAt(int index, boolean enabled)
1519 checkIndex(index, 0, tabs.size());
1520 ((Page) tabs.elementAt(index)).setEnabled(enabled);
1524 * This method sets the component associated with the tab.
1526 * @param index The index of the tab.
1527 * @param component The component associated with the tab.
1529 public void setComponentAt(int index, Component component)
1531 checkIndex(index, 0, tabs.size());
1532 ((Page) tabs.elementAt(index)).setComponent(component);
1536 * This method sets the displayed mnemonic index of the tab.
1538 * @param tabIndex The index of the tab.
1539 * @param mnemonicIndex The mnemonic index.
1541 public void setDisplayedMnemonicIndexAt(int tabIndex, int mnemonicIndex)
1543 checkIndex(tabIndex, 0, tabs.size());
1544 ((Page) tabs.elementAt(tabIndex)).setDisplayedMnemonicIndex(mnemonicIndex);
1548 * This method sets the mnemonic for the tab.
1550 * @param tabIndex The index of the tab.
1551 * @param mnemonic The mnemonic.
1553 public void setMnemonicAt(int tabIndex, int mnemonic)
1555 checkIndex(tabIndex, 0, tabs.size());
1556 ((Page) tabs.elementAt(tabIndex)).setMnemonic(mnemonic);
1560 * This method finds the index of a tab given the title.
1562 * @param title The title that belongs to a tab.
1564 * @return The index of the tab that has the title or -1 if not found.
1566 public int indexOfTab(String title)
1569 for (int i = 0; i < tabs.size(); i++)
1571 if (((Page) tabs.elementAt(i)).getTitle().equals(title))
1581 * This method finds the index of a tab given the icon.
1583 * @param icon The icon that belongs to a tab.
1585 * @return The index of the tab that has the icon or -1 if not found.
1587 public int indexOfTab(Icon icon)
1590 for (int i = 0; i < tabs.size(); i++)
1592 if (((Page) tabs.elementAt(i)).getIcon() == icon)
1602 * This method finds the index of a tab given the component.
1604 * @param component A component associated with a tab.
1606 * @return The index of the tab that has this component or -1 if not found.
1608 public int indexOfComponent(Component component)
1611 for (int i = 0; i < tabs.size(); i++)
1613 if (((Page) tabs.elementAt(i)).getComponent() == component)
1623 * This method returns a tab index given an (x,y) location. The origin of
1624 * the (x,y) pair will be the JTabbedPane's top left position. The tab
1625 * returned will be the one that contains the point. This method is
1626 * delegated to the UI.
1628 * @param x The x coordinate of the point.
1629 * @param y The y coordinate of the point.
1631 * @return The index of the tab that contains the point.
1633 public int indexAtLocation(int x, int y)
1635 return ((TabbedPaneUI) ui).tabForCoordinate(this, x, y);
1639 * This method returns the tooltip text given a mouse event.
1641 * @param event The mouse event.
1643 * @return The tool tip text that is associated with this mouse event.
1645 public String getToolTipText(MouseEvent event)
1647 int index = indexAtLocation(event.getX(), event.getY());
1648 return ((Page) tabs.elementAt(index)).getTip();
1652 * Returns a string describing the attributes for the
1653 * <code>JTabbedPane</code> component, for use in debugging. The return
1654 * value is guaranteed to be non-<code>null</code>, but the format of the
1655 * string may vary between implementations.
1657 * @return A string describing the attributes of the
1658 * <code>JTabbedPane</code>.
1660 protected String paramString()
1662 StringBuffer sb = new StringBuffer(super.paramString());
1663 sb.append(",tabPlacement=");
1664 if (tabPlacement == TOP)
1666 if (tabPlacement == BOTTOM)
1667 sb.append("BOTTOM");
1668 if (tabPlacement == LEFT)
1670 if (tabPlacement == RIGHT)
1672 return sb.toString();
1676 * Returns the object that provides accessibility features for this
1677 * <code>JTabbedPane</code> component.
1679 * @return The accessible context (an instance of
1680 * {@link AccessibleJTabbedPane}).
1682 public AccessibleContext getAccessibleContext()
1684 if (accessibleContext == null)
1686 AccessibleJTabbedPane ctx = new AccessibleJTabbedPane();
1687 addChangeListener(ctx);
1688 accessibleContext = ctx;
1691 return accessibleContext;