KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sshtools > ui > awt > TabbedPanel


1 package com.sshtools.ui.awt;
2
3 import java.util.Enumeration JavaDoc;
4 import java.util.Hashtable JavaDoc;
5 import java.util.Vector JavaDoc;
6
7 import java.awt.BorderLayout JavaDoc;
8 import java.awt.CardLayout JavaDoc;
9 import java.awt.Color JavaDoc;
10 import java.awt.Component JavaDoc;
11 import java.awt.Container JavaDoc;
12 import java.awt.Dimension JavaDoc;
13 import java.awt.FontMetrics JavaDoc;
14 import java.awt.Frame JavaDoc;
15 import java.awt.Graphics JavaDoc;
16 import java.awt.Image JavaDoc;
17 import java.awt.Insets JavaDoc;
18 import java.awt.Label JavaDoc;
19 import java.awt.Panel JavaDoc;
20 import java.awt.Point JavaDoc;
21 import java.awt.Rectangle JavaDoc;
22 import java.awt.event.ActionEvent JavaDoc;
23 import java.awt.event.ActionListener JavaDoc;
24 import java.awt.event.MouseAdapter JavaDoc;
25 import java.awt.event.MouseEvent JavaDoc;
26 import java.awt.event.WindowAdapter JavaDoc;
27 import java.awt.event.WindowEvent JavaDoc;
28
29 /**
30  * <p>
31  * AWT component to provide a tabbed pane similar to Swings JTabbedPane (albeit somewhat simpler!).
32  * </p>
33  *
34  * <p>
35  * Each component added except the first will be invisible until the user clicks on the tab heading either above, below. to the
36  * left, or to the right of the visible component. Clicking on the heading will hide the current tab and make the new selection
37  * visible.
38  * </p>
39  *
40  * @author $Author: lee $
41  */

42
43 public class TabbedPanel
44     extends Container JavaDoc {
45
46   /**
47    * Tabs are placed above the components
48    */

49   public final static int TOP = 0;
50
51   /**
52    * Tabs are placed to the left of the components
53    */

54   public final static int LEFT = 1;
55
56   /**
57    * Tabs are placed below the components
58    */

59   public final static int BOTTOM = 2;
60
61   /**
62    * Tabs are placed to the right of the components
63    */

64   public final static int RIGHT = 3;
65
66   //
67
private final static Insets JavaDoc DEFAULT_INSETS = new Insets JavaDoc(2, 2, 2, 2);
68   private final static int HORIZONTAL_GAP = 3;
69   private final static int VERTICAL_GAP = 3;
70   private final static int IMAGE_TEXT_GAP = 2;
71
72   // Private instance variables
73
private int position;
74   private FontMetrics JavaDoc metrics;
75   private Hashtable JavaDoc tabs;
76   private int sel;
77   private TabbedLayout layout;
78   private Vector JavaDoc listenerList;
79
80   /**
81    * <p>
82    * Create a tabbed panel with the tabs at the specified position. Can be one of :-
83    * </p>
84    * <ul>
85    * <li>TabbedPanel.TOP</li>
86    * <li>TabbedPanel.LEFT</li>
87    * <li>TabbedPanel.BOTTOM</li>
88    * <li>TabbedPanel.RIGHT</li>
89    * </ul>
90    *
91    * <p>
92    * <b><font color="#ff0000">Note, only <i>TOP</i> is currently supported</font></b>
93    * </p>
94    *
95    * @param position position
96    */

97   public TabbedPanel(int position) {
98     super();
99
100     tabs = new Hashtable JavaDoc();
101     listenerList = new Vector JavaDoc();
102     sel = -1;
103
104     setLayout(layout = new TabbedLayout(3, 3));
105     setPosition(position);
106
107     addMouseListener(new MouseAdapter JavaDoc() {
108       public void mouseClicked(MouseEvent JavaDoc evt) {
109         for (Enumeration JavaDoc e = tabs.elements(); e.hasMoreElements(); ) {
110           TabWrapper w = (TabWrapper) e.nextElement();
111           if (w.bounds != null && w.bounds.contains(evt.getX(), evt.getY())) {
112             int idx = indexOfTab(w);
113             if (idx != sel) {
114               setSelectedTab(idx);
115             }
116             break;
117           }
118         }
119
120       }
121     });
122
123     // enableEvents(AWTEvent.MOUSE_EVENT_MASK);
124
}
125
126   /**
127    * Add an <code>ActionListener</code> to be informed when the user selects
128    * a tab.
129    *
130    * @param l listener to add
131    */

132   public void addActionListener(ActionListener JavaDoc l) {
133     listenerList.addElement(l);
134   }
135
136   /**
137    * Remove an <code>ActionListener</code> so as to no longer be informed when
138    * the user selects a tab.
139    *
140    * @param l listener to remove
141    */

142   public void removeActionListener(ActionListener JavaDoc l) {
143     listenerList.removeElement(l);
144   }
145
146   /**
147    * Set the title of a tab at the given index
148    *
149    * @param i index of tab
150    * @param title new tab title
151    */

152   public void setTitleAt(int i, String JavaDoc title) {
153     Component JavaDoc c = getComponent(sel);
154     TabWrapper t = (TabWrapper) tabs.get(c);
155     t.text = title;
156     repaint();
157   }
158
159   /**
160    * Set the selected tab given its index.
161    *
162    * @param idx index of tab to select
163    */

164   public void setSelectedTab(int idx) {
165     sel = idx;
166     if (sel != -1) {
167       int s = listenerList.size();
168       ActionEvent JavaDoc aevt = null;
169       for (int i = s - 1; i >= 0; i--) {
170         if (aevt == null) {
171           aevt = new ActionEvent JavaDoc(TabbedPanel.this, ActionEvent.ACTION_PERFORMED,
172                                  ""); //$NON-NLS-1$
173
}
174         ( (ActionListener JavaDoc) listenerList.elementAt(i)).actionPerformed(aevt);
175       }
176       Component JavaDoc c = getComponent(sel);
177       TabWrapper t = (TabWrapper) tabs.get(c);
178       if(t != null) {
179           layout.show(this, (String JavaDoc) t.name);
180       }
181       repaint();
182     }
183   }
184
185   /**
186    * Get the index of the currently selected tab
187    *
188    * @return selected tab index
189    */

190   public int getSelectedTab() {
191     return sel;
192   }
193
194   /**
195    * <p>
196    * Create a tabbed panel with the tabs at the specified position. Can be one of :-
197    * </p>
198    * <ul>
199    * <li>TabbedPanel.TOP</li>
200    * <li>TabbedPanel.LEFT</li>
201    * <li>TabbedPanel.BOTTOM</li>
202    * <li>TabbedPanel.RIGHT</li>
203    * </ul>
204    *
205    * <p>
206    * <b><font color="#ff0000">Note, only <i>TOP</i> is currently supported</font></b>
207    * </p>
208    *
209    * @param position position
210    */

211   public void setPosition(int position) {
212     doLayout();
213     repaint();
214   }
215
216   public void remove(int idx) {
217     Component JavaDoc c = getComponent(idx);
218     TabWrapper t = (TabWrapper) tabs.get(c);
219     tabs.remove(c);
220     if (sel == idx) {
221       setSelectedTab(tabs.size() - 1);
222     }
223     super.remove(idx);
224   }
225
226   /**
227    * Add a tab.
228    *
229    * @param comp component
230    * @param constraints tab name
231    * @param index tab index
232    * @param image tab image
233    */

234   public void add(Component JavaDoc comp, Object JavaDoc constraints, int index, Image JavaDoc image) {
235     TabWrapper w = new TabWrapper(comp.getName(), String.valueOf(constraints),
236                                   image, comp, constraints);
237     tabs.put(comp, w);
238     super.addImpl(comp, comp.getName(), index);
239     if (sel == -1) {
240       setSelectedTab(0);
241     }
242     else {
243       repaint();
244     }
245   }
246
247   public int getPosition() {
248     return position;
249   }
250
251   public void removeNotify() {
252     super.removeNotify();
253     if (getComponentCount() == 0) {
254       sel = -1;
255     }
256   }
257
258   protected void addImpl(Component JavaDoc comp, Object JavaDoc constraints, int index) {
259     add(comp, constraints, index, null);
260   }
261
262   public void add(Component JavaDoc comp, Object JavaDoc constraints, Image JavaDoc image) {
263     add(comp, constraints, -1, image);
264   }
265
266   public Insets JavaDoc getInsets() {
267     return DEFAULT_INSETS;
268   }
269
270   public void addNotify() {
271     super.addNotify();
272     metrics = getFontMetrics(getFont());
273   }
274
275   public void paint(Graphics JavaDoc g) {
276     super.paint(g);
277
278     Dimension JavaDoc s = getSize();
279     Rectangle JavaDoc r = getHeadingBounds();
280     int ncomponents = getComponentCount();
281     int sel = getSelectedTab();
282
283     // Work out the colors for the border
284
Color JavaDoc c = getBackground();
285     Color JavaDoc midlight = c.brighter();
286     Color JavaDoc highlight = midlight.brighter();
287     Color JavaDoc lowlight = c.darker();
288     Color JavaDoc shadow = lowlight.darker();
289     Color JavaDoc darkShadow = shadow.darker();
290
291     //
292
switch (position) {
293       case TOP:
294
295         //
296
g.setColor(darkShadow);
297         g.drawLine(0, s.height - 1, s.width - 1, s.height - 1);
298         g.drawLine(s.width - 1, s.height - 1, s.width - 1, r.height - 1);
299         //
300
g.setColor(shadow);
301         g.drawLine(1, s.height - 2, s.width - 2, s.height - 2);
302         g.drawLine(s.width - 2, s.height - 2, s.width - 2, r.height);
303         //
304
g.setColor(highlight);
305         g.drawLine(0, s.height - 2, 0, r.height);
306
307         // Paint the tabs
308
int x = 0;
309         int selx = -1;
310
311         for (int i = 0; i < ncomponents; i++) {
312           Component JavaDoc comp = getComponent(i);
313           TabWrapper tab = (TabWrapper) tabs.get(comp);
314
315           if (tab != null) {
316
317             int hw = metrics.stringWidth(tab.text) + (HORIZONTAL_GAP * 2);
318             tab.bounds = new Rectangle JavaDoc(x, 0, hw, r.height);
319
320             if (sel == i) {
321               selx = x;
322               // g.setColor(darkShadow);
323
}
324             else {
325               g.setColor(lowlight);
326               g.fillRect(x, 3, hw - 1, r.height - 4);
327
328               //
329
g.setColor(midlight);
330               g.drawLine(x, 3, x, r.height - 2);
331               g.drawLine(x + 1, 2, x + hw - 2, 2);
332               //
333
g.setColor(darkShadow);
334               g.drawLine(x + hw - 1, 3, x + hw - 1, r.height - 2);
335               //
336
g.setColor(shadow);
337               g.drawLine(x + hw - 2, 4, x + hw - 2, r.height - 2);
338               //
339
g.setColor(highlight);
340               g.drawLine(x, r.height - 1, x + hw - 1, r.height - 1);
341
342               g.setColor(getForeground());
343               g.drawString(tab.text, x + HORIZONTAL_GAP,
344                            (r.height / 2) + (metrics.getHeight() / 2) - 1);
345               // g.setColor(darkShadow);
346
}
347
348             x += hw;
349           }
350
351         }
352         g.setColor(highlight);
353         g.drawLine(x, r.height - 1, s.width - 2, r.height - 1);
354
355         if (selx != -1) {
356           x = selx;
357           Component JavaDoc comp = getComponent(sel);
358           TabWrapper tab = (TabWrapper) tabs.get(comp);
359
360           int hw = metrics.stringWidth(tab.text) + (HORIZONTAL_GAP * 2);
361
362           // g.setColor(getBackground());
363
// g.fillRect(x, 3, hw - 1, r.height - 3);
364

365           //
366
g.setColor(highlight);
367           g.drawLine(x, 1, x, r.height - 2);
368           g.drawLine(x + 1, 0, x + hw - 1, 0);
369           //
370
g.setColor(darkShadow);
371           g.drawLine(x + hw, 1, x + hw, r.height - 2);
372           //
373
g.setColor(shadow);
374           g.drawLine(x + hw - 1, 2, x + hw - 1, r.height - 2);
375
376           g.setColor(getForeground());
377           g.drawString(tab.text, x + HORIZONTAL_GAP,
378                        (r.height / 2) + (metrics.getHeight() / 2) - 3);
379         }
380         break;
381     }
382   }
383
384   //
385
private Dimension JavaDoc getHeadingSize() {
386     Dimension JavaDoc s = new Dimension JavaDoc();
387     int c = getComponentCount();
388     for (int i = 0; i < c; i++) {
389       Component JavaDoc comp = getComponent(i);
390       TabWrapper tab = (TabWrapper) tabs.get(comp);
391       if (tab != null) {
392         int thw =
393             (HORIZONTAL_GAP * 2)
394             +
395             (metrics != null ?
396              metrics.stringWidth(tab.text == null ? "" : tab.text) : 0) //$NON-NLS-1$
397
+ (tab.image == null ? 0 : (IMAGE_TEXT_GAP + tab.image.getWidth(this)));
398         int thh = (VERTICAL_GAP * 2) +
399             Math.max(metrics != null ? metrics.getHeight() : 0,
400                      tab.image == null ? 0 : tab.image.getHeight(this));
401         if (position == TOP || position == BOTTOM) {
402           s.width += thw;
403           s.height = Math.max(s.height, thh);
404         }
405         else {
406           s.height += thh;
407           s.width = Math.max(s.width, thw);
408         }
409       }
410       else {
411         /*DEBUG*/System.err.println(Messages.getString("TabbedPanel.tabWrapperCouldNotBeFound") + i + " [" + comp + //$NON-NLS-1$ //$NON-NLS-2$
412
" could not be found"); //$NON-NLS-1$
413
}
414     }
415     return s;
416
417   }
418
419   /*
420    * Get the bounds of the tab headings
421    */

422   private Rectangle JavaDoc getHeadingBounds() {
423     Dimension JavaDoc s = getHeadingSize();
424     Point JavaDoc loc = new Point JavaDoc();
425     switch (position) {
426       case BOTTOM:
427         loc.y = getSize().height - s.height;
428         break;
429       case RIGHT:
430         loc.x = getSize().width - s.width;
431         break;
432     }
433     return new Rectangle JavaDoc(loc.x, loc.y, s.width, s.height);
434   }
435
436   private int indexOfTab(TabWrapper tab) {
437     int c = getComponentCount();
438     for (int i = 0; i < c; i++) {
439       if (tab.component == getComponent(i)) {
440         return i;
441       }
442     }
443     return -1;
444   }
445
446   // Debug
447
public static void main(String JavaDoc[] args) {
448     Frame JavaDoc frame = new Frame JavaDoc("Tabs"); //$NON-NLS-1$
449
frame.setLayout(new BorderLayout JavaDoc());
450
451     Label JavaDoc l1 = new Label JavaDoc("Test label 1"); //$NON-NLS-1$
452
Panel JavaDoc p1 = new Panel JavaDoc(new BorderLayout JavaDoc());
453     p1.add(l1, BorderLayout.CENTER);
454
455     Label JavaDoc l2 = new Label JavaDoc("Test label 2"); //$NON-NLS-1$
456
Panel JavaDoc p2 = new Panel JavaDoc(new BorderLayout JavaDoc());
457     p2.add(l2, BorderLayout.CENTER);
458
459     Label JavaDoc l3 = new Label JavaDoc("Test label 3"); //$NON-NLS-1$
460
Panel JavaDoc p3 = new Panel JavaDoc(new BorderLayout JavaDoc());
461     p3.add(l3, BorderLayout.CENTER);
462
463     Label JavaDoc l4 = new Label JavaDoc("Test label 4"); //$NON-NLS-1$
464
Panel JavaDoc p4 = new Panel JavaDoc(new BorderLayout JavaDoc());
465     p4.add(l4, BorderLayout.CENTER);
466
467     TabbedPanel tabs = new TabbedPanel(TabbedPanel.TOP);
468     tabs.add("Test Tab 1", p1); //$NON-NLS-1$
469
tabs.add(Messages.getString("TabbedPanel.11"), p2); //$NON-NLS-1$
470
tabs.add(Messages.getString("TabbedPanel.12"), p3); //$NON-NLS-1$
471
tabs.add(Messages.getString("TabbedPanel.13"), p4); //$NON-NLS-1$
472

473     tabs.setSelectedTab(1);
474
475     frame.add(tabs, BorderLayout.CENTER);
476     frame.pack();
477     frame.addWindowListener(new WindowAdapter JavaDoc() {
478       public void windowClosing(WindowEvent JavaDoc evt) {
479         System.exit(0);
480       }
481
482     });
483     frame.setVisible(true);
484   }
485
486   // Supporting classes
487

488   class TabWrapper {
489     Component JavaDoc component;
490     String JavaDoc text;
491     Image JavaDoc image;
492     Rectangle JavaDoc bounds;
493     Object JavaDoc constraints;
494     String JavaDoc name;
495
496     TabWrapper(String JavaDoc name, String JavaDoc text, Image JavaDoc image, Component JavaDoc component,
497                Object JavaDoc contraints) {
498       this.name = name;
499       this.text = text;
500       this.image = image;
501       this.component = component;
502       this.constraints = contraints;
503     }
504   }
505
506   class TabbedLayout
507       extends CardLayout JavaDoc {
508     TabbedLayout(int hgap, int vgap) {
509       super(hgap, vgap);
510     }
511
512     public void layoutContainer(Container JavaDoc parent) {
513       synchronized (parent.getTreeLock()) {
514         Insets JavaDoc insets = parent.getInsets();
515         int ncomponents = parent.getComponentCount();
516         Component JavaDoc comp = null;
517         boolean currentFound = false;
518         Dimension JavaDoc s = getHeadingSize();
519         int headingSize = position == TOP || position == BOTTOM ? s.height :
520             s.width;
521         insets =
522             new Insets JavaDoc(
523             insets.top + (position == TOP ? headingSize : 0),
524             insets.left + (position == LEFT ? headingSize : 0),
525             insets.bottom + (position == BOTTOM ? headingSize : 0),
526             insets.right + (position == BOTTOM ? headingSize : 0));
527         for (int i = 0; i < ncomponents; i++) {
528           comp = parent.getComponent(i);
529           comp.setBounds(
530               getHgap() + insets.left,
531               getVgap() + insets.top,
532               parent.getSize().width -
533               (getHgap() * 2 + insets.left + insets.right),
534               parent.getSize().height -
535               (getVgap() * 2 + insets.top + insets.bottom));
536           if (comp.isVisible()) {
537             currentFound = true;
538           }
539         }
540
541         if (!currentFound && ncomponents > 0) {
542           parent.getComponent(0).setVisible(true);
543         }
544       }
545     }
546
547     /*
548      * (non-Javadoc)
549      *
550      * @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container)
551      */

552     public Dimension JavaDoc minimumLayoutSize(Container JavaDoc parent) {
553       Dimension JavaDoc s = super.maximumLayoutSize(parent);
554       Dimension JavaDoc c = getHeadingSize();
555       return position == TOP
556           || position == BOTTOM
557           ? new Dimension JavaDoc(Math.max(s.width, c.width), s.height + c.height)
558           : new Dimension JavaDoc(s.width + c.width, Math.max(s.height, c.height));
559     }
560
561     /*
562      * (non-Javadoc)
563      *
564      * @see java.awt.LayoutManager#preferredLayoutSize(java.awt.Container)
565      */

566     public Dimension JavaDoc preferredLayoutSize(Container JavaDoc parent) {
567       Dimension JavaDoc s = super.preferredLayoutSize(parent);
568       Dimension JavaDoc c = getHeadingSize();
569       return position == TOP
570           || position == BOTTOM
571           ? new Dimension JavaDoc(Math.max(s.width, c.width), s.height + c.height)
572           : new Dimension JavaDoc(s.width + c.width, Math.max(s.height, c.height));
573     }
574   }
575
576   /**
577    * @return
578    */

579   public int getSelectedTabIndex() {
580     return sel;
581   }
582
583 }
584
Popular Tags