1 19 package org.netbeans.swing.tabcontrol.plaf; 20 21 import javax.swing.*; 22 import java.awt.*; 23 import java.awt.event.WindowListener ; 24 import java.awt.geom.Area ; 25 import java.awt.geom.GeneralPath ; 26 27 32 33 38 class GenericGlowingChiclet { 39 public static final int STATE_PRESSED = 1; 40 public static final int STATE_SELECTED = 2; 41 public static final int STATE_ACTIVE = 4; 42 public static final int STATE_CLOSING = 8; 43 public static final int STATE_ATTENTION = 16; 44 45 static Color[] selectedActive = new Color[]{ 49 new Color(220, 238, 255), new Color(139, 187, 238), 50 new Color(90, 143, 229), new Color(190, 247, 255)}; 51 52 static Color[] selectedPressedActive = new Color[]{ 53 selectedActive[0], new Color(50, 150, 229), 54 new Color(80, 80, 200), selectedActive[3]}; 55 56 static Color[] inactive = new Color[]{ 57 Color.WHITE, new Color(222, 222, 227), new Color(205, 205, 205), 58 new Color(246, 243, 249)}; 59 60 static Color[] active = new Color[]{ 61 Color.WHITE, new Color(222, 222, 227), new Color(205, 205, 205), 62 new Color(246, 243, 249)}; 63 64 static Color[] selectedInactive = new Color[]{ 65 new Color(240, 250, 255), new Color(212, 222, 242), 66 new Color(180, 190, 200), new Color(230, 230, 255)}; 67 68 static Color[] closing = new Color[]{ 69 new Color(255, 238, 220), new Color(238, 137, 109), 70 new Color(255, 50, 50), new Color(255, 237, 40)}; 71 72 static Color[] attention = new Color[]{ 73 new Color(255, 255, 220), new Color(238, 237, 109), 74 new Color(255, 255, 50), new Color(255, 237, 40)}; 75 76 private Color upperTop = selectedActive[0]; 77 private Color upperBottom = selectedActive[1]; 78 private Color lowerTop = selectedActive[2]; 79 private Color lowerBottom = selectedActive[3]; 80 81 private Rectangle scratch = new Rectangle(); 82 private float fupperLeftArc = 0; 83 private float fupperRightArc = 0; 84 private float flowerLeftArc = 0; 85 private float flowerRightArc = 0; 86 private int upperLeftArc = 0; 87 private int upperRightArc = 0; 88 private int lowerLeftArc = 0; 89 private int lowerRightArc = 0; 90 private boolean usePercentages = false; 91 92 private boolean notchRight = false; 93 private boolean notchLeft = false; 94 95 protected boolean changed = false; 96 protected int state = STATE_ACTIVE | STATE_SELECTED; 97 98 public static final GenericGlowingChiclet INSTANCE = new GenericGlowingChiclet(); 99 100 protected GenericGlowingChiclet() { 101 } 105 106 public void setColors(Color upperTop, Color upperBottom, Color lowerTop, 107 Color lowerBottom) { 108 changed |= !upperTop.equals(this.getUpperTop()) 109 || !upperBottom.equals(this.getUpperBottom()) 110 || !lowerTop.equals(this.getLowerTop()) 111 || !lowerBottom.equals(this.getLowerBottom()); 112 this.upperTop = upperTop; 113 this.upperBottom = upperBottom; 114 this.lowerTop = lowerTop; 115 this.lowerBottom = lowerBottom; 116 } 117 118 public Color[] getColors() { 119 return new Color[] { 120 getUpperTop(), getUpperBottom(), getLowerTop(), getLowerBottom() 121 }; 122 } 123 124 protected int getState() { 125 return state; 126 } 127 128 public void setState(int i) { 129 changed |= state != i; 130 if (state != i) { 131 if ((state & STATE_PRESSED) != 0) { 132 state |= STATE_ACTIVE; 133 } 134 state = i; 135 Color[] nue; 136 if ((state & STATE_CLOSING) != 0) { 137 nue = closing; 138 } else if ((state & STATE_ATTENTION) != 0) { 139 nue = attention; 140 } else { 141 switch (state) { 142 case STATE_PRESSED | STATE_ACTIVE: 143 case STATE_PRESSED | STATE_ACTIVE | STATE_SELECTED: 144 nue = selectedPressedActive; 145 break; 146 case STATE_ACTIVE | STATE_SELECTED: 147 nue = selectedActive; 148 break; 149 case STATE_SELECTED: 150 nue = selectedInactive; 151 break; 152 case STATE_ACTIVE: 153 nue = active; 154 break; 155 default : 156 nue = inactive; 157 } 158 } 159 upperTop = nue[0]; 160 upperBottom = nue[1]; 161 lowerTop = nue[2]; 162 lowerBottom = nue[3]; 163 } 164 } 165 166 private Rectangle bounds = new Rectangle(); 167 168 public void setBounds(int x, int y, int w, int h) { 169 changed |= x != bounds.x || y != bounds.y || w != bounds.width 170 || h != bounds.height; 171 bounds.setBounds(x, y, w, h - 1); 172 } 173 174 private boolean allowVertical = false; 175 176 public void setAllowVertical(boolean val) { 177 if (val != allowVertical) { 178 allowVertical = val; 179 changed = true; 180 } 181 } 182 183 private Rectangle getBounds() { 184 scratch.setBounds(bounds); 185 return scratch; 186 } 187 188 public void setArcs(int upperLeft, int upperRight, int lowerLeft, 189 int lowerRight) { 190 changed |= upperLeft != upperLeftArc || upperRight != upperRightArc 191 || lowerLeft != lowerLeftArc || lowerRight != lowerRightArc 192 || usePercentages; 193 194 upperLeftArc = upperLeft; 195 upperRightArc = upperRight; 196 lowerLeftArc = lowerLeft; 197 lowerRightArc = lowerRight; 198 usePercentages = false; 199 } 200 201 public void setArcs(float upperLeft, float upperRight, float lowerLeft, 202 float lowerRight) { 203 changed |= upperLeft != fupperLeftArc || upperRight != fupperRightArc 204 || lowerLeft != flowerLeftArc || lowerRight != flowerRightArc 205 || !usePercentages; 206 207 fupperLeftArc = upperLeft; 208 fupperRightArc = upperRight; 209 flowerLeftArc = lowerLeft; 210 flowerRightArc = lowerRight; 211 usePercentages = true; 212 } 213 214 public void setNotch(boolean right, boolean left) { 215 changed |= right != notchRight || left != notchLeft; 216 notchRight = right; 217 notchLeft = left; 218 } 219 220 private int getNotchRightArc() { 221 int arc = getUpperRightArc(); 222 if (arc == 0) { 223 arc = bounds.height / 2; 224 } 225 return arc / 3; 226 } 227 228 private int getNotchLeftArc() { 229 int arc = getUpperLeftArc(); 230 if (arc == 0) { 231 arc = bounds.height / 2; 232 } 233 return arc / 3; 234 } 235 236 private int getUpperLeftArc() { 237 if (!usePercentages) { 238 return upperLeftArc; 239 } else { 240 return Math.round(fupperLeftArc 241 * Math.min(getBounds().height, 242 getBounds().width)); 243 } 244 } 245 246 private int getUpperRightArc() { 247 if (!usePercentages) { 248 return upperRightArc; 249 } else { 250 return Math.round(fupperRightArc 251 * Math.min(getBounds().height, 252 getBounds().width)); 253 } 254 } 255 256 private int getLowerLeftArc() { 257 if (!usePercentages) { 258 return lowerLeftArc; 259 } else { 260 return Math.round(flowerLeftArc 261 * Math.min(getBounds().height, 262 getBounds().width)); 263 } 264 } 265 266 private int getLowerRightArc() { 267 if (!usePercentages) { 268 return lowerRightArc; 269 } else { 270 return Math.round(flowerRightArc 271 * Math.min(getBounds().height, 272 getBounds().width)); 273 } 274 } 275 276 public void draw(Graphics2D g) { 277 if (bounds.width == 0 || bounds.height == 0) { 278 return; 279 } 280 drawInterior(g); 281 if (drawOutline) { 282 drawOutline(g); 283 } 284 changed = false; 285 } 286 287 private boolean drawOutline = true; 288 public void setDrawOutline (boolean b) { 289 drawOutline = b; 290 } 291 292 private void drawOutline(Graphics2D g) { 293 Shape s = getClipShape(); 294 g.setColor(dark()); 295 g.setStroke(new BasicStroke(0.95f)); 296 Rectangle r = getBounds(); 297 r.height += 1; 298 299 Shape clip = g.getClip(); 300 if (clip != null) { 301 Area a = new Area (clip); 302 a.intersect(new Area (r)); 303 g.setClip(a); 304 } else { 305 g.setClip(r); 306 } 307 308 g.draw(s); 309 g.setColor(getOutlineDark()); 310 311 r = getBounds(); 312 g.setStroke(new BasicStroke(0.70f)); 313 if (getLowerRightArc() != 0) { 314 g.drawLine(Math.max(r.x, r.x + getLowerLeftArc() - 3), 315 r.y + r.height - 1, 316 Math.min(r.x + r.width - getLowerRightArc() + 3, r.x + r.width) - 1, 317 r.y + r.height- 1); 318 } else { 319 g.drawLine(Math.max(r.x, r.x + getLowerLeftArc() - 3), 320 r.y + r.height - 1, 321 Math.min(r.x + r.width - getLowerRightArc() + 3, r.x + r.width), 322 r.y + r.height- 1); 323 } 324 g.setClip(clip); 325 } 326 327 protected Color getOutlineDark() { 328 return new Color(50, 50, 50); 329 } 330 331 private void drawInterior(Graphics2D g) { 332 Shape s = getClipShape(); 333 Area a = new Area (s); 334 335 Shape clip = g.getClip(); 336 if (clip != null) { 337 a.intersect(new Area (clip)); 338 } 339 340 Rectangle r; 341 if (isVertical()) { 342 r = getBounds(); 343 r.width /= 2; 344 a.intersect(new Area (r)); 345 g.setClip(a); 346 347 g.setPaint(getLeftPaint()); 348 g.fill(s); 349 350 r = getBounds(); 351 r.width /= 2; 352 r.x += r.width; 353 a = new Area (s); 354 if (clip != null) { 355 a.intersect(new Area (clip)); 356 } 357 a.intersect(new Area (r)); 358 g.setClip(a); 359 360 g.setPaint(getRightPaint()); 361 g.fill(s); 362 } else { 363 r = getBounds(); 365 r.height /= 2; 366 a.intersect(new Area (r)); 367 368 g.setClip(a); 369 370 g.setPaint(getUpperPaint()); 371 g.fill(s); 372 373 a = new Area (s); 375 if (clip != null) { 376 a.intersect(new Area (clip)); 377 } 378 r = getBounds(); 379 r.y += r.height / 2; 380 r.height -= r.height / 2; 381 a.intersect(new Area (r)); 382 383 g.setClip(a); 384 g.setPaint(getLowerPaint()); 385 g.fill(s); 386 } 387 388 389 Composite composite = g.getComposite(); 390 AlphaComposite comp = AlphaComposite.getInstance( 391 AlphaComposite.SRC_OVER, 0.8f); 392 g.setComposite(comp); 393 394 395 int arc = getUpperLeftArc(); 396 r = getBounds(); 397 r.width = arc; 398 r.height = r.height / 2; 399 400 a = new Area (s); 401 if (clip != null) { 402 a.intersect(new Area (clip)); 403 } 404 a.intersect(new Area (r)); 405 g.setClip(a); 406 g.setPaint(getUpperLeftPaint()); 407 g.fill(s); 408 409 arc = getUpperRightArc(); 410 r = getBounds(); 411 r.x = r.x + r.width - arc; 412 r.width = arc; 413 r.height = r.height / 2; 414 415 a = new Area (s); 416 if (clip != null) { 417 a.intersect(new Area (clip)); 418 } 419 a.intersect(new Area (r)); 420 g.setClip(a); 421 g.setPaint(getUpperRightPaint()); 422 g.fill(s); 423 424 arc = getLowerRightArc(); 425 r = getBounds(); 426 r.x = r.x + r.width - arc; 427 r.width = arc; 428 r.y = r.y + (r.height / 2); 429 r.height = r.height / 2; 430 431 a = new Area (s); 432 if (clip != null) { 433 a.intersect(new Area (clip)); 434 } 435 a.intersect(new Area (r)); 436 g.setClip(a); 437 g.setPaint(getLowerRightPaint()); 438 g.fill(s); 439 440 441 arc = getLowerLeftArc(); 442 r = getBounds(); 443 r.width = arc; 444 r.y = r.y + (r.height / 2); 445 r.height = r.height / 2; 446 447 a = new Area (s); 448 if (clip != null) { 449 a.intersect(new Area (clip)); 450 } 451 a.intersect(new Area (r)); 452 g.setClip(a); 453 g.setPaint(getLowerLeftPaint()); 454 g.fill(s); 455 456 457 g.setClip(clip); 458 g.setComposite(composite); 459 } 460 461 private boolean isVertical() { 462 if (!allowVertical) { 463 return false; 464 } else { 465 return bounds.height > bounds.width; 466 } 467 } 468 469 private GradientPaint getUpperPaint() { 470 Rectangle r = getBounds(); 471 return ColorUtil.getGradientPaint(r.x, r.y + (r.height / 9), 472 getUpperTop(), r.x, 473 r.y + (r.height / 2), getUpperBottom(), 474 true); 475 } 476 477 private GradientPaint getLowerPaint() { 478 Rectangle r = getBounds(); 479 return ColorUtil.getGradientPaint(r.x, r.y + (r.height / 2), 480 getLowerTop(), r.x, r.y + r.height, 481 getLowerBottom(), false); 482 } 483 484 private GradientPaint getLeftPaint() { 485 Rectangle r = getBounds(); 486 return ColorUtil.getGradientPaint(r.x, r.y, getUpperTop(), 487 r.x + (r.width / 2), r.y, 488 getUpperBottom()); 489 } 490 491 private GradientPaint getRightPaint() { 492 Rectangle r = getBounds(); 493 return ColorUtil.getGradientPaint(r.x + (r.width / 2), r.y, getLowerTop(), 494 r.x + r.width, r.y, getLowerBottom()); 495 } 496 497 private GradientPaint getUpperLeftPaint() { 498 Rectangle r = getBounds(); 499 int arc = getUpperLeftArc(); 500 if (!isVertical()) { 501 return ColorUtil.getGradientPaint(r.x, r.y + (r.height / 2), dark(), 502 r.x + (arc / 2), r.y + (r.height / 2) - arc / 2, light()); 503 } else { 504 return ColorUtil.getGradientPaint(r.x + (r.width / 2), r.y, 505 dark(), 506 r.x + (r.width / 2) - (arc / 2), r.y + arc, 507 light()); 508 } 509 } 510 511 private GradientPaint getUpperRightPaint() { 512 Rectangle r = getBounds(); 513 int arc = getUpperRightArc(); 514 if (!isVertical()) { 515 return ColorUtil.getGradientPaint(r.x + r.width, r.y 516 + (r.height / 2), 517 dark(), 518 r.x + r.width - (arc / 2), r.y + (r.height / 2) - arc / 2, 519 light()); 520 } else { 521 return ColorUtil.getGradientPaint(r.x + (r.width / 2), r.y, 522 dark(), r.x + (r.width / 2) + (arc / 2), r.y + arc, light()); 523 } 524 } 525 526 private GradientPaint getLowerRightPaint() { 527 Rectangle r = getBounds(); 528 int arc = getLowerRightArc(); 529 if (!isVertical()) { 530 return ColorUtil.getGradientPaint(r.x + r.width, r.y 531 + (r.height / 2), dark(), r.x + r.width - (arc / 2), 532 r.y + (r.height / 2) + (arc / 2), light()); 533 } else { 534 return ColorUtil.getGradientPaint(r.x + (r.width / 2), 535 r.y + r.height, dark(), r.x + (r.width / 2) + (arc / 2), 536 r.y + r.height - arc, light()); 537 } 538 } 539 540 private GradientPaint getLowerLeftPaint() { 541 Rectangle r = getBounds(); 542 int arc = getLowerLeftArc(); 543 if (!isVertical()) { 544 return ColorUtil.getGradientPaint(r.x, r.y + (r.height / 2), dark(), 545 r.x + (arc / 2), r.y + (r.height / 2) + (arc / 2), light()); 546 } else { 547 return ColorUtil.getGradientPaint(r.x + (r.width / 2), 548 r.y + r.height, dark(), r.x + (r.width / 2) - (arc / 2), 549 r.y + r.height - arc, light()); 550 } 551 } 552 553 private Shape clip = null; 554 555 private Shape getClipShape() { 556 if (changed) 557 update(); 558 if (clip == null) { 559 clip = createClip(); 560 } 561 return clip; 562 } 563 564 protected Color dark() { 565 if ((getState() & STATE_SELECTED) != 0 && (getState() & STATE_ACTIVE) != 0) { 566 return new Color(80, 80, 150); 567 } else { 568 return new Color(130, 130, 150); 569 } 570 } 571 572 private Color light() { 573 Color dark = dark(); 574 return new Color(dark.getRed(), dark.getGreen(), dark.getBlue(), 0); 575 } 576 577 private void update() { 578 clip = null; 579 } 580 581 private Shape createClip() { 582 Rectangle bds = getBounds(); 583 if (!notchLeft && !notchRight && !usePercentages 584 && upperRightArc == lowerRightArc 585 && lowerRightArc == lowerLeftArc 586 && lowerLeftArc == upperLeftArc && upperLeftArc == 0) { 587 return new Rectangle(getBounds()); 588 } 589 int upperRightArc = getUpperRightArc(); 590 int lowerRightArc = getLowerRightArc(); 591 int upperLeftArc = getUpperLeftArc(); 592 int lowerLeftArc = getLowerLeftArc(); 593 int notchR = getNotchRightArc(); 594 int notchL = getNotchLeftArc(); 595 596 GeneralPath gp = new GeneralPath (); 597 if (notchLeft) { 598 gp.moveTo(bds.x + notchL, bds.y + (bds.height / 2)); 599 gp.curveTo(bds.x + notchL, bds.y + (bds.height / 2), 600 bds.x + notchL, bds.y + (bds.height / 2) - notchL, 601 bds.x, bds.y + (bds.height / 2) - notchL); 602 if (bds.y + (bds.height / 2) - notchL > bds.y + upperLeftArc) { 603 gp.lineTo(bds.x, bds.y + upperLeftArc); 604 } 605 gp.curveTo(bds.x, Math.min(bds.y + upperLeftArc, 606 bds.y + (bds.height / 2) - notchL), 607 bds.x, bds.y, bds.x + upperLeftArc, bds.y); 608 } else { 609 gp.moveTo(bds.x, bds.y + bds.height - lowerLeftArc); 610 if (bds.y + bds.height - lowerLeftArc > bds.y + upperLeftArc) { 611 gp.lineTo(bds.x, bds.y + upperLeftArc); 612 } 613 gp.curveTo(bds.x, bds.y + upperLeftArc, bds.x, bds.y, 614 bds.x + upperLeftArc, bds.y); 615 } 616 if (bds.x + bds.width - upperLeftArc > bds.x + upperRightArc) { 617 gp.lineTo(bds.x + bds.width - upperRightArc, bds.y); 618 } 619 620 if (notchRight) { 621 gp.curveTo(bds.x + bds.width - upperRightArc - 1, bds.y, bds.x 622 + bds.width - 1, 623 bds.y, bds.x + bds.width - 1, 624 Math.min( bds.y + upperRightArc, 625 bds.y + (bds.height / 2) - notchR)); 626 627 if (bds.y + upperRightArc < bds.y + (bds.height / 2) - notchR) { 628 gp.lineTo(bds.x + bds.width - 1, 629 bds.y + (bds.height / 2) - notchR); 630 } 631 gp.curveTo(bds.x + bds.width - 1, bds.y + (bds.height / 2) - notchR, 632 bds.x + bds.width - notchR - 1, 633 bds.y + (bds.height / 2) - notchR, 634 bds.x + bds.width - notchR - 1, bds.y + (bds.height / 2)); 635 636 gp.curveTo(bds.x + bds.width - notchR - 1, bds.y + (bds.height / 2), 637 bds.x + bds.width - notchR - 1, 638 bds.y + (bds.height / 2) + notchR, bds.x + bds.width - 1, 639 bds.y + (bds.height / 2) + notchR); 640 641 if (bds.y + (bds.height / 2) + notchR 642 < bds.y + bds.height - lowerRightArc) { 643 gp.lineTo(bds.x + bds.width - 1, 644 bds.y + bds.height - lowerRightArc); 645 } 646 647 gp.curveTo(bds.x + bds.width - 1, Math.max( 648 bds.y + (bds.height / 2) + notchR, 649 bds.y + bds.height - lowerRightArc), 650 bds.x + bds.width - 1, bds.y + bds.height, 651 bds.x + bds.width - lowerRightArc - 1, bds.y + bds.height); 652 653 } else { 654 if (upperRightArc != 0) { 655 gp.curveTo(bds.x + bds.width - upperRightArc - 1, bds.y, 656 bds.x + bds.width - 1, bds.y, 657 bds.x + bds.width - 1, bds.y + upperRightArc); 658 } else { 659 gp.curveTo(bds.x + bds.width - upperRightArc, bds.y, 660 bds.x + bds.width, bds.y, bds.x + bds.width, 661 bds.y + upperRightArc); 662 } 663 if (bds.y + upperRightArc < bds.y + bds.height - lowerRightArc) { 664 if (upperRightArc != 0 && lowerRightArc != 0) { 665 gp.lineTo(bds.x + bds.width - 1, 666 bds.y + bds.height - lowerRightArc); 667 } else { 668 gp.lineTo(bds.x + bds.width, 669 bds.y + bds.height - lowerRightArc); 670 } 671 } 672 if (lowerRightArc != 0) { 673 gp.curveTo(bds.x + bds.width - 1, bds.y + bds.height - lowerRightArc, 674 bds.x + bds.width - 1, bds.y + bds.height, 675 bds.x + bds.width - lowerRightArc - 1, bds.y + bds.height); 676 } else { 677 gp.curveTo(bds.x + bds.width, bds.y + bds.height - lowerRightArc, 678 bds.x + bds.width, bds.y + bds.height, 679 bds.x + bds.width - lowerRightArc, bds.y + bds.height); 680 } 681 } 682 if (bds.x + bds.width - lowerRightArc > bds.x + lowerLeftArc) { 683 gp.lineTo(bds.x + lowerLeftArc, bds.y + bds.height); 684 } 685 686 if (notchLeft) { 687 gp.curveTo(bds.x + lowerLeftArc, bds.y + bds.height, bds.x, bds.y 688 + bds.height, bds.x, 689 Math.max(bds.y + bds.height - lowerLeftArc, 690 bds.y + (bds.height / 2) + notchL)); 691 if (bds.y + bds.height - lowerLeftArc 692 > bds.y + (bds.height / 2) + notchL) { 693 gp.lineTo(bds.x, bds.y + (bds.height / 2) + notchL); 694 } 695 gp.curveTo(bds.x, bds.y + (bds.height / 2) + notchL, 696 bds.x + notchL, bds.y + (bds.height / 2) + notchL, 697 bds.x + notchL, bds.y + (bds.height / 2)); 698 } else { 699 gp.curveTo(bds.x + lowerLeftArc, bds.y + bds.height, bds.x, 700 bds.y + bds.height, bds.x, 701 bds.y + bds.height - lowerLeftArc); 702 } 703 return gp; 704 } 705 706 protected Color getUpperTop() { 707 return upperTop; 708 } 709 710 protected Color getUpperBottom() { 711 return upperBottom; 712 } 713 714 protected Color getLowerTop() { 715 return lowerTop; 716 } 717 718 protected Color getLowerBottom() { 719 return lowerBottom; 720 } 721 722 723 724 725 } 726 | Popular Tags |