package trident.swing; import java.awt.*; import java.awt.event.*; import java.awt.geom.RoundRectangle2D; import javax.swing.*; import org.pushingpixels.trident.Timeline; import org.pushingpixels.trident.Timeline.RepeatBehavior; import org.pushingpixels.trident.interpolator.*; import org.pushingpixels.trident.swing.SwingRepaintTimeline; public class ProgressIndication extends JFrame { public static class ProgressPanel extends JPanel { private static final int INNER_HEIGHT = 60; private static final int INNER_WIDTH = 300; private static final int HIGHLIGHTER_HEIGHT = 2; private static final int HIGHLIGHTER_WIDTH = 58; private int xPosition; private float alpha; private boolean started; private Timeline progressTimeline; public ProgressPanel() { this.xPosition = 0; this.alpha = 0; this.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (started) return; start(); started = true; } }); this.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { if (started) { progressTimeline.cancel(); start(); } } }); new SwingRepaintTimeline(this).playLoop(RepeatBehavior.LOOP); } public void start() { progressTimeline = new Timeline(this); int startX = (getWidth() - INNER_WIDTH) / 2 + 18 + HIGHLIGHTER_WIDTH / 2; int endX = (getWidth() + INNER_WIDTH) / 2 - 18 - HIGHLIGHTER_WIDTH / 2; progressTimeline .addPropertyToInterpolate("xPosition", startX, endX); KeyValues<Float> alphaValues = KeyValues.create(0.0f, 1.0f, 1.0f, 0.0f); KeyTimes alphaTimes = new KeyTimes(0.0f, 0.3f, 0.7f, 1.0f); progressTimeline.addPropertyToInterpolate("alpha", new KeyFrames<Float>(alphaValues, alphaTimes)); progressTimeline.setDuration(1500); progressTimeline.playLoop(RepeatBehavior.LOOP); } @Override protected void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g.create(); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); int w = getWidth(); int h = getHeight(); // Full background g2d.setColor(new Color(12, 12, 12)); g2d.fillRect(0, 0, w, h); if (!started) { g2d.setColor(Color.white); g2d.setFont(new Font("Tahoma", Font.PLAIN, 18)); String caption = "Click to start"; g2d.drawString(caption, (w - g2d.getFontMetrics().stringWidth( caption)) / 2, h / 3); } // Inner gradient fill Shape innerContour = new RoundRectangle2D.Double( (w - INNER_WIDTH) / 2.0, (h - INNER_HEIGHT) / 2.0, INNER_WIDTH, INNER_HEIGHT, 10, 10); g2d.setPaint(new GradientPaint((w - INNER_WIDTH) / 2.0f, (h - INNER_HEIGHT) / 2.0f, new Color(47, 47, 47), (w - INNER_WIDTH) / 2.0f, (h + INNER_HEIGHT) / 2.0f, Color.black)); g2d.fill(innerContour); // Inner contour g2d.setColor(new Color(67, 67, 67)); g2d.draw(innerContour); // Progress track int trackWidth = INNER_WIDTH - 36; int trackHeight = 1; g2d.setColor(new Color(91, 91, 91)); for (int i = 2; i >= 0; i--) { Shape trackContour = new RoundRectangle2D.Double( (w - INNER_WIDTH) / 2 + 18 - i, h / 2 - i - 1, trackWidth + i * 2, trackHeight + i * 2, 2 * i, 2 * i); float alpha = 1.0f; if (i == 1) alpha = 0.3f; if (i == 2) alpha = 0.1f; g2d.setComposite(AlphaComposite.SrcOver.derive(alpha)); g2d.draw(trackContour); } // Highlighter g2d.setColor(new Color(13, 106, 206)); g2d.setComposite(AlphaComposite.SrcOver.derive(0.1f * this.alpha)); for (int i = 6; i >= 0; i--) { g2d.fillOval(this.xPosition - HIGHLIGHTER_WIDTH / 2 - i, h / 2 - HIGHLIGHTER_HEIGHT / 2 - i, HIGHLIGHTER_WIDTH + 2 * i, HIGHLIGHTER_HEIGHT + 2 * i); } // Highlighter on track g2d.setComposite(AlphaComposite.SrcOver.derive(this.alpha)); g2d.setColor(new Color(136, 182, 231)); g2d.fillRect(this.xPosition - 28, h / 2 - 1, 56, 2); g2d.dispose(); } public void setXPosition(int position) { xPosition = position; } public void setAlpha(float alpha) { this.alpha = alpha; } } public ProgressIndication() { super("Swing progress"); this.add(new ProgressPanel()); this.setSize(400, 300); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new ProgressIndication().setVisible(true); } }); } }