1 23 24 package org.objectweb.fractal.gui.graph.view; 25 26 import org.objectweb.fractal.gui.Constants; 27 import org.objectweb.fractal.gui.model.ClientInterface; 28 import org.objectweb.fractal.gui.model.Component; 29 import org.objectweb.fractal.gui.model.Interface; 30 import org.objectweb.fractal.gui.selection.model.Selection; 31 32 import java.awt.Color ; 33 import java.awt.FontMetrics ; 34 import java.awt.Graphics ; 35 import java.awt.Graphics2D ; 36 import java.awt.Point ; 37 import java.awt.Rectangle ; 38 import java.awt.Shape ; 39 import java.util.List ; 40 41 47 48 public class BasicComponentRenderer implements 49 ComponentRenderer, 50 Constants 51 { 52 53 57 58 private final static int MAX_DIV = 16; 59 60 64 65 private final static int INSETS = 2; 66 67 71 72 private final static int EPS = 4; 73 74 79 80 Component c; 81 82 87 88 Rectangle r; 89 90 93 94 int x; 95 96 99 100 int y; 101 102 105 106 int w; 107 108 111 112 int h; 113 114 117 118 List sItfList; 119 120 123 124 List cItfList; 125 126 129 130 int borderSize; 131 132 135 136 int divH; 137 138 141 142 int itfH; 143 144 147 148 int itfW; 149 150 153 154 int itfWi; 155 156 159 160 int bw1; 161 162 165 166 int bw2; 167 168 171 172 int bw3; 173 174 177 178 public BasicComponentRenderer () { 179 } 180 181 185 public void drawComponent ( 186 final Graphics g, 187 final Component c, 188 final Selection s, 189 final Rectangle r, 190 final Color color, 191 final boolean expanded, 192 final int mode, 193 final int state) 194 { 195 initialize(c, r); 196 Object sel = (s == null ? null : s.getSelection()); 197 198 g.translate(x, y); 200 if (c.getMasterComponent() != null && sel != c) { 201 ((Graphics2D )g).setStroke(DASHED_STROKE); 202 } else { 203 ((Graphics2D )g).setStroke(NORMAL_STROKE); 204 } 205 206 216 217 int [] PXO = {itfW+4, itfW+w-2*itfW+3, itfW+w-2*itfW+3, itfW+11, itfW+4 }; 218 int [] PYO = {4, 4, h+3, h+3, h-4 }; 219 g.setColor(Color.lightGray); 220 g.fillPolygon(PXO, PYO, 5); 221 int [] PX = {itfW, itfW+w-2*itfW-1, itfW+w-2*itfW-1, itfW+7, itfW }; 222 int [] PY = {0, 0, h-1, h-1, h-8 }; 223 int [] PXS = {itfW-1, itfW+w-2*itfW, itfW+w-2*itfW, itfW+7, itfW-1 }; 224 int [] PYS = {-1, -1, h, h, h-8 }; 225 g.setColor(color); 226 g.fillPolygon(PX, PY, 5); 227 g.setColor(sel == c ? SELECTION_COLOR : Color.black); 228 g.drawPolygon(PX, PY, 5); 229 if (sel == c) { 230 g.drawPolygon(PXS, PYS, 5); 231 } 232 233 if (c.isComposite()) { 234 g.setColor(Color.white); 235 g.fillRect(bw1, borderSize, w-2*bw1, h-2*borderSize); 236 g.setColor(Color.black); 237 g.drawRect(bw1, borderSize, w-2*bw1-1, h-2*borderSize-1); 238 } 239 240 g.setColor(color); 241 if (state != NO_INSTANCE) { 242 int [] TX = {itfW, itfW+9, itfW+9, itfW+7 }; 243 int [] TY = {h-9, h-9, h-1, h-1 }; 244 if (state == STARTED) { 245 g.setColor(Color.green); 246 } else if (state == STOPPED) { 247 g.setColor(Color.red); 248 } 249 g.fillPolygon(TX, TY, 4); 250 g.setColor(Color.black); 251 g.drawPolygon(TX, TY, 4); 252 } 253 254 if (!expanded) { 255 } 257 272 274 g.setFont (NAME_FONT); 275 String name = c.getName(); 276 if (name.length() == 0) { 277 name = "<missing>"; 278 g.setColor(ERROR_COLOR); 279 } else { 280 g.setColor(Color.black); 281 } 282 drawString (g, name, itfWi, divH/2 - itfH/2 + INSETS, w - 2*itfWi, itfH, 0, true); 283 284 285 287 g.setFont(PROVIDED_FONT); 288 ((Graphics2D )g).setStroke(NORMAL_STROKE); 289 int h = divH + INSETS; 290 int hh = h + divH/2; 291 int hhh = hh - itfH/2; 292 int hhi = hh + itfH/2; 293 294 int ep = 2; 295 296 for (int i = 0; i < sItfList.size(); ++i) { 297 Interface itf = (Interface)sItfList.get(i); 298 if (sel == itf) { 299 g.setColor(SELECTION_COLOR); 300 g.fillRect(-1, hhh - 1, itfW + 1, itfH + 3); 301 } else if (c.isComposite() && expanded && sel == itf.getComplementaryInterface()) { 302 g.setColor(SELECTION_COLOR); 303 g.fillRect(bw1 + 1, hhh - 1, itfW + 1, itfH + 3); 304 } 305 306 g.setColor (itf.getStatus() == Interface.OK ? PROVIDED_COLOR : ERROR_COLOR); 307 if (mode == 0) name = itf.getName(); 308 else if (mode == 1) name = itf.getSignature(); 309 else name = " "; 310 name = ajustName (g, name, (w-2*bw1)/2); 311 312 if (isMasterCollectionItf(itf)) { 313 if (expanded) { 314 drawString (g, name, bw3+1, hhh + INSETS, w - 2*bw3, itfH, 0, true); 315 g.drawLine(bw1, hh, bw2, hh); 316 g.drawLine(bw2, hhh, bw2, hh + itfH/2); 317 g.drawLine(bw2-2, hhh, bw2-2, hh + itfH/2); 318 } 319 } else { 320 if (c.isComposite() && expanded) { 321 drawString (g, name, bw3+1, hhh + INSETS, w - 2*bw3, itfH, 0, true); 322 g.drawLine(bw1, hh, bw2, hh); 323 g.drawLine(bw2, hhh, bw2, hhi); 324 g.drawLine(bw2-1, hhh, bw2-1, hhi); 325 } else { 326 if (itf.isCollection()) { 327 g.setColor(Color.gray); 328 ep = 1; 329 } 330 drawString 331 (g, name, itfW + INSETS, hhh + INSETS, w - 2*itfWi, itfH, 0, true); 332 } 333 g.drawLine(0, hh, itfW - 1, hh); 334 g.drawLine(0, hhh, 0, hhi); 335 g.drawLine(1, hhh, 1, hhi); 336 } 337 h += divH; 338 hh += divH; 339 hhh += divH; 340 hhi += divH; 341 } 342 343 g.setFont(REQUIRED_FONT); 344 h = divH + INSETS; 345 hh = h + divH/2; 346 hhh = hh - itfH/2; 347 hhi = hh + itfH/2; 348 for (int i = 0; i < cItfList.size(); ++i) { 349 Interface itf = (Interface)cItfList.get(i); 350 if (sel == itf) { 351 g.setColor(SELECTION_COLOR); 352 g.fillRect(w - itfW, hhh - 1, itfW+1, itfH+3); 353 } else if (c.isComposite() && expanded && 354 sel == itf.getComplementaryInterface()) 355 { 356 g.setColor(SELECTION_COLOR); 357 g.fillRect(w - bw2 - 1, hhh - 1, itfW, itfH + 3); 358 } 359 g.setColor(itf.getStatus() == Interface.OK ? REQUIRED_COLOR : ERROR_COLOR); 360 if (mode == 0) name = itf.getName(); 362 else if (mode == 1) name = itf.getSignature(); 363 else name = " "; 364 365 name = ajustName (g, name, (w-2*bw1)/2); 366 367 Color col = g.getColor(); 368 if (isMasterCollectionItf(itf)) { 369 drawString 370 (g, name, itfW + INSETS, hhh + INSETS, w - 2*itfWi, itfH, 0, false); 371 g.drawLine(w - itfW, hh, w - 1, hh); 372 g.drawLine(w - 3, hhh, w - 3, hhi); 373 g.drawLine(w, hhh, w, hhi); 374 } else { 375 if (c.isComposite() && expanded) { 376 drawString (g, name, bw3, hhh + INSETS, w - 2*bw3, itfH, 0, false); 377 g.drawLine(w - bw2, hh, w - bw1 - 1, hh); 378 g.drawLine(w - bw2, hhh, w - bw2, hhi); 379 } else { 380 if (itf.isCollection()) { 381 g.setColor(Color.gray); 382 ep = 1; 383 } 384 drawString (g, name, itfWi, hhh + INSETS, w - 2*itfWi, itfH, 0, false); 385 } 386 g.drawLine(w - itfW, hh, w - 1, hh); 387 g.drawLine(w - 1, hhh, w - 1, hhi); 388 if (ep == 2) g.drawLine(w, hhh, w, hhi); 389 } 390 g.setColor (col); 391 h += divH; 392 hh += divH; 393 hhh += divH; 394 hhi += divH; 395 } 396 g.translate(-x, -y); 397 } 398 399 private String ajustName (Graphics g, String name, int max) { 400 FontMetrics fm = g.getFontMetrics(); 401 int nameWidth = fm.stringWidth(name); 402 int paddWidth = fm.stringWidth(".. "); 403 404 if ((nameWidth > (max)) && (name.length()> 3)) { 405 while (nameWidth > (max-paddWidth)) { 406 int len = name.length(); if (len < 4) break; 407 name = name.substring(0, --len); 408 nameWidth = fm.stringWidth(name); 409 } 410 name = name+".. "; 411 } 412 return name; 413 } 414 415 public ComponentPart getComponentPart ( 416 final Component c, 417 final Rectangle r, 418 final boolean expanded, 419 final int x0, 420 final int y0) 421 { 422 if (x0 < r.x || x0 > r.x + r.width || y0 < r.y || y0 > r.y + r.height) { 424 return null; 425 } 426 427 initialize(c, r); 429 int part = isCorner(x + itfW, y, w - 2 * itfW, h, x0, y0); 430 if (part != -1) { 431 return new ComponentPart(c, null, part, r); 432 } 433 434 int h = divH + INSETS; 436 int hhh = h + divH/2 - itfH/2; 437 for (int i = 0; i < sItfList.size(); ++i) { 438 Interface itf = (Interface)sItfList.get(i); 439 if (isMasterCollectionItf(itf)) { 440 if ((x0 >= x + bw1) && (x0 <= x + bw2) && 441 (y0 >= y + hhh) && (y0 <= y + hhh + itfH)) 442 { 443 return new ComponentPart( 444 c, itf.getComplementaryInterface(), ComponentPart.INTERFACE, r); 445 } 446 } else { 447 if ((y0 >= y + hhh) && (y0 <= y + hhh + itfH)) { 448 if (x0 <= x + itfW) { 449 return new ComponentPart(c, itf, ComponentPart.INTERFACE, r); 450 } else if ((x0 >= x + bw1) && (x0 <= x + bw2)) { 451 if (c.isComposite() && expanded) { 452 return new ComponentPart( 453 c, itf.getComplementaryInterface(), ComponentPart.INTERFACE, r); 454 } 455 } 456 } 457 } 458 h += divH; 459 hhh += divH; 460 } 461 462 h = divH + INSETS; 463 hhh = h + divH/2 - itfH/2; 464 for (int i = 0; i < cItfList.size(); ++i) { 465 Interface itf = (Interface)cItfList.get(i); 466 if (isMasterCollectionItf(itf)) { 467 if ((x0 >= x + w - itfW) && (y0 >= y + hhh) && (y0 <= y + hhh + itfH)) { 468 return new ComponentPart(c, itf, ComponentPart.INTERFACE, r); 469 } 470 } 471 else if ((y0 >= y + hhh) && (y0 <= y + hhh + itfH)) { 472 if (x0 >= x + w - itfW) { 473 return new ComponentPart(c, itf, ComponentPart.INTERFACE, r); 474 } else if ((x0 >= x + w - bw2) && (x0 <= x + w - bw1)) { 475 if (c.isComposite() && expanded) { 476 return new ComponentPart( 477 c, itf.getComplementaryInterface(), ComponentPart.INTERFACE, r); 478 } 479 } 480 } 481 h += divH; 482 hhh += divH; 483 } 484 485 part = isBorder (x+itfW, y, w-2*itfW, this.h, x0, y0); 487 if (part != -1) { 488 return new ComponentPart(c, null, part, r); 489 } 490 if ((x0 >= x+itfW) && (x0 <= x+w-itfW) && (y0 >= y) && (y0 <= y+divH)) { 492 return new ComponentPart(c, null, ComponentPart.HEADER, r); 493 } 494 if ((x0 >= x+itfW) && (x0 <= x+w-itfW) && 496 (y0 >= y+divH) && (y0 <= y+this.h)) 497 { 498 return new ComponentPart(c, null, ComponentPart.CONTENT, r); 499 } 500 return null; 501 } 502 503 public Point getInterfacePosition ( 504 final Component c, 505 final Rectangle r, 506 final Interface i) 507 { 508 initialize(c, r); 509 510 int baseX = r.x + r.width; 511 int baseY = r.y + divH / 2 + INSETS; 512 513 if (!(i instanceof ClientInterface)) { 514 if (i.isInternal()) { 515 int index = cItfList.indexOf(i.getComplementaryInterface()); 516 return new Point (baseX - bw2, baseY + divH*(index + 1)); 517 } else { 518 int index = sItfList.indexOf(i); 519 return new Point (r.x, baseY + divH * (index + 1)); 520 } 521 } else { 522 if (i.isInternal()) { 523 int index = sItfList.indexOf(i.getComplementaryInterface()); 524 return new Point (r.x + bw2, baseY + divH*(index + 1)); 525 } else { 526 int index = cItfList.indexOf(i); 527 return new Point (baseX, baseY + divH*(index + 1)); 528 } 529 } 530 } 531 532 public Rectangle getSubComponentArea (final Component c, final Rectangle r) { 533 initialize(c, r); 534 int xp = x + INSETS + itfW + borderSize; 535 int yp = y + INSETS + borderSize; 536 int widthp = w - 2 * (INSETS + itfW + borderSize); 537 int heightp = h - 2 * (INSETS + borderSize); 538 return new Rectangle (xp, yp, widthp, heightp); 539 } 540 541 545 551 552 protected void initialize (final Component c, final Rectangle r) { 553 if (c == this.c && r == this.r) { 554 return; 555 } 556 this.c = c; 557 this.r = r; 558 x = r.x; 559 y = r.y; 560 w = r.width; 561 h = r.height; 562 sItfList = c.getServerInterfaces(); 563 cItfList = c.getClientInterfaces(); 564 565 int divisions = 2 + Math.max(sItfList.size(), cItfList.size()); 566 divH = Math.min(MAX_DIV, (h - 2 * INSETS) / divisions); 567 borderSize = Math.min(5, (h - 2 * INSETS) / divisions); 569 itfH = (int)(divH * 0.75); 570 itfW = itfH / 2; 571 itfWi = itfW + INSETS; 572 bw1 = itfW + borderSize; 573 bw2 = 2*itfW + borderSize; 574 bw3 = 2*itfW + borderSize + INSETS; 575 } 576 577 589 590 protected void drawString ( 591 final Graphics g, 592 final String s, 593 final int x, 594 final int y, 595 final int dx, 596 final int dy, 597 final int insets, 598 final boolean left) 599 { 600 int size = dy - 2 * insets; 601 g.setFont(g.getFont().deriveFont((float)size)); 602 FontMetrics fm = g.getFontMetrics(); 603 double descent = ((double)fm.getDescent()) / fm.getHeight() * size; 604 int y0 = y + dy - insets - (int)Math.round(descent); 605 Shape shape = g.getClip(); 606 g.clipRect(x, y, dx, dy); 607 if (left) { 608 g.drawString(s, x + insets, y0); 609 } else { 610 g.drawString(s, x + dx - insets - fm.stringWidth(s), y0); 611 } 612 g.setClip(shape); 613 } 614 615 628 629 protected int isCorner ( 630 final int x, 631 final int y, 632 final int w, 633 final int h, 634 final int x0, 635 final int y0) 636 { 637 if (Math.abs(x0 - x) < EPS && Math.abs(y0 - y) < EPS) { 638 return ComponentPart.TOP_LEFT_CORNER; 639 } 640 if (Math.abs(x0 - (x + w)) < EPS && Math.abs(y0 - y) < EPS) { 641 return ComponentPart.TOP_RIGHT_CORNER; 642 } 643 if (Math.abs(x0 - x) < EPS && Math.abs(y0 - (y + h)) < EPS) { 644 return ComponentPart.BOTTOM_LEFT_CORNER; 645 } 646 if (Math.abs(x0 - (x + w)) < EPS && Math.abs(y0 - (y + h)) < EPS) { 647 return ComponentPart.BOTTOM_RIGHT_CORNER; 648 } 649 return -1; 650 } 651 652 665 666 protected int isBorder ( 667 final int x, 668 final int y, 669 final int w, 670 final int h, 671 final int x0, 672 final int y0) 673 { 674 if (Math.abs(x0 - x) < EPS && y0 >= y && y0 <= y + h) { 675 return ComponentPart.LEFT_BORDER; 676 } 677 if (Math.abs(y0 - y) < EPS && x0 >= x && x0 <= x + w) { 678 return ComponentPart.TOP_BORDER; 679 } 680 if (Math.abs(x0 - (x + w)) < EPS && y0 >= y && y0 <= y + h) { 681 return ComponentPart.RIGHT_BORDER; 682 } 683 if (Math.abs(y0 - (y + h)) < EPS && x0 >= x && x0 <= x + w) { 684 return ComponentPart.BOTTOM_BORDER; 685 } 686 return -1; 687 } 688 689 697 698 private boolean isMasterCollectionItf (final Interface itf) { 699 return itf.isCollection() && itf.getMasterCollectionInterface() == null; 700 } 701 } 702 | Popular Tags |