1 19 package org.openide.awt; 20 21 import java.awt.*; 22 import java.awt.event.MouseAdapter ; 23 import java.awt.event.MouseEvent ; 24 25 import java.beans.PropertyChangeListener ; 26 import java.beans.PropertyChangeSupport ; 27 28 import java.util.Vector ; 29 30 31 50 public class SpinButton extends Canvas { 51 52 static final long serialVersionUID = -3525959415481788776L; 53 54 59 public static final boolean DEFAULT_ORIENTATION = false; 60 61 66 public static final int DEFAULT_MINIMUM = 0; 67 68 73 public static final int DEFAULT_MAXIMUM = 100; 74 75 80 public static final int DEFAULT_STEP = 1; 81 82 87 public static final int DEFAULT_REPEAT_DELAY = 300; 88 89 94 public static final int DEFAULT_REPEAT_RATE = 70; 95 96 97 private static final boolean SPIN_UP = true; 98 99 100 private static final boolean SPIN_DOWN = false; 101 102 108 protected boolean orientation = DEFAULT_ORIENTATION; 109 110 116 protected boolean arrowsOrientation = DEFAULT_ORIENTATION; 117 118 123 protected int minimum = DEFAULT_MINIMUM; 124 125 130 protected int maximum = DEFAULT_MAXIMUM; 131 132 137 protected int step = DEFAULT_STEP; 138 139 143 protected int value = 0; 144 145 152 protected int repeatDelay = DEFAULT_REPEAT_DELAY; 153 154 160 protected int repeatRate = DEFAULT_REPEAT_RATE; 161 162 165 protected RepeatThread rt = null; 166 167 168 protected boolean running = false; 169 170 171 protected boolean repeating = true; 172 173 174 protected boolean runningDir = SPIN_DOWN; 175 protected boolean boundsIgnored = false; 176 177 178 private PropertyChangeSupport valueSupport = new PropertyChangeSupport (this); 179 180 181 private Vector <SpinButtonListener> spinButtonListeners = new Vector <SpinButtonListener>(3, 3); 182 183 184 public SpinButton() { 185 setBackground(SystemColor.control); 186 setForeground(SystemColor.controlText); 187 188 addMouseListener( 189 new MouseAdapter () { 190 public void mousePressed(MouseEvent evt) { 191 Dimension d = getSize(); 192 boolean newDir = SPIN_UP; 193 194 if (orientation) { 195 if (evt.getX() <= ((d.width - 1) / 2)) { 196 newDir = SPIN_DOWN; 197 } else { 198 newDir = SPIN_UP; 199 } 200 } else { 201 if (evt.getY() <= ((d.height - 1) / 2)) { 202 newDir = SPIN_UP; 203 } else { 204 newDir = SPIN_DOWN; 205 } 206 } 207 208 if ( 209 (((newDir == SPIN_UP) && (value >= maximum)) || ((newDir == SPIN_DOWN) && (value <= minimum))) && 210 !boundsIgnored 211 ) { 212 return; 213 } 214 215 switchRun(newDir); 216 repaint(); 217 } 218 219 public void mouseReleased(MouseEvent evt) { 220 boolean r = running; 221 switchStop(); 222 223 if (r) { 224 repaint(); 225 } 226 } 227 } 228 ); 229 } 230 231 236 public void setForeground(Color color) { 237 super.setForeground(color); 238 repaint(); 239 } 240 241 247 public void setOrientation(boolean aDir) { 248 orientation = aDir; 249 switchStop(); 250 repaint(); 251 } 252 253 259 public void setArrowsOrientation(boolean aDir) { 260 arrowsOrientation = aDir; 261 switchStop(); 262 repaint(); 263 } 264 265 271 public boolean getOrientation() { 272 return orientation; 273 } 274 275 281 public boolean getArrowsOrientation() { 282 return arrowsOrientation; 283 } 284 285 290 public void setMinimum(int aMin) { 291 minimum = aMin; 292 293 if (maximum < minimum) { 294 maximum = minimum; 295 } 296 297 if (value < minimum) { 298 setValue(value); 299 } 300 301 switchStop(); 302 repaint(); 303 } 304 305 309 public int getMinimum() { 310 return minimum; 311 } 312 313 318 public void setMaximum(int aMax) { 319 maximum = aMax; 320 321 if (maximum < minimum) { 322 minimum = maximum; 323 } 324 325 if (value > maximum) { 326 setValue(value); 327 } 328 329 switchStop(); 330 repaint(); 331 } 332 333 337 public int getMaximum() { 338 return maximum; 339 } 340 341 346 public void setValue(int aValue) { 347 int oldValue = value; 348 349 value = aValue; 350 351 if (!boundsIgnored) { 352 if (value < minimum) { 353 value = minimum; 354 } 355 356 if (value > maximum) { 357 value = maximum; 358 } 359 } 360 361 if (value != oldValue) { 362 valueSupport.firePropertyChange("value", new Integer (oldValue), new Integer (value)); } 364 365 if ((getValue() == minimum) || (getValue() == maximum) || (oldValue == minimum) || (oldValue == maximum)) { 366 repaint(); 367 } 368 } 369 370 374 public int getValue() { 375 return value; 376 } 377 378 382 public void setStep(int aStep) { 383 step = aStep; 384 switchStop(); 385 repaint(); 386 } 387 388 392 public int getStep() { 393 return step; 394 } 395 396 401 public void setDelay(int aDelay) { 402 repeatDelay = aDelay; 403 switchStop(); 404 repaint(); 405 } 406 407 412 public int getDelay() { 413 return repeatDelay; 414 } 415 416 421 public void setRate(int aRate) { 422 repeatRate = aRate; 423 switchStop(); 424 repaint(); 425 } 426 427 432 public int getRate() { 433 return repeatRate; 434 } 435 436 public boolean isBoundsIgnored() { 437 return boundsIgnored; 438 } 439 440 public void setBoundsIgnored(boolean ignored) { 441 boundsIgnored = ignored; 442 } 443 444 public boolean isRepeating() { 445 return repeating; 446 } 447 448 public void setRepeating(boolean aRepeating) { 449 repeating = aRepeating; 450 } 451 452 public void paint(Graphics g) { 453 Dimension d = getSize(); 454 455 int left = 0; 456 int top = 0; 457 int w = d.width - 1; 458 int h = d.height - 1; 459 460 g.setColor(getBackground()); 461 g.fillRect(left, top, w, h); 462 463 if (orientation) { 464 w = w / 2; 465 paintBorder(g, left, top, w, h, running && (runningDir == SPIN_DOWN), SPIN_DOWN); 466 left += (w + 1); 467 w = d.width - 1 - left; 468 paintBorder(g, left, top, w, h, running && (runningDir == SPIN_UP), SPIN_UP); 469 } else { 470 h = h / 2; 471 paintBorder(g, left, top, w, h, running && (runningDir == SPIN_UP), SPIN_UP); 472 top += (h + 1); 473 h = d.height - 1 - top; 474 paintBorder(g, left, top, w, h, running && (runningDir == SPIN_DOWN), SPIN_DOWN); 475 } 476 } 477 478 private void paintBorder(Graphics g, int x, int y, int w, int h, boolean isDown, boolean aDir) { 479 g.setColor(Color.black); 480 481 if (!isDown) { 482 g.drawLine(x, y + h, x + w, y + h); 483 g.drawLine(x + w, y, x + w, y + h); 484 } else { 485 g.drawLine(x, y, x + w, y); 486 g.drawLine(x, y, x, y + h); 487 x++; 488 y++; 489 } 490 491 w--; 492 h--; 493 g.setColor(SystemColor.controlHighlight); 494 g.draw3DRect(x, y, w, h, !isDown); 495 paintArrow(g, x, y, w, h, aDir); 496 } 497 498 private void paintArrow(Graphics g, int x, int y, int w, int h, boolean aDir) { 499 if ((w <= 0) || (h <= 0)) { 500 return; 501 } 502 503 int wd = w / 4; 504 int hd = h / 4; 505 int[] xP = new int[3]; 506 int[] yP = new int[3]; 507 508 if (arrowsOrientation) { 509 if (aDir == SPIN_UP) { 510 xP[0] = x + wd; 511 xP[2] = (x + w) - wd; 512 } else { 513 xP[0] = (x + w) - wd; 514 xP[2] = x + wd; 515 } 516 517 xP[1] = xP[0]; 518 yP[0] = y + hd; 519 yP[1] = (y + h) - hd; 520 yP[2] = y + (h / 2); 521 } else { 522 if (aDir == SPIN_UP) { 523 yP[0] = (y + h) - hd; 524 yP[2] = y + hd; 525 } else { 526 yP[0] = y + hd; 527 yP[2] = (y + h) - hd; 528 } 529 530 yP[1] = yP[0]; 531 xP[0] = x + wd; 532 xP[1] = (x + w) - wd; 533 xP[2] = x + (w / 2); 534 } 535 536 if ( 537 (((aDir == SPIN_UP) && (value >= maximum)) || ((aDir == SPIN_DOWN) && (value <= minimum))) && 538 !boundsIgnored 539 ) { 540 Color fg = getForeground(); 541 Color bg = getBackground(); 542 g.setColor( 543 new Color( 544 (fg.getRed() + (2 * bg.getRed())) / 3, (fg.getGreen() + (2 * bg.getGreen())) / 3, 545 (fg.getBlue() + (2 * bg.getBlue())) / 3 546 ) 547 ); 548 } else { 549 g.setColor(getForeground()); 550 } 551 552 g.fillPolygon(xP, yP, 3); 553 } 554 555 protected synchronized void switchRun(boolean aDirect) { 556 if (running) { 557 rt.finish = true; 558 } 559 560 rt = new RepeatThread(); 561 rt.start(); 562 runningDir = aDirect; 563 running = true; 564 } 565 566 public synchronized void switchStop() { 567 if (rt == null) { 568 return; 569 } 570 571 rt.finish = true; 572 running = false; 573 } 574 575 public Dimension getMinimumSize() { 576 return countSize(); 577 } 578 579 public Dimension getPreferredSize() { 580 return countSize(); 581 } 582 583 private Dimension countSize() { 584 int x = 11; 585 int y = x; 586 587 if (orientation) { 588 x = x + x; 589 } else { 590 y = y + y; 591 } 592 593 return new Dimension(x, y); 594 } 595 596 public void addPropertyChangeListener(PropertyChangeListener l) { 597 valueSupport.addPropertyChangeListener(l); 598 } 599 600 public void removePropertyChangeListener(PropertyChangeListener l) { 601 valueSupport.removePropertyChangeListener(l); 602 } 603 604 public void addSpinButtonListener(SpinButtonListener spinButtonListener) { 605 spinButtonListeners.addElement(spinButtonListener); 606 } 607 608 public void removeSpinButtonListener(SpinButtonListener spinButtonListener) { 609 spinButtonListeners.removeElement(spinButtonListener); 610 } 611 612 public void notifySpinButtonListenersAboutUpMove() { 613 int i; 614 int k = spinButtonListeners.size(); 615 616 for (i = 0; i < k; i++) 617 spinButtonListeners.elementAt(i).moveUp(); 618 } 619 620 public void notifySpinButtonListenersAboutDownMove() { 621 int i; 622 int k = spinButtonListeners.size(); 623 624 for (i = 0; i < k; i++) 625 spinButtonListeners.elementAt(i).moveDown(); 626 } 627 628 protected void repeatThreadNotify() { 629 int old_val = getValue(); 630 631 if (runningDir) { 632 setValue(getValue() + step); 633 634 if (value != old_val) { 635 notifySpinButtonListenersAboutUpMove(); 636 } 637 } else { 638 setValue(getValue() - step); 639 640 if (value != old_val) { 641 notifySpinButtonListenersAboutDownMove(); 642 } 643 } 644 645 if ((getValue() == old_val) && !boundsIgnored) { 646 switchStop(); 647 repaint(); 648 } 649 } 650 651 class RepeatThread extends Thread { 652 boolean finish = false; 653 654 public RepeatThread() { 655 finish = false; 656 } 657 658 public void run() { 659 repeatThreadNotify(); 660 661 try { 662 sleep(repeatDelay); 663 } catch (InterruptedException e) { 664 } 665 666 if (!repeating) { 667 return; 668 } 669 670 while (true) { 671 if (finish) { 672 break; 673 } 674 675 repeatThreadNotify(); 676 677 if (finish) { 678 break; 679 } 680 681 try { 682 sleep(repeatRate); 683 } catch (InterruptedException e) { 684 } 685 } 686 } 687 } 688 } 689 | Popular Tags |