Package pdp.scrabble

Source Code of pdp.scrabble.InfiniteProgressPanel$Animator

package pdp.scrabble;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JComponent;

/** Source: http://www.jroller.com/gfx/date/20050215 */
public class InfiniteProgressPanel extends JComponent implements MouseListener {
  private static final long serialVersionUID = 1L;

  private Area[] ticker = null;

  private Thread animation = null;

  private boolean started = false;

  private int alphaLevel = 0;

  private int rampDelay = 300;

  private float shield = 0.70f;

  private String text = "";

  private int barsCount = 14;

  private float fps = 15.0f;

  private RenderingHints hints = null;

  public InfiniteProgressPanel() {
    this("");
  }

  public InfiniteProgressPanel(String text) {
    this(text, 14);
  }

  public InfiniteProgressPanel(String text, int barsCount) {
    this(text, barsCount, 0.70f);
  }

  public InfiniteProgressPanel(String text, int barsCount, float shield) {
    this(text, barsCount, shield, 15.0f);
  }

  public InfiniteProgressPanel(
      String text, int barsCount, float shield, float fps) {

    this(text, barsCount, shield, fps, 300);
  }

  public InfiniteProgressPanel(
      String text, int barsCount, float shield, float fps, int rampDelay) {

    this.text = text;
    this.rampDelay = rampDelay >= 0 ? rampDelay : 0;
    this.shield = shield >= 0.0f ? shield : 0.0f;
    this.fps = fps > 0.0f ? fps : 15.0f;
    this.barsCount = barsCount > 0 ? barsCount : 14;

    this.hints = new RenderingHints(RenderingHints.KEY_RENDERING,
        RenderingHints.VALUE_RENDER_QUALITY);

    this.hints.put(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);

    this.hints.put(RenderingHints.KEY_FRACTIONALMETRICS,
        RenderingHints.VALUE_FRACTIONALMETRICS_ON);
  }

  public void setText(String text) {
    this.paintImmediately(0, 0, this.getWidth(), this.getHeight());
    this.text = text;
  }

  public String getText() {
    return this.text;
  }

  /** Start progress. */
  public void start() {
    this.addMouseListener(this);
    this.setVisible(true);
    this.ticker = buildTicker();
    this.animation = new Animator(true);
    this.animation.start();
  }

  /** Pause progress. */
  public void stop() {
    if (this.animation != null) {
      this.animation.interrupt();
      this.animation = null;
      this.animation = new Animator(false);
      this.animation.start();
    }
  }

  /** Interrupt progress and exit. */
  public void interrupt() {
    if (this.animation != null) {
      this.animation.interrupt();
      this.animation = null;

      this.removeMouseListener(this);
      this.setVisible(false);
    }
  }

  @Override
  public void paintComponent(Graphics g) {
    if (this.started) {
      int width = this.getWidth();
      @SuppressWarnings("unused")
      int height = this.getHeight();

      double maxY = 0.0;

      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHints(this.hints);

      g2.setColor(new Color(255, 255, 255, (int) (alphaLevel * shield)));
      g2.fillRect(0, 0, this.getWidth(), this.getHeight());

      for (int i = 0; i < ticker.length; i++) {
        int channel = 224 - 128 / (i + 1);
        g2.setColor(new Color(channel, channel, channel, alphaLevel));
        g2.fill(this.ticker[i]);

        Rectangle2D bounds = this.ticker[i].getBounds2D();
        if (bounds.getMaxY() > maxY) {
          maxY = bounds.getMaxY();
        }
      }

      if (this.text != null && this.text.length() > 0) {
        FontRenderContext context = g2.getFontRenderContext();
        TextLayout layout = new TextLayout(this.text, getFont(), context);
        Rectangle2D bounds = layout.getBounds();
        g2.setColor(getForeground());
        layout.draw(g2, (float) (width - bounds.getWidth()) / 2,
            (float) (maxY + layout.getLeading()
                + 2 * layout.getAscent()));
      }
    }
  }

  private Area[] buildTicker() {
    Area[] ticker = new Area[this.barsCount];
    Point2D.Double center = new Point2D.Double(
        (double) getWidth() / 2, (double) getHeight() / 2);

    double fixedAngle = 2.0 * Math.PI / ((double) this.barsCount);

    for (double i = 0.0; i < (double) this.barsCount; i++) {
      Area primitive = buildPrimitive();

      AffineTransform toCenter = AffineTransform.getTranslateInstance(
          center.getX(), center.getY());

      AffineTransform toBorder = AffineTransform.getTranslateInstance(
          45.0, -6.0);

      AffineTransform toCircle = AffineTransform.getRotateInstance(
          -i * fixedAngle, center.getX(), center.getY());

      AffineTransform toWheel = new AffineTransform();
      toWheel.concatenate(toCenter);
      toWheel.concatenate(toBorder);

      primitive.transform(toWheel);
      primitive.transform(toCircle);

      ticker[(int) i] = primitive;
    }

    return ticker;
  }

  private Area buildPrimitive() {
    Rectangle2D.Double body = new Rectangle2D.Double(6, 0, 30, 12);
    Ellipse2D.Double head = new Ellipse2D.Double(0, 0, 12, 12);
    Ellipse2D.Double tail = new Ellipse2D.Double(30, 0, 12, 12);

    Area tick = new Area(body);
    tick.add(new Area(head));
    tick.add(new Area(tail));

    return tick;
  }

  private class Animator extends Thread {
    private boolean rampUp = true;

    Animator(boolean rampUp) {
      super("Progress Animator");
      this.rampUp = rampUp;
    }

    @Override
    public void run() {
      Point2D.Double center = new Point2D.Double(
          (double) getWidth() / 2, (double) getHeight() / 2);

      double fixedIncrement = 2.0 * Math.PI / ((double) barsCount);
      AffineTransform toCircle = AffineTransform.getRotateInstance(
          fixedIncrement, center.getX(), center.getY());

      long start = System.currentTimeMillis();
      if (rampDelay == 0) {
        alphaLevel = rampUp ? 255 : 0;
      }

      started = true;
      boolean inRamp = rampUp;

      while (!Thread.interrupted()) {
        if (!inRamp) {
          for (int i = 0; i < ticker.length; i++) {
            ticker[i].transform(toCircle);
          }
        }

        paintImmediately(0, 0, getWidth(), getHeight());

        if (rampUp) {
          if (alphaLevel < 255) {
            alphaLevel = (int) (255 * (
                System.currentTimeMillis() - start) / rampDelay);

            if (alphaLevel >= 255) {
              alphaLevel = 255;
              inRamp = false;
            }
          }
        }
        else if (alphaLevel > 0) {
          alphaLevel = (int) (255 - (255 * (
              System.currentTimeMillis() - start) / rampDelay));

          if (alphaLevel <= 0) {
            alphaLevel = 0;
            break;
          }
        }

        try {
          Thread.sleep(inRamp ? 10 : (int) (1000 / fps));
        }
        catch (InterruptedException ie) {
          break;
        }
        Thread.yield();
      }

      if (!rampUp) {
        started = false;
        paintImmediately(0, 0, getWidth(), getHeight());

        setVisible(false);
        removeMouseListener(InfiniteProgressPanel.this);
      }
    }
  }

  public void mouseClicked(MouseEvent e) {
  }

  public void mousePressed(MouseEvent e) {
  }

  public void mouseReleased(MouseEvent e) {
  }

  public void mouseEntered(MouseEvent e) {
  }

  public void mouseExited(MouseEvent e) {
  }
}
TOP

Related Classes of pdp.scrabble.InfiniteProgressPanel$Animator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.