158 lines
3.3 KiB
Java
158 lines
3.3 KiB
Java
|
|
package net.sourceforge.tuned.ui;
|
|
|
|
|
|
import java.awt.BasicStroke;
|
|
import java.awt.Color;
|
|
import java.awt.Dimension;
|
|
import java.awt.Graphics;
|
|
import java.awt.Graphics2D;
|
|
import java.awt.RenderingHints;
|
|
import java.awt.Stroke;
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.event.ActionListener;
|
|
import java.awt.event.ComponentAdapter;
|
|
import java.awt.event.ComponentEvent;
|
|
import java.awt.geom.Ellipse2D;
|
|
import java.awt.geom.Point2D;
|
|
import java.awt.geom.Rectangle2D;
|
|
|
|
import javax.swing.JComponent;
|
|
import javax.swing.Timer;
|
|
|
|
|
|
public class ProgressIndicator extends JComponent {
|
|
|
|
private float radius = 4.0f;
|
|
private int shapeCount = 3;
|
|
|
|
private float strokeWidth = 2f;
|
|
private Stroke stroke = new BasicStroke(strokeWidth, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND);
|
|
|
|
private Color progressShapeColor = Color.orange;
|
|
private Color backgroundShapeColor = new Color(0f, 0f, 0f, 0.25f);
|
|
|
|
private final Rectangle2D frame = new Rectangle2D.Double();
|
|
private final Ellipse2D circle = new Ellipse2D.Double();
|
|
private final Dimension baseSize = new Dimension(32, 32);
|
|
|
|
private double alpha = 0;
|
|
private double speed = 24;
|
|
|
|
private Timer updateTimer;
|
|
|
|
|
|
public ProgressIndicator() {
|
|
setPreferredSize(baseSize);
|
|
|
|
addComponentListener(new ComponentAdapter() {
|
|
|
|
@Override
|
|
public void componentShown(ComponentEvent e) {
|
|
startAnimation();
|
|
}
|
|
|
|
|
|
@Override
|
|
public void componentHidden(ComponentEvent e) {
|
|
stopAnimation();
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
public void animateOnce() {
|
|
if ((alpha += (speed / 1000)) >= 1) {
|
|
alpha -= Math.floor(alpha);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
public void paintComponent(Graphics g) {
|
|
Graphics2D g2d = (Graphics2D) g;
|
|
|
|
double a = Math.min(getWidth(), getHeight());
|
|
|
|
g2d.scale(a / baseSize.width, a / baseSize.height);
|
|
|
|
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
|
frame.setFrame(radius, radius, baseSize.width - radius * 2 - 1, baseSize.height - radius * 2 - 1);
|
|
|
|
paintShapes(g2d);
|
|
}
|
|
|
|
|
|
private void paintShapes(Graphics2D g2d) {
|
|
circle.setFrame(frame);
|
|
|
|
g2d.setStroke(stroke);
|
|
g2d.setPaint(backgroundShapeColor);
|
|
|
|
g2d.draw(circle);
|
|
|
|
Point2D center = new Point2D.Double(frame.getCenterX(), frame.getMinY());
|
|
|
|
circle.setFrameFromCenter(center, new Point2D.Double(center.getX() + radius, center.getY() + radius));
|
|
|
|
g2d.setStroke(stroke);
|
|
g2d.setPaint(progressShapeColor);
|
|
|
|
// base rotation
|
|
g2d.rotate(getTheta(alpha, 1.0), frame.getCenterX(), frame.getCenterY());
|
|
|
|
double theta = getTheta(1, shapeCount);
|
|
|
|
for (int i = 0; i < shapeCount; i++) {
|
|
g2d.rotate(theta, frame.getCenterX(), frame.getCenterY());
|
|
g2d.fill(circle);
|
|
}
|
|
}
|
|
|
|
|
|
private double getTheta(double value, double max) {
|
|
return (value / max) * 2 * Math.PI;
|
|
}
|
|
|
|
|
|
public void startAnimation() {
|
|
if (updateTimer == null) {
|
|
updateTimer = new Timer(20, new ActionListener() {
|
|
|
|
@Override
|
|
public void actionPerformed(ActionEvent e) {
|
|
animateOnce();
|
|
repaint();
|
|
}
|
|
});
|
|
|
|
updateTimer.start();
|
|
}
|
|
}
|
|
|
|
|
|
public void stopAnimation() {
|
|
if (updateTimer != null) {
|
|
updateTimer.stop();
|
|
updateTimer = null;
|
|
}
|
|
}
|
|
|
|
|
|
public void setShapeCount(int indeterminateShapeCount) {
|
|
this.shapeCount = indeterminateShapeCount;
|
|
}
|
|
|
|
|
|
public void setSpeed(double speed) {
|
|
this.speed = speed;
|
|
}
|
|
|
|
|
|
public double getSpeed() {
|
|
return speed;
|
|
}
|
|
|
|
}
|