import java.awt.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class SpinningTaiChi extends JPanel implements Runnable {
BufferedImage image;
Point loc = new Point();
int dx = 2;
double theta = 0;
double thetaInc = Math.toRadians(3);
AffineTransform at = new AffineTransform();
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
if(image == null)
initImage();
g2.drawRenderedImage(image, at);
}
public void run() {
boolean more = true;
while(more) {
try {
Thread.sleep(50);
} catch(InterruptedException e) {
System.out.println("run interrupted");
more = false;
}
step();
}
}
private void step() {
checkBoundries();
setTransform();
repaint();
}
private void checkBoundries() {
if(loc.x + dx < 0 || loc.x + image.getWidth() + dx > getWidth())
dx *= -1;
}
private void setTransform() {
loc.x += dx;
theta += thetaInc;
at.setToTranslation(loc.x, loc.y);
at.rotate(theta, image.getWidth()/2, image.getHeight()/2);
}
private void start() {
while(image == null) {
try {
Thread.sleep(25);
} catch(InterruptedException e) {
System.out.println("waiting interrupted");
break;
}
}
Thread thread = new Thread(this);
thread.setPriority(Thread.NORM_PRIORITY);
thread.start();
}
private void initImage() {
int s = 160;
int type = BufferedImage.TYPE_INT_ARGB_PRE;
image = new BufferedImage(s, s, type);
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Ellipse2D.Double e = new Ellipse2D.Double(0,0,s,s);
g2.setPaint(Color.white);
g2.fill(e);
Rectangle2D.Double r1 = new Rectangle2D.Double(0,s/4,s/2,s/2);
Rectangle2D.Double r2 = new Rectangle2D.Double(s/2,s/4,s/2-1,s/2);
Arc2D.Double a1 = new Arc2D.Double(r1,0,180,Arc2D.OPEN);
Arc2D.Double a2 = new Arc2D.Double(r2,180,180,Arc2D.OPEN);
Arc2D.Double top = new Arc2D.Double(0,0,s-1,s,0,180,Arc2D.OPEN);
Path2D.Double path = new Path2D.Double(Path2D.WIND_EVEN_ODD);
path.append(a1, false);
path.append(a2, false);
path.append(top, false);
g2.setPaint(Color.black);
g2.fill(path);
g2.draw(path);
g2.fill(new Ellipse2D.Double(s/4-15,s/2-15,30,30));
g2.setPaint(Color.white);
g2.fill(new Ellipse2D.Double(s*3/4-15,s/2-15,30,30));
g2.dispose();
double y = (getHeight() - s)/2;
loc.setLocation(0,y);
at.setToTranslation(0,y);
}
public static void main(String[] args) {
SpinningTaiChi test = new SpinningTaiChi();
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(test);
f.setSize(600,400);
f.setLocationRelativeTo(null);
f.setVisible(true);
test.start();
}
}
loop.