1 package com.sshtools.ui.awt; 2 3 import java.util.Enumeration ; 4 import java.util.Hashtable ; 5 import java.util.Vector ; 6 7 import java.awt.BorderLayout ; 8 import java.awt.CardLayout ; 9 import java.awt.Color ; 10 import java.awt.Component ; 11 import java.awt.Container ; 12 import java.awt.Dimension ; 13 import java.awt.FontMetrics ; 14 import java.awt.Frame ; 15 import java.awt.Graphics ; 16 import java.awt.Image ; 17 import java.awt.Insets ; 18 import java.awt.Label ; 19 import java.awt.Panel ; 20 import java.awt.Point ; 21 import java.awt.Rectangle ; 22 import java.awt.event.ActionEvent ; 23 import java.awt.event.ActionListener ; 24 import java.awt.event.MouseAdapter ; 25 import java.awt.event.MouseEvent ; 26 import java.awt.event.WindowAdapter ; 27 import java.awt.event.WindowEvent ; 28 29 42 43 public class TabbedPanel 44 extends Container { 45 46 49 public final static int TOP = 0; 50 51 54 public final static int LEFT = 1; 55 56 59 public final static int BOTTOM = 2; 60 61 64 public final static int RIGHT = 3; 65 66 private final static Insets DEFAULT_INSETS = new Insets (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 int position; 74 private FontMetrics metrics; 75 private Hashtable tabs; 76 private int sel; 77 private TabbedLayout layout; 78 private Vector listenerList; 79 80 97 public TabbedPanel(int position) { 98 super(); 99 100 tabs = new Hashtable (); 101 listenerList = new Vector (); 102 sel = -1; 103 104 setLayout(layout = new TabbedLayout(3, 3)); 105 setPosition(position); 106 107 addMouseListener(new MouseAdapter () { 108 public void mouseClicked(MouseEvent evt) { 109 for (Enumeration 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 } 125 126 132 public void addActionListener(ActionListener l) { 133 listenerList.addElement(l); 134 } 135 136 142 public void removeActionListener(ActionListener l) { 143 listenerList.removeElement(l); 144 } 145 146 152 public void setTitleAt(int i, String title) { 153 Component c = getComponent(sel); 154 TabWrapper t = (TabWrapper) tabs.get(c); 155 t.text = title; 156 repaint(); 157 } 158 159 164 public void setSelectedTab(int idx) { 165 sel = idx; 166 if (sel != -1) { 167 int s = listenerList.size(); 168 ActionEvent aevt = null; 169 for (int i = s - 1; i >= 0; i--) { 170 if (aevt == null) { 171 aevt = new ActionEvent (TabbedPanel.this, ActionEvent.ACTION_PERFORMED, 172 ""); } 174 ( (ActionListener ) listenerList.elementAt(i)).actionPerformed(aevt); 175 } 176 Component c = getComponent(sel); 177 TabWrapper t = (TabWrapper) tabs.get(c); 178 if(t != null) { 179 layout.show(this, (String ) t.name); 180 } 181 repaint(); 182 } 183 } 184 185 190 public int getSelectedTab() { 191 return sel; 192 } 193 194 211 public void setPosition(int position) { 212 doLayout(); 213 repaint(); 214 } 215 216 public void remove(int idx) { 217 Component 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 234 public void add(Component comp, Object constraints, int index, Image 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 comp, Object constraints, int index) { 259 add(comp, constraints, index, null); 260 } 261 262 public void add(Component comp, Object constraints, Image image) { 263 add(comp, constraints, -1, image); 264 } 265 266 public Insets 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 g) { 276 super.paint(g); 277 278 Dimension s = getSize(); 279 Rectangle r = getHeadingBounds(); 280 int ncomponents = getComponentCount(); 281 int sel = getSelectedTab(); 282 283 Color c = getBackground(); 285 Color midlight = c.brighter(); 286 Color highlight = midlight.brighter(); 287 Color lowlight = c.darker(); 288 Color shadow = lowlight.darker(); 289 Color darkShadow = shadow.darker(); 290 291 switch (position) { 293 case TOP: 294 295 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 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 g.setColor(highlight); 305 g.drawLine(0, s.height - 2, 0, r.height); 306 307 int x = 0; 309 int selx = -1; 310 311 for (int i = 0; i < ncomponents; i++) { 312 Component 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 (x, 0, hw, r.height); 319 320 if (sel == i) { 321 selx = x; 322 } 324 else { 325 g.setColor(lowlight); 326 g.fillRect(x, 3, hw - 1, r.height - 4); 327 328 g.setColor(midlight); 330 g.drawLine(x, 3, x, r.height - 2); 331 g.drawLine(x + 1, 2, x + hw - 2, 2); 332 g.setColor(darkShadow); 334 g.drawLine(x + hw - 1, 3, x + hw - 1, r.height - 2); 335 g.setColor(shadow); 337 g.drawLine(x + hw - 2, 4, x + hw - 2, r.height - 2); 338 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 } 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 comp = getComponent(sel); 358 TabWrapper tab = (TabWrapper) tabs.get(comp); 359 360 int hw = metrics.stringWidth(tab.text) + (HORIZONTAL_GAP * 2); 361 362 365 g.setColor(highlight); 367 g.drawLine(x, 1, x, r.height - 2); 368 g.drawLine(x + 1, 0, x + hw - 1, 0); 369 g.setColor(darkShadow); 371 g.drawLine(x + hw, 1, x + hw, r.height - 2); 372 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 private Dimension getHeadingSize() { 386 Dimension s = new Dimension (); 387 int c = getComponentCount(); 388 for (int i = 0; i < c; i++) { 389 Component 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) + (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 System.err.println(Messages.getString("TabbedPanel.tabWrapperCouldNotBeFound") + i + " [" + comp + " could not be found"); } 414 } 415 return s; 416 417 } 418 419 422 private Rectangle getHeadingBounds() { 423 Dimension s = getHeadingSize(); 424 Point loc = new Point (); 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 (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 public static void main(String [] args) { 448 Frame frame = new Frame ("Tabs"); frame.setLayout(new BorderLayout ()); 450 451 Label l1 = new Label ("Test label 1"); Panel p1 = new Panel (new BorderLayout ()); 453 p1.add(l1, BorderLayout.CENTER); 454 455 Label l2 = new Label ("Test label 2"); Panel p2 = new Panel (new BorderLayout ()); 457 p2.add(l2, BorderLayout.CENTER); 458 459 Label l3 = new Label ("Test label 3"); Panel p3 = new Panel (new BorderLayout ()); 461 p3.add(l3, BorderLayout.CENTER); 462 463 Label l4 = new Label ("Test label 4"); Panel p4 = new Panel (new BorderLayout ()); 465 p4.add(l4, BorderLayout.CENTER); 466 467 TabbedPanel tabs = new TabbedPanel(TabbedPanel.TOP); 468 tabs.add("Test Tab 1", p1); tabs.add(Messages.getString("TabbedPanel.11"), p2); tabs.add(Messages.getString("TabbedPanel.12"), p3); tabs.add(Messages.getString("TabbedPanel.13"), p4); 473 tabs.setSelectedTab(1); 474 475 frame.add(tabs, BorderLayout.CENTER); 476 frame.pack(); 477 frame.addWindowListener(new WindowAdapter () { 478 public void windowClosing(WindowEvent evt) { 479 System.exit(0); 480 } 481 482 }); 483 frame.setVisible(true); 484 } 485 486 488 class TabWrapper { 489 Component component; 490 String text; 491 Image image; 492 Rectangle bounds; 493 Object constraints; 494 String name; 495 496 TabWrapper(String name, String text, Image image, Component component, 497 Object 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 { 508 TabbedLayout(int hgap, int vgap) { 509 super(hgap, vgap); 510 } 511 512 public void layoutContainer(Container parent) { 513 synchronized (parent.getTreeLock()) { 514 Insets insets = parent.getInsets(); 515 int ncomponents = parent.getComponentCount(); 516 Component comp = null; 517 boolean currentFound = false; 518 Dimension s = getHeadingSize(); 519 int headingSize = position == TOP || position == BOTTOM ? s.height : 520 s.width; 521 insets = 522 new Insets ( 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 552 public Dimension minimumLayoutSize(Container parent) { 553 Dimension s = super.maximumLayoutSize(parent); 554 Dimension c = getHeadingSize(); 555 return position == TOP 556 || position == BOTTOM 557 ? new Dimension (Math.max(s.width, c.width), s.height + c.height) 558 : new Dimension (s.width + c.width, Math.max(s.height, c.height)); 559 } 560 561 566 public Dimension preferredLayoutSize(Container parent) { 567 Dimension s = super.preferredLayoutSize(parent); 568 Dimension c = getHeadingSize(); 569 return position == TOP 570 || position == BOTTOM 571 ? new Dimension (Math.max(s.width, c.width), s.height + c.height) 572 : new Dimension (s.width + c.width, Math.max(s.height, c.height)); 573 } 574 } 575 576 579 public int getSelectedTabIndex() { 580 return sel; 581 } 582 583 } 584 | Popular Tags |