KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > rcm > awt > TabPanel


1 package rcm.awt;
2
3 import java.awt.*;
4 import java.awt.event.*;
5
6 public class TabPanel extends Panel {
7   static final int MAX_TABS = 25;
8   static final int selUpper=2;
9   static final int lineWidth=2;
10   static final int horRound=2;
11   static final int verRound=2;
12   static final int internalMargin = 4;
13   static final int xTabOffset = 2;
14   static final int XTitle=4;
15   static final int YTitle=2;
16     
17   Font plainFont; // computed by recalculate ()
18
Font boldFont; // computed by recalculate ()
19
FontMetrics fmBoldFont; // computed by recalculate ()
20

21   final Color light=new Color(223,223,223);
22   final Color shadow=new Color(127,127,127);
23     
24   CardLayout tabLayout=new CardLayout();
25   Panel tabPanel=new Panel();
26   
27   boolean mustRecalculate = true;
28   
29   int Z; // computed by recalculate ()
30

31   int W;
32   int H;
33     
34   Component cards[] = new Component[MAX_TABS];
35   String JavaDoc arrName[]=new String JavaDoc[MAX_TABS];
36   int arrEnd[]=new int[MAX_TABS]; // computed by recalculate ()
37
int arrBeg[]=new int[MAX_TABS]; // computed by recalculate ()
38

39   int nbTab=0;
40   int selected=-1;
41
42   // Extra feature: zero or more buttons flush-right on tab line
43
final static int BUTTON_GUTTER = 2; // pixels between buttons
44

45   public TabPanel() {
46     setLayout(null);
47     tabPanel.setLayout(tabLayout);
48     add(tabPanel);
49     addMouseListener (new MouseHandler ());
50   }
51
52   void recalculate () {
53     plainFont = getFont ();
54     if (plainFont == null)
55         plainFont = new Font ("Helvetica", Font.PLAIN, 12);
56     boldFont = new Font (plainFont.getFamily(), Font.BOLD, plainFont.getSize());
57     fmBoldFont = getFontMetrics (boldFont);
58     
59     Z = fmBoldFont.getHeight()+2*lineWidth+2*YTitle+1;
60
61     for (int i=0; i<nbTab; ++i) {
62         arrBeg[i]=(i==0) ? xTabOffset : arrEnd[i-1];
63         arrEnd[i]=arrBeg[i]+2*XTitle+fmBoldFont.stringWidth(arrName[i])+2*lineWidth;
64         
65     }
66
67     if (selected >= 0) {
68         arrBeg[selected] -= lineWidth;
69         arrEnd[selected] += lineWidth;
70     }
71     
72     mustRecalculate = false;
73   }
74   
75   public void layout () {
76     if (mustRecalculate)
77         recalculate ();
78     Dimension external = getSize ();
79     W = external.width;
80     H = external.height;
81     
82     int x = lineWidth+internalMargin;
83     int y = Z+1+internalMargin;
84     int w = W-2*(lineWidth+internalMargin);
85     int h = H-Z-2*(lineWidth+internalMargin);
86     
87     tabPanel.setBounds (x, y, w, h);
88     tabPanel.validate ();
89
90     Component[] c = getComponents ();
91     int bx = external.width;
92     for (int i=c.length-1; i>=0; --i)
93         if (c[i] != tabPanel && c[i].isVisible()) {
94             Dimension d = c[i].getPreferredSize();
95             bx -= d.width;
96             c[i].setBounds (bx, 0, d.width, d.height);
97             bx -= BUTTON_GUTTER;
98         }
99   }
100   
101     public Dimension getPreferredSize () {
102         Dimension d = super.getPreferredSize ();
103         return new Dimension (d.width + 2*(lineWidth+internalMargin),
104                               d.height + Z + 2*(lineWidth+internalMargin));
105     }
106
107     public Dimension getMinimumSize () {
108         Dimension d = super.getMinimumSize ();
109         return new Dimension (d.width + 2*(lineWidth+internalMargin),
110                               d.height + Z + 2*(lineWidth+internalMargin));
111     }
112
113   public void addTabPanel(String JavaDoc name, boolean enabled, Component c) {
114     if (c.getParent() == tabPanel // panel already added
115
|| nbTab>=arrBeg.length // too many tabs
116
|| c==this) // can't add self
117
return;
118
119     cards[nbTab] = c;
120     arrName[nbTab]=name;
121     tabPanel.add(String.valueOf (nbTab), c);
122     nbTab++;
123
124     if (selected < 0)
125         select (0);
126
127     mustRecalculate = true;
128     repaint ();
129   }
130   
131   public String JavaDoc[] getPanelLabels () {
132     return arrName;
133   }
134
135   public void removeAllTabPanels () {
136     for (int i=nbTab-1; i>=0; --i)
137         removeTabPanel (i);
138   }
139   
140   public void removeTabPanel(Component c) {
141     //finding the tab
142
for(int i=0;i<cards.length;i++) {
143       if(cards[i]==c) {
144         removeTabPanel (i);
145         break;
146       }
147     }
148   }
149         
150   public void removeTabPanel(int i) {
151     if (i<0 || i >= nbTab)
152         return;
153     tabPanel.remove(cards[i]);
154     for(int j=i;j<nbTab-1;j++) {
155       arrName[j]=arrName[j+1];
156       cards[j]=cards[j+1];
157     }
158     nbTab--;
159     if (selected == i)
160         select (Math.min (selected+1, nbTab-1));
161     mustRecalculate = true;
162     repaint ();
163   }
164   
165   public int countTabs () {
166     return nbTab;
167   }
168
169   public void renameTab(String JavaDoc oldName, String JavaDoc newName) {
170     for(int i=0;i<nbTab;i++) {
171       if(arrName[i].equals(oldName)) {
172         arrName[i]=new String JavaDoc(newName);
173         mustRecalculate = true;
174         repaint ();
175         break;
176       }
177     }
178   }
179
180   public void select (int num) {
181     if(num<0||num>nbTab||num==selected)
182         return;
183     selected=num;
184     tabLayout.show(tabPanel,Integer.toString(selected));
185     mustRecalculate = true;
186     repaint ();
187   }
188
189   public Component getSelectedComponent () {
190       if (selected < 0 || selected >= nbTab)
191           return null;
192       else
193           return cards[selected];
194   }
195
196   public synchronized void update (Graphics g) {
197     // avoid clearing background
198
paint (g); // FIX: what happens if a component leaves garbage behind?
199
}
200   
201   public synchronized void paint (Graphics g){
202     if (mustRecalculate || getFont() != plainFont)
203         recalculate ();
204     
205     Dimension d = getSize ();
206     g.setColor(getBackground());
207     g.fillRect(0,0,W,Z+1);
208          
209     for (int curr=0;curr<nbTab;curr++) {
210       int upper=(curr==selected) ? 0 : selUpper;
211       g.setFont((curr==selected) ? boldFont : plainFont);
212       
213       g.setColor(shadow);
214       for (int i=lineWidth;curr!=(selected-1) && i>0;i--) {
215         if(i==1) g.setColor(Color.black);
216         g.drawLine(arrEnd[curr]-i,upper+verRound,arrEnd[curr]-i,Z-lineWidth);
217         if(i==1) g.drawLine(arrEnd[curr]-lineWidth,upper+1,arrEnd[curr]-lineWidth,upper+1);
218       }
219
220       g.setColor(Color.black);
221       g.drawString(arrName[curr],
222                    arrBeg[curr]+(curr==selected ? 2*lineWidth : lineWidth)+XTitle,
223                    upper+YTitle+lineWidth+fmBoldFont.getAscent());
224       
225       g.setColor(Color.white);
226       for (int i=0;i<lineWidth;i++) {
227         if(i==1) g.setColor(light);
228         g.drawLine(arrBeg[curr]+horRound,upper+i,arrEnd[curr]-lineWidth-horRound+1,upper+i);
229         if(curr!=(selected+1)) {
230           g.drawLine(arrBeg[curr]+i,upper+verRound,arrBeg[curr]+i,Z);
231           if(i==0)g.drawLine(arrBeg[curr]+1,upper+1,arrBeg[curr]+1,upper+1);
232         }
233       }
234     }
235     
236     g.setColor(Color.white);
237     for (int i=0;i<lineWidth;i++) {
238       if(i==1) g.setColor(light);
239       g.drawLine(i,Z,i,H-1);
240       if (selected >= 0) {
241           if(selected!=0) g.drawLine(0,Z-lineWidth+i+1,arrBeg[selected],Z-lineWidth+i+1);
242           g.drawLine(arrEnd[selected],Z-lineWidth+i+1,W-1,Z-lineWidth+i+1);
243       }
244       else {
245           g.drawLine(0,Z-lineWidth+i+1,W-1,Z-lineWidth+i+1);
246       }
247     }
248     
249     g.setColor(shadow);
250     for (int i=lineWidth;i>0;i--) {
251       if(i==1) g.setColor(Color.black);
252       g.drawLine(0,H-i,W,H-i);
253       g.drawLine(W-i,Z,W-i,H-1);
254     }
255     
256   }
257
258     void clickTab (int x, int y) {
259       for (int i=0;i<nbTab;i++)
260         if (x>arrBeg[i] && x<arrEnd[i])
261             select (i);
262     }
263     
264     class MouseHandler extends MouseAdapter {
265         public void mousePressed (MouseEvent event) {
266             if(event.getY () < Z)
267                 clickTab (event.getX (), event.getY ());
268         }
269     }
270
271 }
272
Popular Tags