KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > wings > STabbedPane


1 /*
2  * $Id: STabbedPane.java,v 1.20 2005/05/27 12:51:29 blueshift Exp $
3  * Copyright 2000,2005 wingS development team.
4  *
5  * This file is part of wingS (http://www.j-wings.org).
6  *
7  * wingS is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1
10  * of the License, or (at your option) any later version.
11  *
12  * Please see COPYING for the complete licence.
13  */

14 package org.wings;
15
16 import org.wings.plaf.TabbedPaneCG;
17 import org.wings.style.CSSAttributeSet;
18 import org.wings.style.CSSProperty;
19 import org.wings.style.CSSSelector;
20 import org.wings.style.CSSStyleSheet;
21
22 import javax.swing.*;
23 import javax.swing.event.ChangeEvent JavaDoc;
24 import javax.swing.event.ChangeListener JavaDoc;
25 import java.awt.*;
26 import java.io.Serializable JavaDoc;
27 import java.util.ArrayList JavaDoc;
28
29 // FIXME refactorize.
30

31 /**
32  * A tabbed pane shows one tab (usually a panel) at a moment.
33  * The user can switch between the panels.
34  *
35  * @author <a HREF="mailto:haaf@mercatis.de">Armin Haaf</a>,
36  * <a HREF="mailto:andre.lison@general-bytes.com">Andre Lison</a>
37  * @version $Revision: 1.20 $
38  */

39 public class STabbedPane extends SContainer implements LowLevelEventListener, ChangeListener JavaDoc {
40     /**
41      * A Pseudo CSS selector addressing the area which contains the tab buttons.
42      * Refer to {@link SComponent#setAttribute(org.wings.style.CSSSelector, org.wings.style.CSSProperty, String)}
43      */

44     public static final CSSSelector.Pseudo SELECTOR_TAB_AREA = new CSSSelector.Pseudo("area containing the tab buttons");
45
46     /**
47      * A Pseudo CSS selector addressing the selected tab
48      * Refer to {@link SComponent#setAttribute(org.wings.style.CSSSelector, org.wings.style.CSSProperty, String)}
49      */

50     public static final CSSSelector.Pseudo SELECTOR_SELECTED_TAB = new CSSSelector.Pseudo("the elements of the selected tab");
51
52     /**
53      * A Pseudo CSS selector addressing the unselected tab
54      * Refer to {@link SComponent#setAttribute(org.wings.style.CSSSelector, org.wings.style.CSSProperty, String)}
55      */

56     public static final CSSSelector.Pseudo SELECTOR_UNSELECTED_TAB = new CSSSelector.Pseudo("the elements of the unselected tab");
57
58
59     /**
60      * Where the tabs are placed.
61      *
62      * @see #setTabPlacement
63      */

64     protected int tabPlacement = SConstants.TOP;
65
66     /**
67      * The default selection model
68      */

69     protected SingleSelectionModel model;
70
71     ArrayList JavaDoc pages = new ArrayList JavaDoc(2);
72
73     /**
74      * layout used to render the tabs. Only one tab is on top at a time.
75      */

76     final private SCardLayout card = new SCardLayout();
77
78     /**
79      * container for all tabs. The card layout shows always one on
80      * top.
81      */

82     final private SContainer contents = new SContainer(card);
83
84     /**
85      * the maximum tabs per line
86      */

87     protected int maxTabsPerLine = -1;
88
89     /**
90      * Number of selected tab.
91      */

92     protected int selectedIndex = 0;
93
94     /**
95      * the newly selected index during a
96      * lowlevelevent
97      */

98     private int lleChangedIndex = -1;
99
100     /**
101      * @see LowLevelEventListener#isEpochCheckEnabled()
102      */

103     private boolean epochCheckEnabled = true;
104
105
106     /**
107      * Creates a new empty Tabbed Pane with the tabs at the top.
108      *
109      * @see #addTab
110      */

111     public STabbedPane() {
112         this(SConstants.TOP);
113     }
114
115     /**
116      * Creates an empty TabbedPane with the specified tab placement
117      * of either: TOP, BOTTOM, LEFT, or RIGHT.
118      *
119      * @param tabPlacement the placement for the tabs relative to the content
120      * @see #addTab
121      */

122     public STabbedPane(int tabPlacement) {
123         setTabPlacement(tabPlacement);
124         super.addComponent(contents, null, 0);
125         setModel(new DefaultSingleSelectionModel());
126     }
127
128     /**
129      * Return the background color.
130      *
131      * @return the background color
132      */

133     public Color getSelectionBackground() {
134         return dynamicStyles == null || dynamicStyles.get(SELECTOR_SELECTED_TAB) == null ? null : CSSStyleSheet.getBackground((CSSAttributeSet) dynamicStyles.get(SELECTOR_SELECTED_TAB));
135     }
136
137     /**
138      * Set the foreground color.
139      *
140      * @param color the new foreground color
141      */

142     public void setSelectionBackground(Color color) {
143         setAttribute(SELECTOR_SELECTED_TAB, CSSProperty.BACKGROUND_COLOR, CSSStyleSheet.getAttribute(color));
144     }
145
146     /**
147      * Return the foreground color.
148      *
149      * @return the foreground color
150      */

151     public Color getSelectionForeground() {
152         return dynamicStyles == null || dynamicStyles.get(SELECTOR_SELECTED_TAB) == null ? null : CSSStyleSheet.getForeground((CSSAttributeSet) dynamicStyles.get(SELECTOR_SELECTED_TAB));
153     }
154
155     /**
156      * Set the foreground color.
157      *
158      * @param color the new foreground color
159      */

160     public void setSelectionForeground(Color color) {
161         setAttribute(SELECTOR_SELECTED_TAB, CSSProperty.COLOR, CSSStyleSheet.getAttribute(color));
162     }
163
164     /**
165      * Set the font.
166      *
167      * @param font the new font
168      */

169     public void setSelectionFont(SFont font) {
170         setAttributes(SELECTOR_SELECTED_TAB, CSSStyleSheet.getAttributes(font));
171     }
172
173     /**
174      * Return the font.
175      *
176      * @return the font
177      */

178     public SFont getSelectionFont() {
179         return dynamicStyles == null || dynamicStyles.get(SELECTOR_SELECTED_TAB) == null ? null : CSSStyleSheet.getFont((CSSAttributeSet) dynamicStyles.get(SELECTOR_SELECTED_TAB));
180     }
181
182     /**
183      * Add a listener to the list of change listeners.
184      * ChangeListeners are notified, when the tab selection changes.
185      *
186      * @param cl add to listener list
187      */

188     public void addChangeListener(ChangeListener JavaDoc cl) {
189         addEventListener(ChangeListener JavaDoc.class, cl);
190     }
191
192     /**
193      * Remove listener from the list of change listeners.
194      * ChangeListeners are notified, when the tab selection changes.
195      *
196      * @param cl remove from listener list
197      */

198     public void removeChangeListener(ChangeListener JavaDoc cl) {
199         removeEventListener(ChangeListener JavaDoc.class, cl);
200     }
201
202     /**
203      * Fire ChangeEvents at all registered change listeners.
204      */

205     protected void fireStateChanged() {
206         ChangeEvent JavaDoc event = null;
207
208         // maybe the better way to do this is to user the getListenerList
209
// and iterate through all listeners, this saves the creation of
210
// an array but it must cast to the apropriate listener
211
Object JavaDoc[] listeners = getListenerList();
212         for (int i = listeners.length - 2; i >= 0; i -= 2) {
213             if (listeners[i] == ChangeListener JavaDoc.class) {
214                 // Lazily create the event:
215
if (event == null)
216                     event = new ChangeEvent JavaDoc(this);
217                 ((ChangeListener JavaDoc) listeners[i + 1]).stateChanged(event);
218             }
219         }
220     }
221
222     /**
223      * Returns the placement of the tabs for this tabbedpane.
224      *
225      * @see #setTabPlacement
226      */

227     public int getTabPlacement() {
228         return tabPlacement;
229     }
230
231     /**
232      * Sets the tab placement for this tabbedpane.
233      * Possible values are:<ul>
234      * <li>SConstants.TOP
235      * <li>SConstants.BOTTOM
236      * <li>SConstants.LEFT
237      * <li>SConstants.RIGHT
238      * </ul>
239      * The default value is TOP.
240      *
241      * @param tabPlacement the placement for the tabs relative to the content
242      */

243     public void setTabPlacement(int tabPlacement) {
244         if (tabPlacement != SConstants.TOP && tabPlacement != SConstants.LEFT &&
245                 tabPlacement != SConstants.BOTTOM && tabPlacement != SConstants.RIGHT) {
246             throw new IllegalArgumentException JavaDoc("illegal tab placement: must be TOP, BOTTOM, LEFT, or RIGHT");
247         }
248
249         this.tabPlacement = tabPlacement;
250     }
251
252     /**
253      * Returns the model associated with this tabbedpane.
254      *
255      * @see #setModel
256      */

257     public SingleSelectionModel getModel() {
258         return model;
259     }
260
261     /**
262      * Sets the model to be used with this tabbedpane.
263      *
264      * @param model the model to be used
265      * @see #getModel
266      */

267     public void setModel(SingleSelectionModel model) {
268         if (this.model != null)
269             this.model.removeChangeListener(this);
270         this.model = model;
271         if (this.model != null)
272             this.model.addChangeListener(this);
273     }
274
275     /**
276      * Returns the currently selected index for this tabbedpane.
277      * Returns -1 if there is no currently selected tab.
278      *
279      * @return the index of the selected tab
280      * @see #setSelectedIndex
281      */

282     public int getSelectedIndex() {
283         return model.getSelectedIndex();
284     }
285
286     /**
287      * Sets the selected index for this tabbedpane.
288      *
289      * @see #getSelectedIndex
290      * @see SingleSelectionModel#setSelectedIndex
291      */

292     public void setSelectedIndex(int index) {
293         model.setSelectedIndex(index);
294     }
295
296     /**
297      * Returns the currently selected component for this tabbedpane.
298      * Returns null if there is no currently selected tab.
299      *
300      * @return the component corresponding to the selected tab
301      * @see #setSelectedComponent
302      */

303     public SComponent getSelectedComponent() {
304         int index = getSelectedIndex();
305         if (index == -1) {
306             return null;
307         }
308         return ((Page) pages.get(index)).component;
309     }
310
311     /**
312      * Sets the selected component for this tabbedpane. This
313      * will automatically set the selectedIndex to the index
314      * corresponding to the specified component.
315      *
316      * @see #getSelectedComponent
317      */

318     public void setSelectedComponent(SComponent c) {
319         int index = indexOfComponent(c);
320         if (index != -1) {
321             setSelectedIndex(index);
322         } else {
323             throw new IllegalArgumentException JavaDoc("component not found in tabbed pane");
324         }
325     }
326
327     /**
328      * Returns the index of the tab for the specified component.
329      * Returns -1 if there is no tab for this component.
330      *
331      * @param component the component for the tab
332      */

333     public int indexOfComponent(SComponent component) {
334         for (int i = 0; i < getTabCount(); ++i) {
335             if (((Page) pages.get(i)).component.equals(component)) {
336                 return i;
337             }
338         }
339         return -1;
340     }
341
342     /**
343      * Returns the number of tabs in this tabbedpane.
344      *
345      * @return an int specifying the number of tabbed pages
346      */

347     public int getTabCount() {
348         return pages.size();
349     }
350
351     /**
352      * Inserts a <i>component</i>, at <i>index</i>, represented by a
353      * <i>title</i> and/or <i>icon</i>, either of which may be null.
354      * Uses java.util.ArrayList internally, see insertElementAt()
355      * for details of insertion conventions.
356      *
357      * @param title the title to be displayed in this tab
358      * @param icon the icon to be displayed in this tab
359      * @param component The component to be displayed when this tab is clicked.
360      * @param tip the tooltip to be displayed for this tab
361      * @param index the position to insert this new tab
362      * @see #addTab
363      * @see #removeTabAt
364      */

365     public void insertTab(String JavaDoc title, SIcon icon,
366                           SComponent component, String JavaDoc tip,
367                           int index) {
368
369         SIcon disabledIcon = null;
370
371         if (icon != null && icon instanceof SImageIcon) {
372             disabledIcon = new SImageIcon(new ImageIcon(GrayFilter.createDisabledImage(((SImageIcon) icon).getImage())));
373         }
374
375         Page p = new Page(title, icon, disabledIcon, component, tip);
376         pages.add(index, p);
377
378         contents.addComponent(p.component, p.component.getName());
379
380         if (pages.size() == 1) {
381             setSelectedIndex(0);
382         }
383     }
384
385     /**
386      * Adds a <i>component</i> and <i>tip</i> represented by a <i>title</i>
387      * and/or <i>icon</i>, either of which can be null.
388      * Cover method for insertTab().
389      *
390      * @param title the title to be displayed in this tab
391      * @param icon the icon to be displayed in this tab
392      * @param component The component to be displayed when this tab is clicked.
393      * @param tip the tooltip to be displayed for this tab
394      * @see #insertTab
395      * @see #removeTabAt
396      */

397     public void addTab(String JavaDoc title, SIcon icon, SComponent component, String JavaDoc tip) {
398         insertTab(title, icon, component, tip, pages.size());
399     }
400
401     /**
402      * Adds a <i>component</i> represented by a <i>title</i> and/or <i>icon</i>,
403      * either of which can be null.
404      * Cover method for insertTab().
405      *
406      * @param title the title to be displayed in this tab
407      * @param icon the icon to be displayed in this tab
408      * @param component The component to be displayed when this tab is clicked.
409      * @see #insertTab
410      * @see #removeTabAt
411      */

412     public void addTab(String JavaDoc title, SIcon icon, SComponent component) {
413         insertTab(title, icon, component, null, pages.size());
414     }
415
416     /**
417      * Adds a <i>component</i> represented by a <i>title</i> and no icon.
418      * Cover method for insertTab().
419      *
420      * @param title the title to be displayed in this tab
421      * @param component The component to be displayed when this tab is clicked.
422      * @see #insertTab
423      * @see #removeTabAt
424      */

425     public void addTab(String JavaDoc title, SComponent component) {
426         insertTab(title, null, component, null, pages.size());
427     }
428
429
430     /**
431      * Adds a <i>component</i> with the specified tab title.
432      * Cover method for insertTab().
433      *
434      * @param title the title to be displayed in this tab
435      * @param component The component to be displayed when this tab is clicked.
436      * @see #insertTab
437      * @see #removeTabAt
438      */

439     public SComponent add(String JavaDoc title, SComponent component) {
440         addTab(title, component);
441         return component;
442     }
443
444     /**
445      * Adds a <i>component</i> at the specified tab index. If constraints
446      * is a String or an Icon, it will be used for the tab title,
447      * otherwise the component's name will be used as the tab title.
448      * Cover method for insertTab().
449      *
450      * @param component The component to be displayed when this tab is clicked.
451      * @param constraints the object to be displayed in the tab
452      * @see #insertTab
453      * @see #removeTabAt
454      */

455     public SComponent addComponent(SComponent component,
456                                    Object JavaDoc constraints) {
457         return addComponent(component, constraints, pages.size());
458     }
459
460     /**
461      * Adds a <i>component</i> at the specified tab index. If constraints
462      * is a String or an Icon, it will be used for the tab title,
463      * otherwise the component's name will be used as the tab title.
464      * Cover method for insertTab().
465      *
466      * @param component The component to be displayed when this tab is clicked.
467      * @param constraints the object to be displayed in the tab
468      * @param index the position to insert this new tab
469      * @see #insertTab
470      * @see #removeTabAt
471      */

472     public SComponent addComponent(SComponent component,
473                                    Object JavaDoc constraints, int index) {
474         SIcon icon = constraints instanceof SIcon ? (SIcon) constraints : null;
475         String JavaDoc title = constraints instanceof String JavaDoc ? (String JavaDoc) constraints : null;
476         insertTab(title, icon, component, null, Math.min(index, pages.size()));
477
478         return component;
479     }
480
481     /**
482      * Removes the tab at <i>index</i>.
483      * After the component associated with <i>index</i> is removed,
484      * its visibility is reset to true to ensure it will be visible
485      * if added to other containers.
486      *
487      * @param index the index of the tab to be removed
488      * @see #addTab
489      * @see #insertTab
490      */

491     public void removeTabAt(int index) {
492         // If we are removing the currently selected tab AND
493
// it happens to be the last tab in the bunch, then
494
// select the previous tab, except it is the last one.
495
// TODO: how is a tabbedPane with no tabs rendered?
496
int newTabCount = getTabCount() - 1;
497         int selected = getSelectedIndex();
498         removePageAt(index);
499         if (newTabCount > 0) {
500             if (selected >= (newTabCount)) {
501                 /* last tab was selected and maybe removed, so try to find a
502                  * tab to select before
503                  */

504                 int decrement = 1;
505
506                 while (newTabCount > decrement && !isEnabledAt(newTabCount - decrement)) {
507                     decrement++;
508                 }
509                 if (isEnabledAt(newTabCount - decrement)) {
510                     setSelectedIndex(newTabCount - decrement);
511                 } else {
512                     // only disabled tabs left
513
setSelectedIndex(-1);
514                 }
515             } else {
516                 int newTab = selected;
517                 /* some tab was selected and maybe removed, so try to find a
518                  * tab to select behind or before the removed one
519                  */

520                 while ((newTabCount - 1 > newTab) && !isEnabledAt(newTab)) {
521                     newTab++;
522                 }
523                 if (isEnabledAt(newTab)) {
524                     setSelectedIndex(newTab);
525                     getSelectedComponent().setVisible(true);
526                 } else {
527                     // see if there is an enabled tab before
528
newTab = selected - 1;
529                     if (newTab == -1) {
530                         setSelectedIndex(-1);
531                         return;
532                     }
533                     while (newTab > 0 && !isEnabledAt(newTab)) {
534                         newTab--;
535                     }
536                     if (isEnabledAt(newTab)) {
537                         setSelectedIndex(newTab);
538                         getSelectedComponent().setVisible(true);
539                     } else {
540                         // only disabled tabs left
541
setSelectedIndex(-1);
542                     }
543                 }
544
545             }
546         } else {
547             // no tab left
548
setSelectedIndex(-1);
549         }
550     }
551
552     /**
553      * Removes the tab which corresponds to the specified component.
554      *
555      * @param component the component to remove from the tabbedpane
556      * @see #addTab
557      * @see #removeTabAt
558      */

559     public void remove(SComponent component) {
560         int index = indexOfComponent(component);
561         if (index != -1) {
562             removeTabAt(index);
563         }
564     }
565
566     /**
567      * Sets the maximum tabs per line. tabs <= 0: No maximum.
568      */

569     public void setMaxTabsPerLine(int tabs) {
570         maxTabsPerLine = tabs;
571     }
572
573     /**
574      * Returns the maximum tabs per line.
575      */

576     public int getMaxTabsPerLine() {
577         return maxTabsPerLine;
578     }
579
580     /**
581      * Returns the tab title at <i>index</i>.
582      *
583      * @see #setTitleAt
584      */

585     public String JavaDoc getTitleAt(int index) {
586         return ((Page) pages.get(index)).title;
587     }
588
589     /**
590      * Returns the tab icon at <i>index</i>.
591      *
592      * @see #setIconAt
593      */

594     public SIcon getIconAt(int index) {
595         return ((Page) pages.get(index)).icon;
596     }
597
598     /**
599      * Returns the tab disabled icon at <i>index</i>.
600      *
601      * @see #setDisabledIconAt
602      */

603     public SIcon getDisabledIconAt(int index) {
604         return ((Page) pages.get(index)).disabledIcon;
605     }
606
607     /**
608      * Returns the tab background color at <i>index</i>.
609      *
610      * @see #setBackgroundAt
611      */

612     public Color getBackgroundAt(int index) {
613         return ((Page) pages.get(index)).background;
614     }
615
616     /**
617      * Returns the tab foreground color at <i>index</i>.
618      *
619      * @see #setForegroundAt
620      */

621     public Color getForegroundAt(int index) {
622         return ((Page) pages.get(index)).foreground;
623     }
624
625     /**
626      * Returns the tab style at <i>index</i>.
627      *
628      * @see #setStyleAt
629      */

630     public String JavaDoc getStyleAt(int index) {
631         return ((Page) pages.get(index)).style;
632     }
633
634     /**
635      * Returns whether or not the tab at <i>index</i> is
636      * currently enabled.
637      *
638      * @see #setEnabledAt
639      */

640     public boolean isEnabledAt(int index) {
641         return ((Page) pages.get(index)).enabled;
642     }
643
644     /**
645      * Sets the title at <i>index</i> to <i>title</i> which can be null.
646      * An internal exception is raised if there is no tab at that index.
647      *
648      * @param index the tab index where the title should be set
649      * @param title the title to be displayed in the tab
650      * @see #getTitleAt
651      */

652     public void setTitleAt(int index, String JavaDoc title) {
653         ((Page) pages.get(index)).title = title;
654     }
655
656     /**
657      * Sets the icon at <i>index</i> to <i>icon</i> which can be null.
658      * An internal exception is raised if there is no tab at that index.
659      *
660      * @param index the tab index where the icon should be set
661      * @param icon the icon to be displayed in the tab
662      * @see #getIconAt
663      */

664     public void setIconAt(int index, SIcon icon) {
665         ((Page) pages.get(index)).icon = icon;
666     }
667
668     /**
669      * Sets the disabled icon at <i>index</i> to <i>icon</i> which can be null.
670      * An internal exception is raised if there is no tab at that index.
671      *
672      * @param index the tab index where the disabled icon should be set
673      * @param disabledIcon the icon to be displayed in the tab when disabled
674      * @see #getDisabledIconAt
675      */

676     public void setDisabledIconAt(int index, SIcon disabledIcon) {
677         ((Page) pages.get(index)).disabledIcon = disabledIcon;
678     }
679
680     /**
681      * Sets the background color at <i>index</i> to <i>background</i>
682      * which can be null, in which case the tab's background color
683      * will default to the background color of the tabbedpane.
684      * An internal exception is raised if there is no tab at that index.
685      *
686      * @param index the tab index where the background should be set
687      * @param background the color to be displayed in the tab's background
688      * @see #getBackgroundAt
689      */

690     public void setBackgroundAt(int index, Color background) {
691         ((Page) pages.get(index)).background = background;
692     }
693
694     /**
695      * Sets the foreground color at <i>index</i> to <i>foreground</i>
696      * which can be null, in which case the tab's foreground color
697      * will default to the foreground color of this tabbedpane.
698      * An internal exception is raised if there is no tab at that index.
699      *
700      * @param index the tab index where the foreground should be set
701      * @param foreground the color to be displayed as the tab's foreground
702      * @see #getForegroundAt
703      */

704     public void setForegroundAt(int index, Color foreground) {
705         ((Page) pages.get(index)).foreground = foreground;
706     }
707
708     /**
709      * Sets the style at <i>index</i> to <i>style</i>
710      * which can be null, in which case the tab's style
711      * will default to the style of this tabbedpane.
712      * An internal exception is raised if there is no tab at that index.
713      *
714      * @param index the tab index where the style should be set
715      * @param style the style to be used as the tab's style
716      * @see #getStyleAt
717      */

718     public void setStyleAt(int index, String JavaDoc style) {
719         ((Page) pages.get(index)).style = style;
720     }
721
722     /**
723      * Sets whether or not the tab at <i>index</i> is enabled.
724      * An internal exception is raised if there is no tab at that index.
725      *
726      * @param index the tab index which should be enabled/disabled
727      * @param enabled whether or not the tab should be enabled
728      * @see #isEnabledAt
729      */

730     public void setEnabledAt(int index, boolean enabled) {
731         ((Page) pages.get(index)).enabled = enabled;
732     }
733
734     /**
735      * Set the tooltip text for tab at <i>index</i>
736      *
737      * @param index set the tooltip for this tab
738      */

739     public void setToolTipTextAt(int index, String JavaDoc toolTip) {
740         ((Page) pages.get(index)).toolTip = toolTip;
741     }
742
743     /**
744      * Get the tooltip text from tab at <i>index</i>
745      *
746      * @return the text or <i>null</i> if not set.
747      */

748     public String JavaDoc getToolTipTextAt(int index) {
749         return ((Page) pages.get(index)).toolTip;
750     }
751
752     /**
753      * Sets the component at <i>index</i> to <i>component</i>.
754      * An internal exception is raised if there is no tab at that index.
755      *
756      * @param index the tab index where this component is being placed
757      * @param component the component for the tab
758      * @see #getComponent(int)
759      */

760     public void setComponent(int index, SComponent component) {
761         Page page = (Page) pages.get(index);
762         if (component != page.component) {
763             if (page.component != null) {
764                 contents.remove(page.component);
765             }
766             page.component = component;
767             contents.addComponent(page.component, page.component.getName());
768             if (getSelectedIndex() == index)
769                 card.show(component);
770         }
771     }
772
773     /**
774      * Returns the first tab index with a given <i>title</i>,
775      * Returns -1 if no tab has this title.
776      *
777      * @param title the title for the tab
778      */

779     public int indexOfTab(String JavaDoc title) {
780         for (int i = 0; i < getTabCount(); i++) {
781             String JavaDoc titleAt = getTitleAt(i);
782             if (title == null && titleAt == null || title != null && title.equals(titleAt))
783                 return i;
784         }
785         return -1;
786     }
787
788     /**
789      * Returns the first tab index with a given <i>icon</i>.
790      * Returns -1 if no tab has this icon.
791      *
792      * @param icon the icon for the tab
793      */

794     public int indexOfTab(SIcon icon) {
795         for (int i = 0; i < getTabCount(); i++) {
796             SIcon iconAt = getIconAt(i);
797             if (icon == null && iconAt == null || icon != null && icon.equals(iconAt))
798                 return i;
799         }
800         return -1;
801     }
802
803     private void removePageAt(int i) {
804         contents.remove(((Page) pages.get(i)).component);
805         pages.remove(i);
806     }
807
808     /**
809      * Lightweight container for tab properties.
810      */

811     private static class Page implements Serializable JavaDoc {
812         public String JavaDoc title;
813         public String JavaDoc toolTip;
814         public Color foreground;
815         public Color background;
816         public SIcon icon;
817         public SIcon disabledIcon;
818         public boolean enabled = true;
819         public String JavaDoc style;
820         public SComponent component;
821
822         public Page(String JavaDoc title, SIcon icon,
823                     SIcon disabledIcon, SComponent component, String JavaDoc tip) {
824             this.title = title;
825             this.toolTip = tip;
826             this.icon = icon;
827             this.disabledIcon = disabledIcon;
828             this.component = component;
829         }
830     }
831
832     /**
833      * Set the parent frame of this tabbed pane
834      *
835      * @param f the parent frame.
836      */

837     public void setParentFrame(SFrame f) {
838         super.setParentFrame(f);
839         contents.setParentFrame(f);
840     }
841
842     public void setCG(TabbedPaneCG cg) {
843         super.setCG(cg);
844     }
845
846     /**
847      * Tab was clicked.
848      *
849      * @see LowLevelEventListener#processLowLevelEvent(String, String[])
850      */

851     public void processLowLevelEvent(String JavaDoc action, String JavaDoc[] values) {
852         processKeyEvents(values);
853
854         for (int i = 0; i < values.length; ++i) {
855             try {
856                 int index = new Integer JavaDoc(values[i]).intValue();
857                 if (index < 0 || index >= pages.size())
858                     continue;
859
860                 /* prevent clever users from showing
861                  * disabled tabs
862                  */

863                 if (((Page) pages.get(index)).enabled) {
864                     lleChangedIndex = index;
865                     SForm.addArmedComponent(this);
866                     return;
867                 }
868             } catch (NumberFormatException JavaDoc nfe) {
869                 continue;
870             }
871         }
872     }
873
874     /**
875      * Does nothin'.
876      */

877     public void fireIntermediateEvents() {
878     }
879
880     /**
881      * Sets selection and fire changeevents, if user changed
882      * tab selection.
883      */

884     public void fireFinalEvents() {
885         requestFocus();
886         super.fireFinalEvents();
887         if (lleChangedIndex > -1)
888             setSelectedIndex(lleChangedIndex);
889         lleChangedIndex = -1;
890     }
891
892     /**
893      * @see LowLevelEventListener#isEpochCheckEnabled()
894      */

895     public boolean isEpochCheckEnabled() {
896         return epochCheckEnabled;
897     }
898
899     /**
900      * @see LowLevelEventListener#isEpochCheckEnabled()
901      */

902     public void setEpochCheckEnabled(boolean epochCheckEnabled) {
903         this.epochCheckEnabled = epochCheckEnabled;
904     }
905
906     /**
907      * When tab selection changed.
908      *
909      * @see ChangeListener#stateChanged(ChangeEvent)
910      */

911     public void stateChanged(ChangeEvent JavaDoc ce) {
912         final int index = model.getSelectedIndex();
913         if (index >= pages.size() || index == -1) return;
914         card.show(((Page) pages.get(index)).component);
915
916         reload();
917         fireStateChanged();
918     }
919
920     public void removeAllTabs() {
921         while (getTabCount() != 0) {
922             removeTabAt(0);
923         }
924     }
925
926 }
927
928
929
Popular Tags