用延迟绘制图形

huangapple go评论59阅读模式
英文:

Draw shapes with delay

问题

我知道已经有成百上千的帖子,但我就是理解不了…
我有一个非常简单的类,用于绘制一个网格。我想在每个方块之后添加0.2秒的延迟。Thread.sleep不起作用。有什么最简单的方法吗?

    public Screen() {
        repaint();
    }
    public void paint(Graphics g) {

        for(int i = 0; i < 9; i++) {
            for(int j = 0; j < 9; j++) {
                g.drawRect(50 * i, 50 * j, 50, 50);
                //添加延迟
            }
        }
    }
英文:

I know there are already hundreds of threads but I just cant understand it..
I have this very simple class thats drawing a grid. I would like to add like a 0.2 second delay after each square. Thread.sleep doesnt work. What is the simplest way?

    public Screen() {
        repaint();
    }
    public void paint(Graphics g) {

        for(int i = 0; i &lt; 9; i++) {
            for(int j = 0; j &lt; 9; j++) {
                g.drawRect(50 * i, 50 * j, 50, 50);
                //Add delay
            }
        }
    }

</details>


# 答案1
**得分**: 3

以下是您要求的翻译内容:

最简单的实现延迟绘图的方法是使用 [`Swing Timer`](https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html),这是一个不会在执行时阻塞 [EDT](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html) 的类。这将允许您创建延迟,而不会阻塞用户界面(使所有内容立即显示)。

您将有一个单独的 `JPanel`,它将在 `paintComponent(...)` 方法中处理绘图,而不是像您在上面的代码中所做的那样在 `paint(...)` 中处理。这个 `JPanel` 将重新绘制来自 [`Shape`](https://docs.oracle.com/javase/7/docs/api/java/awt/Shape.html) API 的每个 `Rectangle` 形状。

```java
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class DelayedDrawing {
    private JFrame frame;
    private JPanel pane;
    private Timer timer;
    private int xCoord = 0;
    private int yCoord = 0;
    private static final int GAP = 10;
    private static final int WIDTH_HEIGHT = 10;
    private static final int ROWS = 5;
    private static final int COLS = 5;
    
    private List<Rectangle> rectangles;
    
    @SuppressWarnings("serial")
    private void createAndShowGUI() {
        // 创建 JFrame
        frame = new JFrame(this.getClass().getSimpleName());
        // 创建一个基于 Shape API 的 Rectangle 列表
        rectangles = new ArrayList<>();
        createRectangle();
        
        // 创建用于绘制每个矩形的 JPanel
        pane = new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(150, 150);
            }
            
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                for (Rectangle r : rectangles) {
                    System.out.println(r.x + " " + r.y);
                    g2d.draw(r);
                }
            }
        };
        
        // 启动定时器
        timer = new Timer(200, listener);
        timer.setInitialDelay(1000);
        timer.start();
        
        // 将所有内容添加到 frame
        frame.add(pane);
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    
    private void createRectangle() {
        Rectangle r = new Rectangle(xCoord * WIDTH_HEIGHT + GAP, yCoord * WIDTH_HEIGHT + GAP, WIDTH_HEIGHT, WIDTH_HEIGHT);
        rectangles.add(r);
    }
    
    private ActionListener listener = e -> {
        if (xCoord < ROWS) {
            if (yCoord < COLS) {
                yCoord++;
            } else {
                yCoord = 0;
                xCoord++;
                if (xCoord == ROWS) {
                    timer.stop();
                    return;
                }
            }
        }
        createRectangle();
        pane.repaint();
    };
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new DelayedDrawing()::createAndShowGUI);
    }
}

希望这对您有所帮助。

英文:

The simplest way to achieve delayed drawing is by using a Swing Timer, which is a class that won't block the EDT when executed. This will allow you to create a delay without blocking your UI (and making everything appear at once).

You'll have a single JPanel that's going to handle the painting in the paintComponent(...) method and not paint(...) as you did in your code above. This JPanel will repaint every Rectangle shape from the Shape API.

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class DelayedDrawing {
	private JFrame frame;
	private JPanel pane;
	private Timer timer;
	private int xCoord = 0;
	private int yCoord = 0;
	private static final int GAP = 10;
	private static final int WIDTH_HEIGHT = 10;
	private static final int ROWS = 5;
	private static final int COLS = 5;
	
	private List&lt;Rectangle&gt; rectangles;
	
	@SuppressWarnings(&quot;serial&quot;)
	private void createAndShowGUI() {
		//We create the JFrame
		frame = new JFrame(this.getClass().getSimpleName());
		//We create a list of Rectangles from the Shape API
		rectangles = new ArrayList&lt;&gt;();
		createRectangle();
		
		//Creates our JPanel that&#39;s going to draw every rectangle
		pane = new JPanel() {
			//Specifies the size of our JPanel
			@Override
			public Dimension getPreferredSize() {
				return new Dimension(150, 150);
			}
			
			//This is where the &quot;magic&quot; happens, it iterates over our list and repaints every single Rectangle in it
			@Override
			protected void paintComponent(Graphics g) {
				super.paintComponent(g);
				Graphics2D g2d = (Graphics2D) g;
				for (Rectangle r : rectangles) {
					System.out.println(r.x + &quot; &quot; + r.y);
					g2d.draw(r);
				}
			}
		};
		
		//This starts our Timer
		timer = new Timer(200, listener);
		timer.setInitialDelay(1000);
		timer.start();
		
		//We add everything to the frame
		frame.add(pane);
		frame.pack();
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	//Creates a new Rectangle and adds it to the List
	private void createRectangle() {
		Rectangle r = new Rectangle(xCoord * WIDTH_HEIGHT + GAP, yCoord * WIDTH_HEIGHT + GAP, WIDTH_HEIGHT, WIDTH_HEIGHT);
		rectangles.add(r);
	}
	
	//This will be executed everytime the Timer is fired
	private ActionListener listener = e -&gt; {
		if (xCoord &lt; ROWS) {
			if (yCoord &lt; COLS) {
				yCoord++;
			} else {
				yCoord = 0;
				xCoord++;
				if (xCoord == ROWS) {
					timer.stop();
					return;
				}
			}
		}
		createRectangle();
		pane.repaint();
	};
	
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new DelayedDrawing()::createAndShowGUI);
	}
}

用延迟绘制图形

huangapple
  • 本文由 发表于 2020年5月29日 04:41:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/62074141.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定