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; Font boldFont; FontMetrics fmBoldFont; 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; 31 int W; 32 int H; 33 34 Component cards[] = new Component[MAX_TABS]; 35 String arrName[]=new String [MAX_TABS]; 36 int arrEnd[]=new int[MAX_TABS]; int arrBeg[]=new int[MAX_TABS]; 39 int nbTab=0; 40 int selected=-1; 41 42 final static int BUTTON_GUTTER = 2; 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 name, boolean enabled, Component c) { 114 if (c.getParent() == tabPanel || nbTab>=arrBeg.length || c==this) 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 [] 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 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 oldName, String newName) { 170 for(int i=0;i<nbTab;i++) { 171 if(arrName[i].equals(oldName)) { 172 arrName[i]=new String (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 paint (g); } 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 |