Java AWT Как рисовать объекты с задержкой - PullRequest
0 голосов
/ 27 апреля 2019

Я хотел бы рисовать новую случайную форму каждые 2 секунды.

У меня уже есть окно, которое показывает сразу несколько фигур. Я пытался возиться с Timer, чтобы через несколько секунд появилось что-то новое в окне, но это не сработало, или вся программа зависла. Это хорошая идея, чтобы использовать таймер? Как мне это реализовать, чтобы она работала?

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

Я также хотел бы нарисовать несколько случайных фигур. Можно ли использовать переключатель в методе рисования для этой цели? Я бы сделал случайную переменную, если это 1, то это нарисовало бы прямоугольник, если это 2, то это нарисовало бы овал и т. Д.

Ответы [ 2 ]

0 голосов
/ 27 апреля 2019

Прежде всего, не меняйте способ рисования JFrame (другими словами, не переопределяйте paintComponent() из JFrame). Создайте расширяющий класс JPanel и нарисуйте JPanel. Во-вторых, не переопределяйте метод paint(). Переопределить paintComponent(). В-третьих, всегда запускайте приложения Swing с SwingUtilities.invokeLater(), поскольку они должны запускаться в своем собственном потоке с именем EDT (Поток диспетчеризации событий). Наконец, javax.swing.Timer - это то, что вы ищете.

Взгляните на этот пример. Он рисует овальную форму в случайных X, Y каждые 1500 мс.

Предварительный просмотр:

preview

Исходный код:

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));
    }
}
0 голосов
/ 27 апреля 2019

Во-первых, не делайте подкласс JFrame;вместо этого создайте подкласс JPanel и поместите эту панель в JFrame.Во-вторых, не переопределяйте paint () - вместо этого переопределяйте paintComponent ().В-третьих, создайте таймер Swing и в его методе actionPerformed () внесите необходимые изменения, а затем вызовите yourPanel.repaint ()

...