Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
Spinner.java
1 
16 package net.squiz.matrix.ui;
17 
18 import java.awt.*;
19 import java.awt.event.*;
20 import javax.swing.*;
21 import net.squiz.matrix.core.*;
22 import java.util.*;
23 import java.awt.image.*;
24 
33 public class Spinner extends JComponent implements Runnable {
34 
36  public static final String SPINNER_ICON = "spinner.png";
38  public static final int delay = 40;
40  public static final int IMG_OFFSET = 15;
41 
42  private Dimension size = new Dimension(IMG_OFFSET, IMG_OFFSET);
43 
44  private boolean isStarted = false;
45  private int framePtr = 0;
46  private volatile Thread animator;
47  private Image[] frames;
48  private Image stopImage;
49 
54  public Spinner() {
55  ImageIcon spinner = (ImageIcon) GUIUtilities.getAssetMapIcon(SPINNER_ICON);
56  Image spinnerImg = spinner.getImage();
57 
58  BufferedImage spinnerSrc = new BufferedImage(
59  spinner.getIconWidth(),
60  spinner.getIconHeight(),
61  BufferedImage.TYPE_INT_ARGB_PRE
62  );
63 
64  Graphics2D g2d = (Graphics2D) spinnerSrc.createGraphics();
65  g2d.drawImage(spinnerImg, 0, 0, null);
66  g2d.dispose();
67 
68  // the number of frames of animation is one less than the icon width
69  // as we need to remove the stop spinner state from the frames
70  int numFrames = (spinner.getIconWidth() / IMG_OFFSET) - 1;
71  int offset = IMG_OFFSET;
72  frames = new Image[numFrames];
73 
74  // the stop image is the first image square in the main spinner sequence
75  stopImage = spinnerSrc.getSubimage(0, 0, IMG_OFFSET, IMG_OFFSET);
76 
77  // all other images are IMG_OFFSET from the stop image
78  for (int i = 0; i < numFrames; i++) {
79  frames[i] = spinnerSrc.getSubimage(offset, 0, IMG_OFFSET, IMG_OFFSET);
80  offset += IMG_OFFSET;
81  }
82  }
83 
87  public void run() {
88  Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
89  long tm = System.currentTimeMillis();
90 
91  while (Thread.currentThread() == animator) {
92  Graphics g = getGraphics();
93  if (g != null) {
94  g.drawImage(frames[framePtr], 0, 0, null);
95  }
96  if (framePtr == frames.length - 1) {
97  framePtr = 0;
98  } else {
99  framePtr++;
100  }
101 
102  try {
103  tm += delay;
104  Thread.sleep(Math.max(0, tm - System.currentTimeMillis()));
105  } catch (InterruptedException e) {
106  break;
107  }
108  Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
109  }
110  }
111 
118  public void paint(Graphics g) {
119  super.paint(g);
120  // if we are not spinning we need to paint the stop spinner state
121  // whenever paint gets called
122  if (!isStarted) {
123  g.drawImage(stopImage, 0, 0, null);
124  }
125  }
126 
131  public Dimension getMaximumSize() {
132  return size;
133  }
134 
139  public Dimension getMinimumSize() {
140  return size;
141  }
142 
147  public Dimension getPreferredSize() {
148  return size;
149  }
150 
156  public void start() {
157  if (isStarted)
158  return;
159  isStarted = true;
160  animator = new Thread(this);
161  animator.start();
162  }
163 
169  public void stop() {
170  isStarted = false;
171  framePtr = 0;
172  animator = null;
173  Graphics g = getGraphics();
174  if (g != null)
175  g.drawImage(stopImage, 0, 0, null);
176  }
177 
184  public boolean isStarted() {
185  return isStarted;
186  }
187 }