简体   繁体   English

Java AWT如何延迟绘制对象

[英]Java AWT How to draw objects with delay

I would like to draw a new random shape every 2 seconds. 我想每2秒绘制一个新的随机形状。

I already have a window, that shows immediately some shapes. 我已经有一个窗口,可以立即显示一些形状。 I tried to mess around with Timer to make new things appear in the window after a few seconds, but it didn't work, or the whole program freezes. 我试图弄乱Timer,使新的东西在几秒钟后出现在窗口中,但是它不起作用,或者整个程序死机了。 Is it a good idea to use Timer? 使用Timer是个好主意吗? How should I implement it, to make it work? 我应该如何实施它以使其起作用?

import javax.swing.*;
import java.awt.*;
import java.util.Random;

class Window extends JFrame {

    Random rand = new Random();
    int x = rand.nextInt(1024);
    int y = rand.nextInt(768);
    int shape = rand.nextInt(2);

    Window(){
        setSize(1024,768);
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(new Color(0, 52, 255));
        switch(shape) {
            case 0:
                g.fillOval(x, y, 50, 50);
                break;
            case 1:
                g.fillRect(x,y,100,100);
                break;
        }
        repaint();
    }
}

public class Main {
    public static void main(String[] args) {
        Window window = new Window();
    }
}

I would also like to draw some random shapes. 我也想画一些随机的形状。 Is it ok, to use switch in paint method for this purpose? 为此可以在涂料中使用开关吗? I would make a random variable, if it's 1 it would paint rectangle, if it's 2 it would paint oval etc. 我将创建一个随机变量,如果为1,则将绘制矩形,如果为2,则将绘制椭圆等。

First, don't subclass JFrame; 首先,不要继承JFrame; subclass JPanel instead, and place that panel in a JFrame. 子类化JPanel,然后将该面板放在JFrame中。 Second, don't override paint() - override paintComponent() instead. 其次,不要覆盖paint()-而是覆盖paintComponent()。 Third, create a Swing Timer, and in its actionPerformed() method make the changes you want and then call yourPanel.repaint() 第三,创建一个Swing Timer,并在其actionPerformed()方法中进行所需的更改,然后调用yourPanel.repaint()

First of all, do not change the way JFrame gets painted (with other words, do not override paintComponent() of a JFrame ). 首先,不要更改JFrame的绘制方式(换句话说,不要覆盖JFrame paintComponent() )。 Create an extending class of JPanel and paint the JPanel instead. 创建一个扩展的JPanel类,并绘制JPanel Secondly, do not override paint() method. 其次,不要重写paint()方法。 Override paintComponent() . 覆盖paintComponent() Thirdly, always run Swing applications with SwingUtilities.invokeLater() since they should run in their own thread named EDT (Event dispatch thread). 第三,始终使用SwingUtilities.invokeLater()运行Swing应用程序,因为它们应在自己的名为EDT(事件调度线程)的线程中运行。 Finally, javax.swing.Timer is what you are looking for. 最后,您正在寻找javax.swing.Timer

Take a look at this example. 看一下这个例子。 It paints an oval shape in random X,Y every 1500ms. 每1500毫秒随机绘制一次X,Y的椭圆形。

Preview: 预习:

预习

Source code: 源代码:

import java.awt.BorderLayout;
import java.awt.Graphics;

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

public class DrawShapes extends JFrame {
    private ShapePanel shape;

    public DrawShapes() {
        super("Random shapes");
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(shape = new ShapePanel(), BorderLayout.CENTER);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(500, 500);
        setLocationRelativeTo(null);

        initTimer();
    }

    private void initTimer() {
        Timer t = new Timer(1500, e -> {
            shape.randomizeXY();
            shape.repaint();
        });
        t.start();
    }

    public static class ShapePanel extends JPanel {
        private int x, y;

        public ShapePanel() {
            randomizeXY();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.fillOval(x, y, 10, 10);
        }

        public void randomizeXY() {
            x = (int) (Math.random() * 500);
            y = (int) (Math.random() * 500);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new DrawShapes().setVisible(true));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM