用“线索”绘制一个光滑的圆圈

时间:2015-08-29 13:32:02

标签: java swing graphics2d event-dispatch-thread

使用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);

        }

    }

}

1 个答案:

答案 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}}