为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

手掌心 2023-09-13 15:27:36
我有一些为了好玩而编写的代码,用不同颜色绘制圆圈线。在不使用 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);
查看完整描述

2 回答

?
青春有我

TA贡献1784条经验 获得超8个赞

绘画方法仅用于绘画。它不应该:

  1. 创建对象。也就是说,不要创建 Circle 对象。

  2. 停止定时器。

  3. 绘制代码将简单地遍历 ArrayList 来绘制所有 Circlce 对象。

Timer 的 ActionListener 用于:

  1. 创建 Cirlce 对象并将它们一次一个地添加到 ArrayList 中。

  2. 确定每个对象的颜色

  3. 创建所需数量的对象后停止计时器。

所以基本上在你的 Board 类中你需要一个像addCircle(....). 这会将 Circle 对象添加到 ArrayList,然后repaint()对其自身进行调用。然后,您更改ActionListener代码以创建 Circle 对象并调用该addCirle(...)方法。

我想问题是颜色并不与每个对象相关联

正确的。您将需要一个自定义对象来进行绘画。这个自定义对象将包含两个属性:

  1. 圆对象

  2. Circle 对象的颜色。

或者另一种选择是直接绘制 BufferedImage,然后在面板中显示 BufferedImage。


查看完整回答
反对 回复 2023-09-13
?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

我得到了相同的结果,但有一个例外,代码如下:


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

        });

    }

}



查看完整回答
反对 回复 2023-09-13
  • 2 回答
  • 0 关注
  • 81 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信