如何在 Java Swing 中制作不不断改变/闪烁颜色的简单动画形状?

我有一些为了好玩而编写的代码,用不同颜色绘制圆圈线。在不使用 Swing Timer 的情况下,圆圈会“一次性”绘制,并且它们的颜色会在红色、绿色、蓝色和黄色之间交替。因此,如果没有计时器,代码将按预期工作。然而,当我尝试制作动画以便可以看到正在绘制的圆圈时,这意味着使用 Swing Timer 进行循环而不是 while/for 循环,所有圆圈都具有相同的颜色,并保持四种颜色一起闪烁。我想问题是颜色与每个对象无关,而是与整个框架相关联,因为我每隔几毫秒更改一次框架的颜色,已经绘制的圆圈不会像它们那样保留其原始颜色while 循环。如果您看到任何解决方案,我们将不胜感激!


public class Board extends JPanel {


    private static final long serialVersionUID = 6676924870723702476L;


    private Timer timer;

    private final int DELAY = 30;


    private ActionListener drawLine;

    private Ellipse2D circ;

    private ArrayList<Ellipse2D> circles = new ArrayList<>();


    private double circDiam = 80;

    private double circX = 0;

    private double circY = 0;

    private short circNum = 1;


    public Board() {


        drawLine = (ActionEvent e) -> {


            repaint();


            circX += circDiam;


            if(circNum == 5)

            {

                circNum = 1;            

            }

        };


        timer = new Timer(DELAY, drawLine);

        timer.start();

    }


    private Color getCircColor(short circNum) { 

        switch(circNum) {

            case 1:

                return Color.blue;

            case 2:

                return Color.red;

            case 3:

                return Color.yellow;

            case 4:

                return Color.green;

            default:

                return Color.gray;

        }

    }


    protected void paintComponent(Graphics g) {

        super.paintComponent(g);


        Dimension size = new Dimension(getWidth(), getHeight());

        double width = size.getWidth();

        double height = size.getHeight();


        Graphics2D g2d = (Graphics2D) g;


        RenderingHints rHints = new  RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        rHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

        g2d.setRenderingHints(rHints);



手掌心
浏览 82回答 2
2回答

青春有我

绘画方法仅用于绘画。它不应该:创建对象。也就是说,不要创建 Circle 对象。停止定时器。绘制代码将简单地遍历 ArrayList 来绘制所有 Circlce 对象。Timer 的 ActionListener 用于:创建 Cirlce 对象并将它们一次一个地添加到 ArrayList 中。确定每个对象的颜色创建所需数量的对象后停止计时器。所以基本上在你的 Board 类中你需要一个像addCircle(....). 这会将 Circle 对象添加到 ArrayList,然后repaint()对其自身进行调用。然后,您更改ActionListener代码以创建 Circle 对象并调用该addCirle(...)方法。我想问题是颜色并不与每个对象相关联正确的。您将需要一个自定义对象来进行绘画。这个自定义对象将包含两个属性:圆对象Circle 对象的颜色。或者另一种选择是直接绘制 BufferedImage,然后在面板中显示 BufferedImage。

慕田峪4524236

我得到了相同的结果,但有一个例外,代码如下:public class Board extends JPanel {    private static final long serialVersionUID = 6676924870723702476L;    private Timer timer;    private final int DELAY = 30;    private ActionListener drawLine;    private RCircle circ;    private ArrayList<RCircle> circles = new ArrayList<>();    private double circDiam = 80;    private double circX = 0;    private double circY = 0;    private short circNum = 1;    private double height = 800;    private double width = 800;    public Board() {        drawLine = (ActionEvent e) -> {            if(circX >= width - circDiam)            {                circY += circDiam;                circX = 0;                circDiam *= 0.865   ;            }            if(circY >= height - circDiam) {                timer.stop();            }            circ = new RCircle(circX, circY, circDiam, circNum);            circNum++;            addCircle();            circX += circDiam;            if(circNum == 5)            {                circNum = 1;                        }        };        timer = new Timer(DELAY, drawLine);        timer.start();    }    private void addCircle() {        circles.add(circ);        repaint();    }    protected void paintComponent(Graphics g) {        super.paintComponent(g);        Graphics2D g2d = (Graphics2D) g;        RenderingHints rHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);        rHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);        g2d.setRenderingHints(rHints);        g2d.setColor(circ.getColor());        for(RCircle circ : circles) {            g2d.fill(circ.getCirc());        }    }}public class RCircle {    private Ellipse2D circ;    private Color color;    public RCircle(double x, double y, double circDiam, short circNum) {         this.circ = new Ellipse2D.Double(x, y, circDiam, circDiam);         this.color = getCircColor(circNum);    }    private Color getCircColor(short circNum) {         switch(circNum) {            case 1:                return Color.blue;            case 2:                return Color.red;            case 3:                return Color.yellow;            case 4:                return Color.green;            default:                return Color.gray;        }    }    public Ellipse2D getCirc() {        return circ;    }    public void setCirc(Ellipse2D circ) {        this.circ = circ;    }    public Color getColor() {        return color;    }    public void setColor(Color color) {        this.color = color;    }}public class Execute extends JFrame {    private static final long serialVersionUID = -3483390877436935589L;    public Execute() {        add(new Board());        setSize(800, 800);        setResizable(false);        setLocationRelativeTo(null);        setDefaultCloseOperation(EXIT_ON_CLOSE);    }    public static void main(String[] args) {        EventQueue.invokeLater(() -> {            Execute ex = new Execute();            ex.setVisible(true);        });    }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java