/** * This software is released as part of the Pumpernickel project. * * All com.pump resources in the Pumpernickel project are distributed under the * MIT License: * https://raw.githubusercontent.com/mickleness/pumpernickel/master/License.txt * * More information about the Pumpernickel project is available here: * https://mickleness.github.io/pumpernickel/ */ package com.pump.plaf; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Arc2D; import java.awt.geom.GeneralPath; import javax.swing.JComponent; /** * A <code>ThrobberUI</code> of two arrows that rotate clockwise. * <p> * <table summary="Sample Animations of ChasingArrowsThrobberUI" cellpadding="10"> * <tr> * <td><img src= * "https://raw.githubusercontent.com/mickleness/pumpernickel/master/resources/throbber/ChasingArrowsThrobberUI.gif" * alt="ChassingArrowsThrobberUI"></td> * <td><img src= * "https://raw.githubusercontent.com/mickleness/pumpernickel/master/resources/throbber/ChasingArrowsThrobberUIx2.gif" * alt="ChassingArrowsThrobberUI Magnified 2x"></td> * <td><img src= * "https://raw.githubusercontent.com/mickleness/pumpernickel/master/resources/throbber/ChasingArrowsThrobberUIx4.gif" * alt="ChassingArrowsThrobberUI Magnified 4x"></td> * </tr> * </table> * <p> * On installation: the component's foreground is set to dark gray, but if that * is changed then that color is used to render this animation. * <P> * The default period for this animation is 2000, but you can modify this with * the period client properties {@link ThrobberUI#PERIOD_KEY} or * {@link ThrobberUI#PERIOD_MULTIPLIER_KEY}. */ public class ChasingArrowsThrobberUI extends ThrobberUI { /** * The default duration (in ms) it takes to complete a cycle. */ public static final int DEFAULT_PERIOD = 2000; private static final float PI = (float) Math.PI; private static final int[] x = new int[] { 8, 8, 11 }; private static final int[] y = new int[] { 0, 6, 3 }; private static final BasicStroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL); private AffineTransform transform = new AffineTransform(); private Arc2D arc = new Arc2D.Float(3, 3, 10, 10, 65, 140, Arc2D.OPEN); private GeneralPath path = new GeneralPath(); public ChasingArrowsThrobberUI() { super(1000 / 24); } @Override protected synchronized void paintForeground(Graphics2D g, JComponent jc, Dimension size, Float fixedFraction) { g.setStroke(stroke); float f; if (fixedFraction != null) { f = fixedFraction; } else { int p = getPeriod(jc, DEFAULT_PERIOD); f = System.currentTimeMillis() % p; f = f / ((float) p); } f = f * 2 * PI; Color color = jc == null ? getDefaultForeground() : jc.getForeground(); g.setColor(color); for (int k = 0; k < 2; k++) { transform.setToRotation(f + k * Math.PI, size.width / 2, size.height / 2); path.reset(); path.moveTo(x[0], y[0]); path.lineTo(x[1], y[1]); path.lineTo(x[2], y[2]); path.lineTo(x[0], y[0]); path.transform(transform); g.fill(path); path.reset(); path.append(arc.getPathIterator(transform), false); g.draw(path); } } @Override public Dimension getPreferredSize() { return new Dimension(16, 16); } @Override public Color getDefaultForeground() { return Color.darkGray; } }