BasicProgressBarUI.java [plain text]
package javax.swing.plaf.basic;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JComponent;
import javax.swing.JProgressBar;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ProgressBarUI;
public class BasicProgressBarUI extends ProgressBarUI
{
protected class ChangeHandler implements ChangeListener
{
public void stateChanged(ChangeEvent e)
{
progressBar.repaint();
}
}
private class PropertyChangeHandler implements PropertyChangeListener
{
public void propertyChange(PropertyChangeEvent e)
{
if (e.getPropertyName().equals("inderterminate"))
if (((Boolean) e.getNewValue()).booleanValue())
startAnimationTimer();
else
stopAnimationTimer();
else
progressBar.repaint();
}
}
private class Animator implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
incrementAnimationIndex();
}
}
private transient Timer animationTimer;
private transient int animationIndex;
private transient int numFrames;
private transient Animator animation;
private transient PropertyChangeHandler propertyListener;
protected ChangeListener changeListener;
protected JProgressBar progressBar;
private transient int cellLength;
private transient int cellSpacing;
private transient Color selectionBackground;
private transient Color selectionForeground;
public BasicProgressBarUI()
{
super();
}
public static ComponentUI createUI(JComponent x)
{
return new BasicProgressBarUI();
}
protected int getAmountFull(Insets b, int width, int height)
{
double percentDone = progressBar.getPercentComplete();
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
return (int) (percentDone * (width - b.left - b.right));
else
return (int) (percentDone * (height - b.top - b.bottom));
}
protected int getAnimationIndex()
{
return animationIndex;
}
protected Rectangle getBox(Rectangle r)
{
if (!progressBar.isIndeterminate())
return null;
int iterations = numFrames / 2 + 1;
double boxDependent;
double boxIndependent;
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
{
Dimension dims = getPreferredInnerHorizontal();
boxDependent = (double) dims.width / iterations;
boxIndependent = dims.height;
}
else
{
Dimension dims = getPreferredInnerVertical();
boxDependent = (double) dims.height / iterations;
boxIndependent = dims.width;
}
Rectangle vr = new Rectangle();
SwingUtilities.calculateInnerArea(progressBar, vr);
int index = getAnimationIndex();
if (animationIndex > (numFrames + 1) / 2)
index = numFrames - getAnimationIndex();
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
{
r.x = vr.x + (int) (index * boxDependent);
r.y = vr.y;
r.width = (int) boxDependent;
r.height = (int) boxIndependent;
}
else
{
index++;
r.x = vr.x;
r.y = vr.height - (int) (index * boxDependent) + vr.y;
r.width = (int) boxIndependent;
r.height = (int) boxDependent;
}
return r;
}
protected int getCellLength()
{
return cellLength;
}
protected int getCellSpacing()
{
return cellSpacing;
}
public Dimension getMaximumSize(JComponent c)
{
return getPreferredSize(c);
}
public Dimension getMinimumSize(JComponent c)
{
return getPreferredSize(c);
}
protected Dimension getPreferredInnerHorizontal()
{
Rectangle vr = new Rectangle();
SwingUtilities.calculateInnerArea(progressBar, vr);
return new Dimension(vr.width, vr.height);
}
protected Dimension getPreferredInnerVertical()
{
Rectangle vr = new Rectangle();
SwingUtilities.calculateInnerArea(progressBar, vr);
return new Dimension(vr.width, vr.height);
}
public Dimension getPreferredSize(JComponent c)
{
Graphics g = progressBar.getGraphics();
Insets insets = c.getInsets();
FontMetrics fm = g.getFontMetrics(c.getFont());
int textW = fm.stringWidth(progressBar.getString());
int textH = fm.getHeight();
g.dispose();
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
{
if (textH < 20)
textH = 20;
if (textW < 200)
textW = 200;
}
else
{
if (textH < 200)
textH = 200;
if (textW < 20)
textW = 20;
}
textW += insets.left + insets.right;
textH += insets.top + insets.bottom;
return new Dimension(textW, textH);
}
protected Color getSelectionBackground()
{
return selectionBackground;
}
protected Color getSelectionForeground()
{
return selectionForeground;
}
protected Point getStringPlacement(Graphics g, String progressString, int x,
int y, int width, int height)
{
Rectangle tr = new Rectangle();
Rectangle vr = new Rectangle(x, y, width, height);
Rectangle ir = new Rectangle();
Font f = g.getFont();
FontMetrics fm = g.getFontMetrics(f);
SwingUtilities.layoutCompoundLabel(progressBar, fm, progressString, null,
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.CENTER, vr, ir, tr, 0);
return new Point(tr.x, tr.y);
}
protected void incrementAnimationIndex()
{
animationIndex++;
if (animationIndex >= numFrames)
animationIndex = 0;
progressBar.repaint();
}
public void paint(Graphics g, JComponent c)
{
if (! progressBar.isIndeterminate())
paintDeterminate(g, c);
else
paintIndeterminate(g, c);
if (progressBar.isBorderPainted())
progressBar.getBorder().paintBorder(progressBar, g, 0, 0,
progressBar.getWidth(),
progressBar.getHeight());
}
protected void paintDeterminate(Graphics g, JComponent c)
{
Color saved = g.getColor();
int space = getCellSpacing();
int len = getCellLength();
int max = progressBar.getMaximum();
int min = progressBar.getMinimum();
int value = progressBar.getValue();
Rectangle vr = new Rectangle();
SwingUtilities.calculateInnerArea(c, vr);
Rectangle or = c.getBounds();
Insets insets = c.getInsets();
int amountFull = getAmountFull(insets, or.width, or.height);
g.setColor(c.getBackground());
g.fill3DRect(vr.x, vr.y, vr.width, vr.height, false);
if (max != min && len != 0 && value > min)
{
int iterations = value / (space + len);
if (progressBar.getOrientation() == JProgressBar.HORIZONTAL)
{
double spaceInUnits = space * (double) vr.width / (max - min);
double lenInUnits = len * (double) vr.width / (max - min);
double currX = vr.x;
g.setColor(c.getForeground());
g.fill3DRect(vr.x, vr.y, amountFull, vr.height, true);
g.setColor(c.getBackground());
if (spaceInUnits != 0)
{
for (int i = 0; i < iterations; i++)
{
currX += lenInUnits;
g.fill3DRect((int) currX, vr.y, (int) spaceInUnits,
vr.height, true);
currX += spaceInUnits;
}
}
}
else
{
double currY = vr.y;
double spaceInUnits = space * (double) vr.height / (max - min);
double lenInUnits = len * (double) vr.height / (max - min);
g.setColor(c.getForeground());
g.fill3DRect(vr.x, vr.y + vr.height - amountFull, vr.width,
amountFull, true);
g.setColor(c.getBackground());
if (spaceInUnits != 0)
{
for (int i = 0; i < iterations; i++)
{
currY -= lenInUnits + spaceInUnits;
g.fill3DRect(vr.x, (int) currY, vr.width,
(int) spaceInUnits, true);
}
}
}
}
if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
paintString(g, 0, 0, or.width, or.height, amountFull, insets);
g.setColor(saved);
}
protected void paintIndeterminate(Graphics g, JComponent c)
{
Color saved = g.getColor();
Insets insets = c.getInsets();
Rectangle or = c.getBounds();
Rectangle vr = new Rectangle();
SwingUtilities.calculateInnerArea(c, vr);
g.setColor(c.getBackground());
g.fill3DRect(vr.x, vr.y, vr.width, vr.height, false);
Rectangle box = new Rectangle();
getBox(box);
g.setColor(c.getForeground());
g.fill3DRect(box.x, box.y, box.width, box.height, true);
if (progressBar.isStringPainted() && !progressBar.getString().equals(""))
paintString(g, 0, 0, or.width, or.height,
getAmountFull(insets, or.width, or.height), insets);
g.setColor(saved);
}
protected void paintString(Graphics g, int x, int y, int width, int height,
int amountFull, Insets b)
{
Point placement = getStringPlacement(g, progressBar.getString(),
x + b.left, y + b.top,
width - b.left - b.right,
height - b.top - b.bottom);
Color saved = g.getColor();
g.setColor(Color.WHITE);
FontMetrics fm = g.getFontMetrics(progressBar.getFont());
g.drawString(progressBar.getString(), placement.x,
placement.y + fm.getAscent());
g.setColor(saved);
}
protected void setAnimationIndex(int newValue)
{
animationIndex = (newValue <= numFrames) ? newValue : 0;
progressBar.repaint();
}
protected void setCellLength(int cellLen)
{
cellLength = cellLen;
}
protected void setCellSpacing(int cellSpace)
{
cellSpacing = cellSpace;
}
protected void startAnimationTimer()
{
if (animationTimer != null)
animationTimer.start();
}
protected void stopAnimationTimer()
{
if (animationTimer != null)
animationTimer.stop();
setAnimationIndex(0);
}
protected void installDefaults()
{
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
progressBar.setFont(defaults.getFont("ProgressBar.font"));
progressBar.setForeground(defaults.getColor("ProgressBar.foreground"));
progressBar.setBackground(defaults.getColor("ProgressBar.background"));
progressBar.setBorder(defaults.getBorder("ProgressBar.border"));
progressBar.setOpaque(true);
selectionForeground = defaults.getColor("ProgressBar.selectionForeground");
selectionBackground = defaults.getColor("ProgressBar.selectionBackground");
cellLength = defaults.getInt("ProgressBar.cellLength");
cellSpacing = defaults.getInt("ProgressBar.cellSpacing");
int repaintInterval = defaults.getInt("ProgressBar.repaintInterval");
int cycleTime = defaults.getInt("ProgressBar.cycleTime");
if (cycleTime % repaintInterval != 0
&& (cycleTime / repaintInterval) % 2 != 0)
{
int div = (cycleTime / repaintInterval) + 2;
div /= 2;
div *= 2;
cycleTime = div * repaintInterval;
}
setAnimationIndex(0);
numFrames = cycleTime / repaintInterval;
animationTimer.setDelay(repaintInterval);
}
protected void uninstallDefaults()
{
progressBar.setFont(null);
progressBar.setForeground(null);
progressBar.setBackground(null);
selectionForeground = null;
selectionBackground = null;
}
protected void installListeners()
{
changeListener = new ChangeHandler();
propertyListener = new PropertyChangeHandler();
animation = new Animator();
progressBar.addChangeListener(changeListener);
progressBar.addPropertyChangeListener(propertyListener);
animationTimer.addActionListener(animation);
}
protected void uninstallListeners()
{
progressBar.removeChangeListener(changeListener);
progressBar.removePropertyChangeListener(propertyListener);
animationTimer.removeActionListener(animation);
changeListener = null;
propertyListener = null;
animation = null;
}
public void installUI(JComponent c)
{
super.installUI(c);
if (c instanceof JProgressBar)
{
progressBar = (JProgressBar) c;
animationTimer = new Timer(200, null);
animationTimer.setRepeats(true);
installDefaults();
installListeners();
}
}
public void uninstallUI(JComponent c)
{
super.uninstallUI(c);
uninstallListeners();
uninstallDefaults();
animationTimer = null;
progressBar = null;
}
}