Why my arc is jumping
Here is the code
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
publicclass ArcTestextends JPanel{
privateint m_angle = 0;
public ArcTest(){
Animate anim =new Animate();
anim.start();
}
publicvoid paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(5f));
Color start = Color.GRAY;
Color end= Color.WHITE;
//GradientPaint gp = new GradientPaint(0 ,0 ,start ,0 ,m_angle , end);
//g2d.setPaint(gp);
g2d.drawArc(30, 30, 30 , 30, m_angle, 280);
}
publicstaticvoid main(String[] args){
JFrame f =new JFrame();
ArcTest t =new ArcTest();
f.add(t);
f.setSize(400 ,400);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);
}
class Animateextends Thread{
publicvoid run(){
while(true){
ArcTest.this.repaint();
m_angle += 10;
if(m_angle > 360){
m_angle = 0;
}
try{
Thread.sleep(20);
}catch (InterruptedException e){}
}
}
}
}
[3166 byte] By [
shay_tea] at [2007-10-3 2:56:16]

Change the m_angle increment to 1 and increase the sleep delay to 200ms to see what happens
to the arc with each successive rendering.
I tried two things to smooth out the animation:
1 — create an arc and animate it with AffineTransform
2 — create an image of the arc and rotate it with AffineTransform.
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.GraphicsDevice;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class ArcTestRx extends JPanel{
Arc2D arc;
GradientPaint gp;
BufferedImage image;
private int m_angle = 0;
public ArcTestRx(){
arc = new Arc2D.Double(0, 0, 30, 30, 0, 280, Arc2D.OPEN);
Color start = Color.GRAY;
Color end= Color.WHITE;
gp = new GradientPaint(30, 30, start, 60, 60, end);
createImage();
Animate anim = new Animate();
anim.start();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.setStroke(new BasicStroke(5f));
//g2d.setPaint(gp);
g2d.drawArc(30, 30, 30, 30, m_angle, 280);
//arc.setArc(30, 30, 30, 30, m_angle, 280, Arc2D.OPEN);
//g2d.draw(arc);
double radians = Math.toRadians(m_angle);
Rectangle2D r = arc.getBounds2D();
// arc angles are measured positive anti-clockwise
// the rest of java measures angles positive clockwise
// can we draw a smoother animation using AffineTransform
// to rotate an Arc2D?
AffineTransform at = AffineTransform.getTranslateInstance(300, 30);
at.rotate(-radians, r.getCenterX(), r.getCenterY());
g2d.draw(at.createTransformedShape(arc));
// how about rotating an image of the Arc2D with AffineTransform?
at.setToTranslation(200, 200);
at.rotate(-radians, image.getWidth()/2, image.getHeight()/2);
g2d.drawRenderedImage(image, at);
}
private void createImage(){
BasicStroke stroke = new BasicStroke(5f);
float lineWidth = stroke.getLineWidth();
Rectangle r = arc.getBounds();
int w = (int)(r.width + lineWidth);
int h = (int)(r.height + lineWidth);
image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2.setPaint(Color.black);
g2.setStroke(new BasicStroke(5f));
g2.translate(lineWidth/2.0, lineWidth/2.0);
g2.draw(arc);
g2.dispose();
}
public static void main(String[] args) {
JFrame f = new JFrame();
ArcTestRx t = new ArcTestRx();
f.add(t);
f.setSize(400, 400);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);
}
class Animate extends Thread{
public void run(){
while(true){
ArcTestRx.this.repaint();
m_angle += 10;
if(m_angle > 360){
m_angle = 0;
}
try {
Thread.sleep(20);
} catch (InterruptedException e) {}
}
}
}
}
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
public class ArcTestRx extends JPanel{
Color start, end;
private int m_angle = 0;
public ArcTestRx(){
start = Color.GRAY;
end= UIManager.getColor("Panel.background");
setLayout(new BorderLayout());
add(new JLabel(new ImageIcon("loading.gif")), "First");
Animate anim = new Animate();
anim.start();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
g2d.setStroke(new BasicStroke(5f));
GradientPaint gp = getGradient();
g2d.setPaint(gp);
g2d.drawArc(30, 30, 30, 30, m_angle, 180);
}
private GradientPaint getGradient() {
int cx = 45;
int cy = 45;
double radius = (30 + 1)/2.0;
double theta = -Math.toRadians(m_angle);
float x2 = (float)(cx + radius*Math.cos(theta));
float y2 = (float)(cy + radius*Math.sin(theta));
float x1 = (float)(cx + radius*Math.cos(theta+Math.PI));
float y1 = (float)(cy + radius*Math.sin(theta+Math.PI));
return new GradientPaint(x1, y1, start, x2, y2, end);
}
public static void main(String[] args) {
JFrame f = new JFrame();
ArcTestRx t = new ArcTestRx();
f.add(t);
f.setSize(240, 120);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);
}
class Animate extends Thread{
public void run(){
while(true){
ArcTestRx.this.repaint();
m_angle += 10;
if(m_angle > 360){
m_angle = 0;
}
try {
Thread.sleep(20);
} catch (InterruptedException e) {}
}
}
}
}