Java图形-如何增加绘画调用之间的延迟以创建动画?

时间:2019-04-18 21:31:31

标签: java

我正在用Java设计一个简单的分形程序,该程序将从绘制一个矩形开始,然后递归地在每个角上绘制大小为1/4的矩形。这将在所有方向上重复并跨越,直到尺寸收敛到0。

到目前为止,我的程序和设计已完全正常运行;但是,我正在添加不确定该怎么做的内容。当我运行程序时,分形在弹出的JFrame中显示为已完成。我想做的是让每个矩形单独显示,并且每个被绘制之间的延迟很短。

我的main方法有一个类,该类仅实例化GUI对象并调用其run()方法。在大多数情况下,所有相关代码都存在于这两个文件中。

在GUI类中

public GUI()
 {
      Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
      fractal = new Fractal(this, screenSize.width, screenSize.height);

      this.setTitle("Fractals");
      this.setSize(screenSize.width, screenSize.height);
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      this.getContentPane().add(fractal);
      this.setFocusable(true);
      this.setVisible(true);
 }

 public void run()
 {
      fractal.repaint();
 }

在“分形”课程中

public Fractal(GUI gui, int width, int height)
 {
      this.gui = gui;
      this.screenWidth = width;
      this.screenHeight = height;
 }

 @Override
 protected void paintComponent(Graphics g)
 {
      super.paintComponent(g);

      /* Calculate coordinates and dimensions */
      int x = 3 * this.screenWidth / 8;
      int y = 3 * this.screenHeight / 8;
      int width = this.screenWidth / 4;
      int height = this.screenHeight / 4;

      /* Draw the center rectangle */
      g.setColor(Color.BLACK);
      g.fillRect(x, y, width, height);

      /* Adjust dimensions for next rectangles */
      width /= 2;
      height /= 2;

      /* Draw rectangles at the corners */
      drawTopLeft(g, x - width, y - height, width, height);
      drawBottomLeft(g, x - width, y + (2 * height), width, height);
      drawTopRight(g, x + (2 * width), y - height, width, height);
      drawBottomRight(g, x + (2 * width), y + (2 * height), width, height);
 }

 public void drawTopLeft(Graphics g, int x, int y, int width, int height)
 {
      /* Ensure the boundaries lay within the screen */
      if(x > 0 && y > 0)
      {
           /* Draw itself */
           g.fillRect(x, y, width, height);

           /* Adjust dimensions for next rectangles */
           width /= 2;
           height /= 2;

           /* Draw rectangles at the corners */
           if(width > 0 && height > 0)
           {
                drawTopLeft(g, x - width, y - height, width, height);
                drawBottomLeft(g, x - width, y + (2 * height), width, height);
                drawTopRight(g, x + (2 * width), y - height, width, height);
           }
      }
 }

 public void drawBottomLeft(Graphics g, int x, int y, int width, int height)
 {
      /* Ensure the boundaries lay within the screen */
      if(x > 0 && y + height < screenHeight)
      {
           /* Draw itself */
           g.fillRect(x, y, width, height);

           /* Adjust dimensions for next rectangles */
           width /= 2;
           height /= 2;

           /* Draw rectangles at the corners */
           if(width > 0 && height > 0)
           {
                drawTopLeft(g, x - width, y - height, width, height);
                drawBottomLeft(g, x - width, y + (2 * height), width, height);
                drawBottomRight(g, x + (2 * width), y + (2 * height), width, height);
           }
      }
 }

 public void drawTopRight(Graphics g, int x, int y, int width, int height)
 {
      /* Ensure the boundaries lay within the screen */
      if(x + width < screenWidth && y > 0)
      {
           /* Draw itself */
           g.fillRect(x, y, width, height);

           /* Adjust dimensions for next rectangles */
           width /= 2;
           height /= 2;

           /* Draw rectangles at the corners */
           if(width > 0 && height > 0)
           {
                drawTopLeft(g, x - width, y - height, width, height);
                drawTopRight(g, x + (2 * width), y - height, width, height);
                drawBottomRight(g, x + (2 * width), y + (2 * height), width, height);
           }
      }
 }

 public void drawBottomRight(Graphics g, int x, int y, int width, int height)
 {
      /* Ensure the boundaries lay within the screen */
      if(x + width < screenWidth && y + height < screenHeight)
      {
           /* Draw itself */
           g.fillRect(x, y, width, height);

           /* Adjust dimensions for next rectangles */
           width /= 2;
           height /= 2;

           /* Draw rectangles at the corners */
           if(width > 0 && height > 0)
           {
                drawBottomLeft(g, x - width, y + (2 * height), width, height);
                drawTopRight(g, x + (2 * width), y - height, width, height);
                drawBottomRight(g, x + (2 * width), y + (2 * height), width, height);
           }
      }
 }

这是输出生成的内容。

The fractal generation

1 个答案:

答案 0 :(得分:1)

您需要在paintComponent方法之外计算每个矩形。随后的每一个都应存储在数组或列表或某些数据结构中。然后调用repaint并睡眠1秒钟(但不要在paintComponent方法中睡眠)。

然后您的paintComponent方法必须遍历矩形列表并绘制每个矩形。因此,每次调用重画时,都会先绘制旧的,再绘制新的。

最重要的是,不要在paintComponent上进行太多处理,否则在EDT中运行的任何其他方法将使您的应用程序变得无响应或无法正常工作。

还有一件事。除非您退出方法,否则您在paintComponent中所做的任何绘图都将不可见。

我之前没有看到您的图片。如果要绘制曲线或对角线,则在绘制之前在paintComponent中设置以下内容。它将使图形变得平滑。

Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);