BasicProgressBarUIpublic class BasicProgressBarUI extends ProgressBarUI A Basic L&F implementation of ProgressBarUI. |
Fields Summary |
---|
private int | cachedPercent | private int | cellLength | private int | cellSpacing | private Color | selectionForeground | private Color | selectionBackground | private Animator | animator | protected JProgressBar | progressBar | protected ChangeListener | changeListener | private Handler | handler | private int | animationIndexThe current state of the indeterminate animation's cycle.
0, the initial value, means paint the first frame.
When the progress bar is indeterminate and showing,
the default animation thread updates this variable
by invoking incrementAnimationIndex()
every repaintInterval milliseconds. | private int | numFramesThe number of frames per cycle. Under the default implementation,
this depends on the cycleTime and repaintInterval. It
must be an even number for the default painting algorithm. This
value is set in the initIndeterminateValues method. | private int | repaintIntervalInterval (in ms) between repaints of the indeterminate progress bar.
The value of this method is set
(every time the progress bar changes to indeterminate mode)
using the
"ProgressBar.repaintInterval" key in the defaults table. | private int | cycleTimeThe number of milliseconds until the animation cycle repeats.
The value of this method is set
(every time the progress bar changes to indeterminate mode)
using the
"ProgressBar.cycleTime" key in the defaults table. | private static boolean | ADJUSTTIMER | protected Rectangle | boxRectUsed to hold the location and size of the bouncing box (returned
by getBox) to be painted. | private Rectangle | nextPaintRectThe rectangle to be updated the next time the
animation thread calls repaint. For bouncing-box
animation this rect should include the union of
the currently displayed box (which needs to be erased)
and the box to be displayed next.
This rectangle's values are set in
the setAnimationIndex method. | private Rectangle | componentInnardsThe component's painting area, not including the border. | private Rectangle | oldComponentInnards | private double | deltaFor bouncing-box animation, the change in position per frame. | private int | maxPosition |
Methods Summary |
---|
private void | cleanUpIndeterminateValues()Invoked by PropertyChangeHandler.
// stop the animation thread if necessary
if (progressBar.isDisplayable()) {
stopAnimationTimer();
}
cycleTime = repaintInterval = 0;
numFrames = animationIndex = 0;
maxPosition = 0;
delta = 0.0;
boxRect = nextPaintRect = null;
componentInnards = oldComponentInnards = null;
progressBar.removeHierarchyListener(getHandler());
| public static javax.swing.plaf.ComponentUI | createUI(javax.swing.JComponent x) //maximum X (horiz) or Y box location
return new BasicProgressBarUI();
| protected int | getAmountFull(java.awt.Insets b, int width, int height)This determines the amount of the progress bar that should be filled
based on the percent done gathered from the model. This is a common
operation so it was abstracted out. It assumes that your progress bar
is linear. That is, if you are making a circular progress indicator,
you will want to override this method.
int amountFull = 0;
BoundedRangeModel model = progressBar.getModel();
if ( (model.getMaximum() - model.getMinimum()) != 0) {
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
amountFull = (int)Math.round(width *
progressBar.getPercentComplete());
} else {
amountFull = (int)Math.round(height *
progressBar.getPercentComplete());
}
}
return amountFull;
| protected int | getAnimationIndex()Gets the index of the current animation frame.
return animationIndex;
| protected java.awt.Rectangle | getBox(java.awt.Rectangle r)Stores the position and size of
the bouncing box that would be painted for the current animation index
in r and returns r .
Subclasses that add to the painting performed
in this class's implementation of paintIndeterminate --
to draw an outline around the bouncing box, for example --
can use this method to get the location of the bouncing
box that was just painted.
By overriding this method,
you have complete control over the size and position
of the bouncing box,
without having to reimplement paintIndeterminate .
int currentFrame = getAnimationIndex();
int middleFrame = numFrames/2;
if (sizeChanged() || delta == 0.0 || maxPosition == 0.0) {
updateSizes();
}
r = getGenericBox(r);
if (r == null) {
return null;
}
if (middleFrame <= 0) {
return null;
}
//assert currentFrame >= 0 && currentFrame < numFrames
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
if (currentFrame < middleFrame) {
r.x = componentInnards.x
+ (int)Math.round(delta * (double)currentFrame);
} else {
r.x = maxPosition
- (int)Math.round(delta *
(currentFrame - middleFrame));
}
} else { //VERTICAL indeterminate progress bar
if (currentFrame < middleFrame) {
r.y = componentInnards.y
+ (int)Math.round(delta * currentFrame);
} else {
r.y = maxPosition
- (int)Math.round(delta *
(currentFrame - middleFrame));
}
}
return r;
| protected int | getBoxLength(int availableLength, int otherDimension)Returns the length
of the "bouncing box" to be painted.
This method is invoked by the
default implementation of paintIndeterminate
to get the width (if the progress bar is horizontal)
or height (if vertical) of the box.
For example:
boxRect.width = getBoxLength(componentInnards.width,
componentInnards.height);
return (int)Math.round(availableLength/6.0);
| private int | getCachedPercent()
return cachedPercent;
| protected int | getCellLength()Returns the width (if HORIZONTAL) or height (if VERTICAL)
of each of the indivdual cells/units to be rendered in the
progress bar. However, for text rendering simplification and
aesthetic considerations, this function will return 1 when
the progress string is being rendered.
if (progressBar.isStringPainted()) {
return 1;
} else {
return cellLength;
}
| protected int | getCellSpacing()Returns the spacing between each of the cells/units in the
progress bar. However, for text rendering simplification and
aesthetic considerations, this function will return 0 when
the progress string is being rendered.
if (progressBar.isStringPainted()) {
return 0;
} else {
return cellSpacing;
}
| private int | getCycleTime()Returns the number of milliseconds per animation cycle.
This value is meaningful
only if the progress bar is in indeterminate mode.
The cycle time is used by the default indeterminate progress bar
painting code when determining
how far to move the bouncing box per frame.
The cycle time is specified by
the "ProgressBar.cycleTime" UI default
and adjusted, if necessary,
by the initIndeterminateDefaults method.
return cycleTime;
| private java.awt.Rectangle | getGenericBox(java.awt.Rectangle r)Assumes that the component innards, max position, etc. are up-to-date.
if (r == null) {
r = new Rectangle();
}
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
r.width = getBoxLength(componentInnards.width,
componentInnards.height);
if (r.width < 0) {
r = null;
} else {
r.height = componentInnards.height;
r.y = componentInnards.y;
}
// end of HORIZONTAL
} else { //VERTICAL progress bar
r.height = getBoxLength(componentInnards.height,
componentInnards.width);
if (r.height < 0) {
r = null;
} else {
r.width = componentInnards.width;
r.x = componentInnards.x;
}
} // end of VERTICAL
return r;
| private javax.swing.plaf.basic.BasicProgressBarUI$Handler | getHandler()
if (handler == null) {
handler = new Handler();
}
return handler;
| public java.awt.Dimension | getMaximumSize(javax.swing.JComponent c)
Dimension pref = getPreferredSize(progressBar);
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
pref.width = Short.MAX_VALUE;
} else {
pref.height = Short.MAX_VALUE;
}
return pref;
| public java.awt.Dimension | getMinimumSize(javax.swing.JComponent c)The Minimum size for this component is 10. The rationale here
is that there should be at least one pixel per 10 percent.
Dimension pref = getPreferredSize(progressBar);
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
pref.width = 10;
} else {
pref.height = 10;
}
return pref;
| protected java.awt.Dimension | getPreferredInnerHorizontal()
Dimension horizDim = (Dimension)DefaultLookup.get(progressBar, this,
"ProgressBar.horizontalSize");
if (horizDim == null) {
horizDim = new Dimension(146, 12);
}
return horizDim;
| protected java.awt.Dimension | getPreferredInnerVertical()
Dimension vertDim = (Dimension)DefaultLookup.get(progressBar, this,
"ProgressBar.vertictalSize");
if (vertDim == null) {
vertDim = new Dimension(12, 146);
}
return vertDim;
| public java.awt.Dimension | getPreferredSize(javax.swing.JComponent c)
Dimension size;
Insets border = progressBar.getInsets();
FontMetrics fontSizer = progressBar.getFontMetrics(
progressBar.getFont());
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
size = new Dimension(getPreferredInnerHorizontal());
// Ensure that the progress string will fit
if (progressBar.isStringPainted()) {
// I'm doing this for completeness.
String progString = progressBar.getString();
int stringWidth = SwingUtilities2.stringWidth(
progressBar, fontSizer, progString);
if (stringWidth > size.width) {
size.width = stringWidth;
}
// This uses both Height and Descent to be sure that
// there is more than enough room in the progress bar
// for everything.
// This does have a strange dependency on
// getStringPlacememnt() in a funny way.
int stringHeight = fontSizer.getHeight() +
fontSizer.getDescent();
if (stringHeight > size.height) {
size.height = stringHeight;
}
}
} else {
size = new Dimension(getPreferredInnerVertical());
// Ensure that the progress string will fit.
if (progressBar.isStringPainted()) {
String progString = progressBar.getString();
int stringHeight = fontSizer.getHeight() +
fontSizer.getDescent();
if (stringHeight > size.width) {
size.width = stringHeight;
}
// This is also for completeness.
int stringWidth = SwingUtilities2.stringWidth(
progressBar, fontSizer, progString);
if (stringWidth > size.height) {
size.height = stringWidth;
}
}
}
size.width += border.left + border.right;
size.height += border.top + border.bottom;
return size;
| private int | getRepaintInterval()Returns the desired number of milliseconds between repaints.
This value is meaningful
only if the progress bar is in indeterminate mode.
The repaint interval determines how often the
default animation thread's timer is fired.
It's also used by the default indeterminate progress bar
painting code when determining
how far to move the bouncing box per frame.
The repaint interval is specified by
the "ProgressBar.repaintInterval" UI default.
return repaintInterval;
| protected java.awt.Color | getSelectionBackground()The "selectionBackground" is the color of the text when it is painted
over an unfilled area of the progress bar.
return selectionBackground;
| protected java.awt.Color | getSelectionForeground()The "selectionForeground" is the color of the text when it is painted
over a filled area of the progress bar.
return selectionForeground;
| protected java.awt.Point | getStringPlacement(java.awt.Graphics g, java.lang.String progressString, int x, int y, int width, int height)Designate the place where the progress string will be painted.
This implementation places it at the center of the progress
bar (in both x and y). Override this if you want to right,
left, top, or bottom align the progress string or if you need
to nudge it around for any reason.
FontMetrics fontSizer = SwingUtilities2.getFontMetrics(progressBar, g,
progressBar.getFont());
int stringWidth = SwingUtilities2.stringWidth(progressBar, fontSizer,
progressString);
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
return new Point(x + Math.round(width/2 - stringWidth/2),
y + ((height +
fontSizer.getAscent() -
fontSizer.getLeading() -
fontSizer.getDescent()) / 2));
} else { // VERTICAL
return new Point(x + ((width - fontSizer.getAscent() +
fontSizer.getLeading() + fontSizer.getDescent()) / 2),
y + Math.round(height/2 - stringWidth/2));
}
| protected void | incrementAnimationIndex()Sets the index of the current animation frame,
to the next valid value,
which results in the progress bar being repainted.
The next valid value is, by default,
the current animation index plus one.
If the new value would be too large,
this method sets the index to 0.
Subclasses might need to override this method
to ensure that the index does not go over
the number of frames needed for the particular
progress bar instance.
This method is invoked by the default animation thread
every X milliseconds,
where X is specified by the "ProgressBar.repaintInterval"
UI default.
int newValue = getAnimationIndex() + 1;
if (newValue < numFrames) {
setAnimationIndex(newValue);
} else {
setAnimationIndex(0);
}
| private void | initAnimationIndex()
if ((progressBar.getOrientation() == JProgressBar.HORIZONTAL) &&
(BasicGraphicsUtils.isLeftToRight(progressBar))) {
// If this is a left-to-right progress bar,
// start at the first frame.
setAnimationIndex(0);
} else {
// If we go right-to-left or vertically, start at the right/bottom.
setAnimationIndex(numFrames/2);
}
| private int | initCycleTime()
cycleTime = DefaultLookup.getInt(progressBar, this,
"ProgressBar.cycleTime", 3000);
return cycleTime;
| private void | initIndeterminateDefaults()Initialize cycleTime, repaintInterval, numFrames, animationIndex.
initRepaintInterval(); //initialize repaint interval
initCycleTime(); //initialize cycle length
// Make sure repaintInterval is reasonable.
if (repaintInterval <= 0) {
repaintInterval = 100;
}
// Make sure cycleTime is reasonable.
if (repaintInterval > cycleTime) {
cycleTime = repaintInterval * 20;
} else {
// Force cycleTime to be a even multiple of repaintInterval.
int factor = (int)Math.ceil(
((double)cycleTime)
/ ((double)repaintInterval*2));
cycleTime = repaintInterval*factor*2;
}
| private void | initIndeterminateValues()Invoked by PropertyChangeHandler.
NOTE: This might not be invoked until after the first
paintIndeterminate call.
initIndeterminateDefaults();
//assert cycleTime/repaintInterval is a whole multiple of 2.
numFrames = cycleTime/repaintInterval;
initAnimationIndex();
boxRect = new Rectangle();
nextPaintRect = new Rectangle();
componentInnards = new Rectangle();
oldComponentInnards = new Rectangle();
// we only bother installing the HierarchyChangeListener if we
// are indeterminate
progressBar.addHierarchyListener(getHandler());
// start the animation thread if necessary
if (progressBar.isDisplayable()) {
startAnimationTimer();
}
| private int | initRepaintInterval()
repaintInterval = DefaultLookup.getInt(progressBar,
this, "ProgressBar.repaintInterval", 50);
return repaintInterval;
| protected void | installDefaults()
LookAndFeel.installProperty(progressBar, "opaque", Boolean.TRUE);
LookAndFeel.installBorder(progressBar,"ProgressBar.border");
LookAndFeel.installColorsAndFont(progressBar,
"ProgressBar.background",
"ProgressBar.foreground",
"ProgressBar.font");
cellLength = UIManager.getInt("ProgressBar.cellLength");
cellSpacing = UIManager.getInt("ProgressBar.cellSpacing");
selectionForeground = UIManager.getColor("ProgressBar.selectionForeground");
selectionBackground = UIManager.getColor("ProgressBar.selectionBackground");
| protected void | installListeners()
//Listen for changes in the progress bar's data.
changeListener = getHandler();
progressBar.addChangeListener(changeListener);
//Listen for changes between determinate and indeterminate state.
progressBar.addPropertyChangeListener(getHandler());
| public void | installUI(javax.swing.JComponent c)
progressBar = (JProgressBar)c;
installDefaults();
installListeners();
if (progressBar.isIndeterminate()) {
initIndeterminateValues();
}
| public void | paint(java.awt.Graphics g, javax.swing.JComponent c)Delegates painting to one of two methods:
paintDeterminate or paintIndeterminate.
if (progressBar.isIndeterminate()) {
paintIndeterminate(g, c);
} else {
paintDeterminate(g, c);
}
| protected void | paintDeterminate(java.awt.Graphics g, javax.swing.JComponent c)All purpose paint method that should do the right thing for almost
all linear, determinate progress bars. By setting a few values in
the defaults
table, things should work just fine to paint your progress bar.
Naturally, override this if you are making a circular or
semi-circular progress bar.
if (!(g instanceof Graphics2D)) {
return;
}
Insets b = progressBar.getInsets(); // area for border
int barRectWidth = progressBar.getWidth() - (b.right + b.left);
int barRectHeight = progressBar.getHeight() - (b.top + b.bottom);
int cellLength = getCellLength();
int cellSpacing = getCellSpacing();
// amount of progress to draw
int amountFull = getAmountFull(b, barRectWidth, barRectHeight);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(progressBar.getForeground());
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
// draw the cells
if (cellSpacing == 0 && amountFull > 0) {
// draw one big Rect because there is no space between cells
g2.setStroke(new BasicStroke((float)barRectHeight,
BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
} else {
// draw each individual cell
g2.setStroke(new BasicStroke((float)barRectHeight,
BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL,
0.f, new float[] { cellLength, cellSpacing }, 0.f));
}
if (BasicGraphicsUtils.isLeftToRight(c)) {
g2.drawLine(b.left, (barRectHeight/2) + b.top,
amountFull + b.left, (barRectHeight/2) + b.top);
} else {
g2.drawLine((barRectWidth + b.left),
(barRectHeight/2) + b.top,
barRectWidth + b.left - amountFull,
(barRectHeight/2) + b.top);
}
} else { // VERTICAL
// draw the cells
if (cellSpacing == 0 && amountFull > 0) {
// draw one big Rect because there is no space between cells
g2.setStroke(new BasicStroke((float)barRectWidth,
BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
} else {
// draw each individual cell
g2.setStroke(new BasicStroke((float)barRectWidth,
BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL,
0f, new float[] { cellLength, cellSpacing }, 0f));
}
g2.drawLine(barRectWidth/2 + b.left,
b.top + barRectHeight,
barRectWidth/2 + b.left,
b.top + barRectHeight - amountFull);
}
// Deal with possible text painting
if (progressBar.isStringPainted()) {
paintString(g, b.left, b.top,
barRectWidth, barRectHeight,
amountFull, b);
}
| protected void | paintIndeterminate(java.awt.Graphics g, javax.swing.JComponent c)All purpose paint method that should do the right thing for all
linear bouncing-box progress bars.
Override this if you are making another kind of
progress bar.
if (!(g instanceof Graphics2D)) {
return;
}
Insets b = progressBar.getInsets(); // area for border
int barRectWidth = progressBar.getWidth() - (b.right + b.left);
int barRectHeight = progressBar.getHeight() - (b.top + b.bottom);
Graphics2D g2 = (Graphics2D)g;
// Paint the bouncing box.
boxRect = getBox(boxRect);
if (boxRect != null) {
g2.setColor(progressBar.getForeground());
g2.fillRect(boxRect.x, boxRect.y,
boxRect.width, boxRect.height);
}
// Deal with possible text painting
if (progressBar.isStringPainted()) {
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
paintString(g2, b.left, b.top,
barRectWidth, barRectHeight,
boxRect.x, boxRect.width, b);
}
else {
paintString(g2, b.left, b.top,
barRectWidth, barRectHeight,
boxRect.y, boxRect.height, b);
}
}
| protected void | paintString(java.awt.Graphics g, int x, int y, int width, int height, int amountFull, java.awt.Insets b)
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
if (BasicGraphicsUtils.isLeftToRight(progressBar)) {
if (progressBar.isIndeterminate()) {
boxRect = getBox(boxRect);
paintString(g, x, y, width, height,
boxRect.x, boxRect.width, b);
} else {
paintString(g, x, y, width, height, x, amountFull, b);
}
}
else {
paintString(g, x, y, width, height, x + width - amountFull,
amountFull, b);
}
}
else {
if (progressBar.isIndeterminate()) {
boxRect = getBox(boxRect);
paintString(g, x, y, width, height,
boxRect.y, boxRect.height, b);
} else {
paintString(g, x, y, width, height, y + height - amountFull,
amountFull, b);
}
}
| private void | paintString(java.awt.Graphics g, int x, int y, int width, int height, int fillStart, int amountFull, java.awt.Insets b)Paints the progress string.
if (!(g instanceof Graphics2D)) {
return;
}
Graphics2D g2 = (Graphics2D)g;
String progressString = progressBar.getString();
g2.setFont(progressBar.getFont());
Point renderLocation = getStringPlacement(g2, progressString,
x, y, width, height);
Rectangle oldClip = g2.getClipBounds();
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
g2.setColor(getSelectionBackground());
SwingUtilities2.drawString(progressBar, g2, progressString,
renderLocation.x, renderLocation.y);
g2.setColor(getSelectionForeground());
g2.clipRect(fillStart, y, amountFull, height);
SwingUtilities2.drawString(progressBar, g2, progressString,
renderLocation.x, renderLocation.y);
} else { // VERTICAL
g2.setColor(getSelectionBackground());
AffineTransform rotate =
AffineTransform.getRotateInstance(Math.PI/2);
g2.setFont(progressBar.getFont().deriveFont(rotate));
renderLocation = getStringPlacement(g2, progressString,
x, y, width, height);
SwingUtilities2.drawString(progressBar, g2, progressString,
renderLocation.x, renderLocation.y);
g2.setColor(getSelectionForeground());
g2.clipRect(x, fillStart, width, amountFull);
SwingUtilities2.drawString(progressBar, g2, progressString,
renderLocation.x, renderLocation.y);
}
g2.setClip(oldClip);
| protected void | setAnimationIndex(int newValue)Sets the index of the current animation frame
to the specified value and requests that the
progress bar be repainted.
Subclasses that don't use the default painting code
might need to override this method
to change the way that the repaint method
is invoked.
if (animationIndex != newValue) {
if (sizeChanged()) {
animationIndex = newValue;
maxPosition = 0; //needs to be recalculated
delta = 0.0; //needs to be recalculated
progressBar.repaint();
return;
}
//Get the previous box drawn.
nextPaintRect = getBox(nextPaintRect);
//Update the frame number.
animationIndex = newValue;
//Get the next box to draw.
if (nextPaintRect != null) {
boxRect = getBox(boxRect);
if (boxRect != null) {
nextPaintRect.add(boxRect);
}
}
} else { //animationIndex == newValue
return;
}
if (nextPaintRect != null) {
progressBar.repaint(nextPaintRect);
} else {
progressBar.repaint();
}
| private void | setCachedPercent(int cachedPercent)
this.cachedPercent = cachedPercent;
| protected void | setCellLength(int cellLen)
this.cellLength = cellLen;
| protected void | setCellSpacing(int cellSpace)
this.cellSpacing = cellSpace;
| private boolean | sizeChanged()
if ((oldComponentInnards == null) || (componentInnards == null)) {
return true;
}
oldComponentInnards.setRect(componentInnards);
componentInnards = SwingUtilities.calculateInnerArea(progressBar,
componentInnards);
return !oldComponentInnards.equals(componentInnards);
| protected void | startAnimationTimer()Starts the animation thread, creating and initializing
it if necessary. This method is invoked when an
indeterminate progress bar should start animating.
Reasons for this may include:
- The progress bar is determinate and becomes displayable
- The progress bar is displayable and becomes determinate
- The progress bar is displayable and determinate and this
UI is installed
If you implement your own animation thread,
you must override this method.
if (animator == null) {
animator = new Animator();
}
animator.start(getRepaintInterval());
| protected void | stopAnimationTimer()Stops the animation thread.
This method is invoked when the indeterminate
animation should be stopped. Reasons for this may include:
- The progress bar changes to determinate
- The progress bar is no longer part of a displayable hierarchy
- This UI in uninstalled
If you implement your own animation thread,
you must override this method.
if (animator != null) {
animator.stop();
}
| protected void | uninstallDefaults()
LookAndFeel.uninstallBorder(progressBar);
| protected void | uninstallListeners()Removes all listeners installed by this object.
progressBar.removeChangeListener(changeListener);
progressBar.removePropertyChangeListener(getHandler());
handler = null;
| public void | uninstallUI(javax.swing.JComponent c)
if (progressBar.isIndeterminate()) {
cleanUpIndeterminateValues();
}
uninstallDefaults();
uninstallListeners();
progressBar = null;
| private void | updateSizes()Updates delta, max position.
Assumes componentInnards is correct (e.g. call after sizeChanged()).
int length = 0;
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL) {
length = getBoxLength(componentInnards.width,
componentInnards.height);
maxPosition = componentInnards.x + componentInnards.width
- length;
} else { //VERTICAL progress bar
length = getBoxLength(componentInnards.height,
componentInnards.width);
maxPosition = componentInnards.y + componentInnards.height
- length;
}
//If we're doing bouncing-box animation, update delta.
delta = 2.0 * (double)maxPosition/(double)numFrames;
|
|