1 7 8 package javax.swing.plaf.basic; 9 10 import com.sun.java.swing.SwingUtilities2; 11 import java.awt.*; 12 import java.awt.geom.AffineTransform ; 13 import java.awt.event.*; 14 import javax.swing.*; 15 import javax.swing.event.*; 16 import javax.swing.plaf.*; 17 import java.beans.PropertyChangeListener ; 18 import java.beans.PropertyChangeEvent ; 19 import java.io.Serializable ; 20 import sun.swing.DefaultLookup; 21 22 29 public class BasicProgressBarUI extends ProgressBarUI { 30 private int cachedPercent; 31 private int cellLength, cellSpacing; 32 private Color selectionForeground, selectionBackground; 36 37 private Animator animator; 38 39 protected JProgressBar progressBar; 40 protected ChangeListener changeListener; 41 private Handler handler; 42 43 51 private int animationIndex = 0; 52 53 59 private int numFrames; 61 68 private int repaintInterval; 69 70 77 private int cycleTime; 79 private static boolean ADJUSTTIMER = true; 84 90 protected Rectangle boxRect; 91 92 101 private Rectangle nextPaintRect; 102 103 105 private Rectangle componentInnards; private Rectangle oldComponentInnards; 108 109 private double delta = 0.0; 110 111 private int maxPosition = 0; 113 114 public static ComponentUI createUI(JComponent x) { 115 return new BasicProgressBarUI (); 116 } 117 118 public void installUI(JComponent c) { 119 progressBar = (JProgressBar)c; 120 installDefaults(); 121 installListeners(); 122 if (progressBar.isIndeterminate()) { 123 initIndeterminateValues(); 124 } 125 } 126 127 public void uninstallUI(JComponent c) { 128 if (progressBar.isIndeterminate()) { 129 cleanUpIndeterminateValues(); 130 } 131 uninstallDefaults(); 132 uninstallListeners(); 133 progressBar = null; 134 } 135 136 protected void installDefaults() { 137 LookAndFeel.installProperty(progressBar, "opaque", Boolean.TRUE); 138 LookAndFeel.installBorder(progressBar,"ProgressBar.border"); 139 LookAndFeel.installColorsAndFont(progressBar, 140 "ProgressBar.background", 141 "ProgressBar.foreground", 142 "ProgressBar.font"); 143 cellLength = UIManager.getInt("ProgressBar.cellLength"); 144 cellSpacing = UIManager.getInt("ProgressBar.cellSpacing"); 145 selectionForeground = UIManager.getColor("ProgressBar.selectionForeground"); 146 selectionBackground = UIManager.getColor("ProgressBar.selectionBackground"); 147 } 148 149 protected void uninstallDefaults() { 150 LookAndFeel.uninstallBorder(progressBar); 151 } 152 153 protected void installListeners() { 154 changeListener = getHandler(); 156 progressBar.addChangeListener(changeListener); 157 158 progressBar.addPropertyChangeListener(getHandler()); 160 } 161 162 private Handler getHandler() { 163 if (handler == null) { 164 handler = new Handler(); 165 } 166 return handler; 167 } 168 169 186 protected void startAnimationTimer() { 187 if (animator == null) { 188 animator = new Animator(); 189 } 190 191 animator.start(getRepaintInterval()); 192 } 193 194 209 protected void stopAnimationTimer() { 210 if (animator != null) { 211 animator.stop(); 212 } 213 } 214 215 218 protected void uninstallListeners() { 219 progressBar.removeChangeListener(changeListener); 220 progressBar.removePropertyChangeListener(getHandler()); 221 handler = null; 222 } 223 224 225 234 protected Dimension getPreferredInnerHorizontal() { 235 Dimension horizDim = (Dimension)DefaultLookup.get(progressBar, this, 236 "ProgressBar.horizontalSize"); 237 if (horizDim == null) { 238 horizDim = new Dimension(146, 12); 239 } 240 return horizDim; 241 } 242 243 protected Dimension getPreferredInnerVertical() { 244 Dimension vertDim = (Dimension)DefaultLookup.get(progressBar, this, 245 "ProgressBar.vertictalSize"); 246 if (vertDim == null) { 247 vertDim = new Dimension(12, 146); 248 } 249 return vertDim; 250 } 251 252 256 protected Color getSelectionForeground() { 257 return selectionForeground; 258 } 259 260 264 protected Color getSelectionBackground() { 265 return selectionBackground; 266 } 267 268 private int getCachedPercent() { 269 return cachedPercent; 270 } 271 272 private void setCachedPercent(int cachedPercent) { 273 this.cachedPercent = cachedPercent; 274 } 275 276 287 protected int getCellLength() { 288 if (progressBar.isStringPainted()) { 289 return 1; 290 } else { 291 return cellLength; 292 } 293 } 294 295 protected void setCellLength(int cellLen) { 296 this.cellLength = cellLen; 297 } 298 299 309 protected int getCellSpacing() { 310 if (progressBar.isStringPainted()) { 311 return 0; 312 } else { 313 return cellSpacing; 314 } 315 } 316 317 protected void setCellSpacing(int cellSpace) { 318 this.cellSpacing = cellSpace; 319 } 320 321 328 protected int getAmountFull(Insets b, int width, int height) { 329 int amountFull = 0; 330 BoundedRangeModel model = progressBar.getModel(); 331 332 if ( (model.getMaximum() - model.getMinimum()) != 0) { 333 if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { 334 amountFull = (int)Math.round(width * 335 progressBar.getPercentComplete()); 336 } else { 337 amountFull = (int)Math.round(height * 338 progressBar.getPercentComplete()); 339 } 340 } 341 return amountFull; 342 } 343 344 348 public void paint(Graphics g, JComponent c) { 349 if (progressBar.isIndeterminate()) { 350 paintIndeterminate(g, c); 351 } else { 352 paintDeterminate(g, c); 353 } 354 } 355 356 380 protected Rectangle getBox(Rectangle r) { 381 int currentFrame = getAnimationIndex(); 382 int middleFrame = numFrames/2; 383 384 if (sizeChanged() || delta == 0.0 || maxPosition == 0.0) { 385 updateSizes(); 386 } 387 388 r = getGenericBox(r); 389 390 if (r == null) { 391 return null; 392 } 393 if (middleFrame <= 0) { 394 return null; 395 } 396 397 if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { 399 if (currentFrame < middleFrame) { 400 r.x = componentInnards.x 401 + (int)Math.round(delta * (double)currentFrame); 402 } else { 403 r.x = maxPosition 404 - (int)Math.round(delta * 405 (currentFrame - middleFrame)); 406 } 407 } else { if (currentFrame < middleFrame) { 409 r.y = componentInnards.y 410 + (int)Math.round(delta * currentFrame); 411 } else { 412 r.y = maxPosition 413 - (int)Math.round(delta * 414 (currentFrame - middleFrame)); 415 } 416 } 417 return r; 418 } 419 420 424 private void updateSizes() { 425 int length = 0; 426 427 if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { 428 length = getBoxLength(componentInnards.width, 429 componentInnards.height); 430 maxPosition = componentInnards.x + componentInnards.width 431 - length; 432 433 } else { length = getBoxLength(componentInnards.height, 435 componentInnards.width); 436 maxPosition = componentInnards.y + componentInnards.height 437 - length; 438 } 439 440 delta = 2.0 * (double)maxPosition/(double)numFrames; 442 } 443 444 447 private Rectangle getGenericBox(Rectangle r) { 448 if (r == null) { 449 r = new Rectangle(); 450 } 451 452 if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { 453 r.width = getBoxLength(componentInnards.width, 454 componentInnards.height); 455 if (r.width < 0) { 456 r = null; 457 } else { 458 r.height = componentInnards.height; 459 r.y = componentInnards.y; 460 } 461 463 } else { r.height = getBoxLength(componentInnards.height, 465 componentInnards.width); 466 if (r.height < 0) { 467 r = null; 468 } else { 469 r.width = componentInnards.width; 470 r.x = componentInnards.x; 471 } 472 } 474 return r; 475 } 476 477 510 protected int getBoxLength(int availableLength, int otherDimension) { 511 return (int)Math.round(availableLength/6.0); 512 } 513 514 524 protected void paintIndeterminate(Graphics g, JComponent c) { 525 if (!(g instanceof Graphics2D)) { 526 return; 527 } 528 529 Insets b = progressBar.getInsets(); int barRectWidth = progressBar.getWidth() - (b.right + b.left); 531 int barRectHeight = progressBar.getHeight() - (b.top + b.bottom); 532 533 Graphics2D g2 = (Graphics2D)g; 534 535 boxRect = getBox(boxRect); 537 if (boxRect != null) { 538 g2.setColor(progressBar.getForeground()); 539 g2.fillRect(boxRect.x, boxRect.y, 540 boxRect.width, boxRect.height); 541 } 542 543 if (progressBar.isStringPainted()) { 545 if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { 546 paintString(g2, b.left, b.top, 547 barRectWidth, barRectHeight, 548 boxRect.x, boxRect.width, b); 549 } 550 else { 551 paintString(g2, b.left, b.top, 552 barRectWidth, barRectHeight, 553 boxRect.y, boxRect.height, b); 554 } 555 } 556 } 557 558 559 571 protected void paintDeterminate(Graphics g, JComponent c) { 572 if (!(g instanceof Graphics2D)) { 573 return; 574 } 575 576 Insets b = progressBar.getInsets(); int barRectWidth = progressBar.getWidth() - (b.right + b.left); 578 int barRectHeight = progressBar.getHeight() - (b.top + b.bottom); 579 580 int cellLength = getCellLength(); 581 int cellSpacing = getCellSpacing(); 582 int amountFull = getAmountFull(b, barRectWidth, barRectHeight); 584 585 Graphics2D g2 = (Graphics2D)g; 586 g2.setColor(progressBar.getForeground()); 587 588 if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { 589 if (cellSpacing == 0 && amountFull > 0) { 591 g2.setStroke(new BasicStroke((float)barRectHeight, 593 BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); 594 } else { 595 g2.setStroke(new BasicStroke((float)barRectHeight, 597 BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 598 0.f, new float[] { cellLength, cellSpacing }, 0.f)); 599 } 600 601 if (BasicGraphicsUtils.isLeftToRight(c)) { 602 g2.drawLine(b.left, (barRectHeight/2) + b.top, 603 amountFull + b.left, (barRectHeight/2) + b.top); 604 } else { 605 g2.drawLine((barRectWidth + b.left), 606 (barRectHeight/2) + b.top, 607 barRectWidth + b.left - amountFull, 608 (barRectHeight/2) + b.top); 609 } 610 611 } else { if (cellSpacing == 0 && amountFull > 0) { 614 g2.setStroke(new BasicStroke((float)barRectWidth, 616 BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); 617 } else { 618 g2.setStroke(new BasicStroke((float)barRectWidth, 620 BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 621 0f, new float[] { cellLength, cellSpacing }, 0f)); 622 } 623 624 g2.drawLine(barRectWidth/2 + b.left, 625 b.top + barRectHeight, 626 barRectWidth/2 + b.left, 627 b.top + barRectHeight - amountFull); 628 } 629 630 if (progressBar.isStringPainted()) { 632 paintString(g, b.left, b.top, 633 barRectWidth, barRectHeight, 634 amountFull, b); 635 } 636 } 637 638 639 protected void paintString(Graphics g, int x, int y, 640 int width, int height, 641 int amountFull, Insets b) { 642 if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { 643 if (BasicGraphicsUtils.isLeftToRight(progressBar)) { 644 if (progressBar.isIndeterminate()) { 645 boxRect = getBox(boxRect); 646 paintString(g, x, y, width, height, 647 boxRect.x, boxRect.width, b); 648 } else { 649 paintString(g, x, y, width, height, x, amountFull, b); 650 } 651 } 652 else { 653 paintString(g, x, y, width, height, x + width - amountFull, 654 amountFull, b); 655 } 656 } 657 else { 658 if (progressBar.isIndeterminate()) { 659 boxRect = getBox(boxRect); 660 paintString(g, x, y, width, height, 661 boxRect.y, boxRect.height, b); 662 } else { 663 paintString(g, x, y, width, height, y + height - amountFull, 664 amountFull, b); 665 } 666 } 667 } 668 669 683 private void paintString(Graphics g, int x, int y, int width, int height, 684 int fillStart, int amountFull, Insets b) { 685 if (!(g instanceof Graphics2D)) { 686 return; 687 } 688 689 Graphics2D g2 = (Graphics2D)g; 690 String progressString = progressBar.getString(); 691 g2.setFont(progressBar.getFont()); 692 Point renderLocation = getStringPlacement(g2, progressString, 693 x, y, width, height); 694 Rectangle oldClip = g2.getClipBounds(); 695 696 if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { 697 g2.setColor(getSelectionBackground()); 698 SwingUtilities2.drawString(progressBar, g2, progressString, 699 renderLocation.x, renderLocation.y); 700 g2.setColor(getSelectionForeground()); 701 g2.clipRect(fillStart, y, amountFull, height); 702 SwingUtilities2.drawString(progressBar, g2, progressString, 703 renderLocation.x, renderLocation.y); 704 } else { g2.setColor(getSelectionBackground()); 706 AffineTransform rotate = 707 AffineTransform.getRotateInstance(Math.PI/2); 708 g2.setFont(progressBar.getFont().deriveFont(rotate)); 709 renderLocation = getStringPlacement(g2, progressString, 710 x, y, width, height); 711 SwingUtilities2.drawString(progressBar, g2, progressString, 712 renderLocation.x, renderLocation.y); 713 g2.setColor(getSelectionForeground()); 714 g2.clipRect(x, fillStart, width, amountFull); 715 SwingUtilities2.drawString(progressBar, g2, progressString, 716 renderLocation.x, renderLocation.y); 717 } 718 g2.setClip(oldClip); 719 } 720 721 722 729 protected Point getStringPlacement(Graphics g, String progressString, 730 int x,int y,int width,int height) { 731 FontMetrics fontSizer = SwingUtilities2.getFontMetrics(progressBar, g, 732 progressBar.getFont()); 733 int stringWidth = SwingUtilities2.stringWidth(progressBar, fontSizer, 734 progressString); 735 736 if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { 737 return new Point(x + Math.round(width/2 - stringWidth/2), 738 y + ((height + 739 fontSizer.getAscent() - 740 fontSizer.getLeading() - 741 fontSizer.getDescent()) / 2)); 742 } else { return new Point(x + ((width - fontSizer.getAscent() + 744 fontSizer.getLeading() + fontSizer.getDescent()) / 2), 745 y + Math.round(height/2 - stringWidth/2)); 746 } 747 } 748 749 750 public Dimension getPreferredSize(JComponent c) { 751 Dimension size; 752 Insets border = progressBar.getInsets(); 753 FontMetrics fontSizer = progressBar.getFontMetrics( 754 progressBar.getFont()); 755 756 if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { 757 size = new Dimension(getPreferredInnerHorizontal()); 758 if (progressBar.isStringPainted()) { 760 String progString = progressBar.getString(); 762 int stringWidth = SwingUtilities2.stringWidth( 763 progressBar, fontSizer, progString); 764 if (stringWidth > size.width) { 765 size.width = stringWidth; 766 } 767 int stringHeight = fontSizer.getHeight() + 773 fontSizer.getDescent(); 774 if (stringHeight > size.height) { 775 size.height = stringHeight; 776 } 777 } 778 } else { 779 size = new Dimension(getPreferredInnerVertical()); 780 if (progressBar.isStringPainted()) { 782 String progString = progressBar.getString(); 783 int stringHeight = fontSizer.getHeight() + 784 fontSizer.getDescent(); 785 if (stringHeight > size.width) { 786 size.width = stringHeight; 787 } 788 int stringWidth = SwingUtilities2.stringWidth( 790 progressBar, fontSizer, progString); 791 if (stringWidth > size.height) { 792 size.height = stringWidth; 793 } 794 } 795 } 796 797 size.width += border.left + border.right; 798 size.height += border.top + border.bottom; 799 return size; 800 } 801 802 806 public Dimension getMinimumSize(JComponent c) { 807 Dimension pref = getPreferredSize(progressBar); 808 if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { 809 pref.width = 10; 810 } else { 811 pref.height = 10; 812 } 813 return pref; 814 } 815 816 public Dimension getMaximumSize(JComponent c) { 817 Dimension pref = getPreferredSize(progressBar); 818 if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) { 819 pref.width = Short.MAX_VALUE; 820 } else { 821 pref.height = Short.MAX_VALUE; 822 } 823 return pref; 824 } 825 826 831 protected int getAnimationIndex() { 832 return animationIndex; 833 } 834 835 850 protected void setAnimationIndex(int newValue) { 851 if (animationIndex != newValue) { 852 if (sizeChanged()) { 853 animationIndex = newValue; 854 maxPosition = 0; delta = 0.0; progressBar.repaint(); 857 return; 858 } 859 860 nextPaintRect = getBox(nextPaintRect); 862 863 animationIndex = newValue; 865 866 if (nextPaintRect != null) { 868 boxRect = getBox(boxRect); 869 if (boxRect != null) { 870 nextPaintRect.add(boxRect); 871 } 872 } 873 } else { return; 875 } 876 877 if (nextPaintRect != null) { 878 progressBar.repaint(nextPaintRect); 879 } else { 880 progressBar.repaint(); 881 } 882 } 883 884 private boolean sizeChanged() { 885 if ((oldComponentInnards == null) || (componentInnards == null)) { 886 return true; 887 } 888 889 oldComponentInnards.setRect(componentInnards); 890 componentInnards = SwingUtilities.calculateInnerArea(progressBar, 891 componentInnards); 892 return !oldComponentInnards.equals(componentInnards); 893 } 894 895 915 protected void incrementAnimationIndex() { 916 int newValue = getAnimationIndex() + 1; 917 918 if (newValue < numFrames) { 919 setAnimationIndex(newValue); 920 } else { 921 setAnimationIndex(0); 922 } 923 } 924 925 939 private int getRepaintInterval() { 940 return repaintInterval; 941 } 942 943 private int initRepaintInterval() { 944 repaintInterval = DefaultLookup.getInt(progressBar, 945 this, "ProgressBar.repaintInterval", 50); 946 return repaintInterval; 947 } 948 949 963 private int getCycleTime() { 964 return cycleTime; 965 } 966 967 private int initCycleTime() { 968 cycleTime = DefaultLookup.getInt(progressBar, this, 969 "ProgressBar.cycleTime", 3000); 970 return cycleTime; 971 } 972 973 974 975 private void initIndeterminateDefaults() { 976 initRepaintInterval(); initCycleTime(); 979 if (repaintInterval <= 0) { 981 repaintInterval = 100; 982 } 983 984 if (repaintInterval > cycleTime) { 986 cycleTime = repaintInterval * 20; 987 } else { 988 int factor = (int)Math.ceil( 990 ((double)cycleTime) 991 / ((double)repaintInterval*2)); 992 cycleTime = repaintInterval*factor*2; 993 } 994 } 995 996 1002 private void initIndeterminateValues() { 1003 initIndeterminateDefaults(); 1004 numFrames = cycleTime/repaintInterval; 1006 initAnimationIndex(); 1007 1008 boxRect = new Rectangle(); 1009 nextPaintRect = new Rectangle(); 1010 componentInnards = new Rectangle(); 1011 oldComponentInnards = new Rectangle(); 1012 1013 progressBar.addHierarchyListener(getHandler()); 1016 1017 if (progressBar.isDisplayable()) { 1019 startAnimationTimer(); 1020 } 1021 } 1022 1023 1024 private void cleanUpIndeterminateValues() { 1025 if (progressBar.isDisplayable()) { 1027 stopAnimationTimer(); 1028 } 1029 1030 cycleTime = repaintInterval = 0; 1031 numFrames = animationIndex = 0; 1032 maxPosition = 0; 1033 delta = 0.0; 1034 1035 boxRect = nextPaintRect = null; 1036 componentInnards = oldComponentInnards = null; 1037 1038 progressBar.removeHierarchyListener(getHandler()); 1039 } 1040 1041 private void initAnimationIndex() { 1044 if ((progressBar.getOrientation() == JProgressBar.HORIZONTAL) && 1045 (BasicGraphicsUtils.isLeftToRight(progressBar))) { 1046 setAnimationIndex(0); 1049 } else { 1050 setAnimationIndex(numFrames/2); 1052 } 1053 } 1054 1055 1065 private class Animator implements ActionListener { 1066 private Timer timer; 1067 private long previousDelay; private int interval; private long lastCall; private int MINIMUM_DELAY = 5; 1071 1072 1076 private void start(int interval) { 1077 previousDelay = interval; 1078 lastCall = 0; 1079 1080 if (timer == null) { 1081 timer = new Timer(interval, this); 1082 } else { 1083 timer.setDelay(interval); 1084 } 1085 1086 if (ADJUSTTIMER) { 1087 timer.setRepeats(false); 1088 timer.setCoalesce(false); 1089 } 1090 1091 timer.start(); 1092 } 1093 1094 1097 private void stop() { 1098 timer.stop(); 1099 } 1100 1101 1104 public void actionPerformed(ActionEvent e) { 1105 if (ADJUSTTIMER) { 1106 long time = System.currentTimeMillis(); 1107 1108 if (lastCall > 0) { int nextDelay = (int)(previousDelay 1115 - time + lastCall 1116 + getRepaintInterval()); 1117 if (nextDelay < MINIMUM_DELAY) { 1118 nextDelay = MINIMUM_DELAY; 1119 } 1120 timer.setInitialDelay(nextDelay); 1121 previousDelay = nextDelay; 1122 } 1123 timer.start(); 1124 lastCall = time; 1125 } 1126 1127 incrementAnimationIndex(); } 1129 } 1130 1131 1132 1137 public class ChangeHandler implements ChangeListener { 1138 public void stateChanged(ChangeEvent e) { 1143 getHandler().stateChanged(e); 1144 } 1145 } 1146 1147 1148 private class Handler implements ChangeListener , PropertyChangeListener , HierarchyListener { 1149 public void stateChanged(ChangeEvent e) { 1151 BoundedRangeModel model = progressBar.getModel(); 1152 int newRange = model.getMaximum() - model.getMinimum(); 1153 int newPercent; 1154 int oldPercent = getCachedPercent(); 1155 1156 if (newRange > 0) { 1157 newPercent = (int)((100 * (long)model.getValue()) / newRange); 1158 } else { 1159 newPercent = 0; 1160 } 1161 1162 if (newPercent != oldPercent) { 1163 setCachedPercent(newPercent); 1164 progressBar.repaint(); 1165 } 1166 } 1167 1168 public void propertyChange(PropertyChangeEvent e) { 1170 String prop = e.getPropertyName(); 1171 if ("indeterminate" == prop) { 1172 if (progressBar.isIndeterminate()) { 1173 initIndeterminateValues(); 1174 } else { 1175 cleanUpIndeterminateValues(); 1177 } 1178 progressBar.repaint(); 1179 } 1180 } 1181 1182 public void hierarchyChanged(HierarchyEvent he) { 1184 if ((he.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) { 1185 if (progressBar.isIndeterminate()) { 1186 if (progressBar.isDisplayable()) { 1187 startAnimationTimer(); 1188 } else { 1189 stopAnimationTimer(); 1190 } 1191 } 1192 } 1193 } 1194 } 1195} 1196 | Popular Tags |