使用Graphics2D,我是否可以制作一个没有“摇摆”效果的光滑圆圈?如果有,怎么样?要理解我的意思,你必须运行以下示例:
import java.awt.Color;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.*;
public class CircleExample {
static int angle = 0;
public static void main(String[] args) {
JFrame frame = new JFrame();
new Thread(new Runnable() {
public void run() {
while (true) {
if (angle >= 360) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
angle = 0;
}
angle++;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
frame.repaint();
}
}
}).start();
frame.getContentPane().add(new Circle());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setVisible(true);
}
static class Circle extends JPanel {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D gg = (Graphics2D) g;
gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
gg.setColor(Color.BLACK);
gg.drawArc(40, 40, 100, 100, 0, angle);
}
}
}
答案 0 :(得分:3)
摆动效果是由于抗锯齿决定因不同的弧而略有不同,可能是由于舍入误差造成的。
解决这个问题的一种方法是绘制一个完整的圆 - 它总是以抗锯齿的方式呈现 - 但将其剪切到给定的圆弧。因此,实际上只会绘制其中的一部分。
以下是基于Andrew Thompson的基于计时器的答案(已被删除),但我在原始帖子中添加了一些延迟,并使Circle
成为public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.getContentPane().add(new Circle());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setVisible(true);
}
static class Circle extends JPanel {
private int angle = 0;
// The clip arc is going to be slightly larger than the actual
// arc, otherwise some antialiasing pixels will be clipped off.
private Arc2D clip = new Arc2D.Double(35,35,110,110,0,360,Arc2D.PIE);
Circle() {
ActionListener actionListener = new ActionListener() {
int waitCounter = 0;
@Override
public void actionPerformed(ActionEvent e) {
// When the angle reaches 360, set a wait for 100
// runs of the timer.
if (angle >= 360) {
angle = 0;
waitCounter = 100;
}
// If waiting, count down the time. When the wait
// counter is zero, do the actual work.
if (waitCounter > 0) {
waitCounter--;
} else {
angle++;
repaint();
}
}
};
// The timer itself runs every 10 milliseconds.
Timer timer = new Timer(10, actionListener);
timer.start();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D gg = (Graphics2D) g;
gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// Set the clipping arc to the current angle.
clip.setAngleExtent(angle);
gg.setClip(clip);
// Draw a full circle. It will be clipped to the arc set above.
gg.setColor(Color.BLACK);
gg.drawOval(40,40,100,100);
}
}
类的字段而不是一个静态变量。
{{1}}