Как рисовать объекты из ArrayList в Java

Итак, я пытаюсь создать программу, которая рисует группу прямоугольников, которые случайным образом перемещаются по экрану. У меня есть класс Dot, в котором каждая точка содержит свои значения x и y, а в моем классе рисования я случайным образом меняю значения x и y, а затем перерисовываю (). То, что у меня есть прямо сейчас, не загружает ничего, кроме пустого JFrame. Подозреваю, что рисую каждую точку неправильно. Вот мой код:

import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;

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

public class Movement extends JFrame {
    public ArrayList<Dot> dots = new ArrayList<Dot>();
    Random rn = new Random();
    DrawPanel drawPanel = new DrawPanel();
    public Movement() {
        for(int i = 0; i < 100; i ++) {
            Dot dot = new Dot(5, 5);
            dots.add(dot);
        }
        ActionListener listener = new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                    for(int i = 0; i < dots.size();i++) {
                        dots.get(i).setX(dots.get(i).getX() + rn.nextInt(20)-10);
                        dots.get(i).setY(dots.get(i).getY() + rn.nextInt(20)-10);
                    }
                    drawPanel.repaint();

            }
        };
        Timer timer = new Timer(100, listener);
        timer.start();
        add(drawPanel);

        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
        setBounds(100, 100, 500, 500);
    }

    private class DrawPanel extends JPanel {

        protected void paintComponent(Graphics g) {
             for(int i = 0; i < dots.size(); i ++) {
                g.fillRect(dots.get(i).getX(), dots.get(i).getY(), 5, 5);;
                super.paintComponent(g);
             }


        }

    }
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Movement();
            }
        });
    }
}

Класс точки:

public class Dot {
    private int x, y;
    public Dot(int x, int y) {
        this.x = x;
        this.y = y;

    }
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }

}

Любая помощь приветствуется.

Ваш ActionListener когда-нибудь срабатывает? Вы отлаживали свой код?

Mena 15.11.2018 17:36
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
1 168
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если вы вызовете super.paintComponent(g); после того, как раскрасите свои собственные компоненты, вы уничтожите свою собственную картину. Так,

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D)g;
         for(int i = 0; i < dots.size(); i ++) {
             g2d.fillRect(dots.get(i).x, dots.get(i).y, 5, 5);
         }
    }

Также,

// don't repeat type in constructor
// use built in point instead of custom class
public ArrayList<Point> dots = new ArrayList<>();

и

    ActionListener listener = new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
                for(int i = 0; i < dots.size();i++) {
                    dots.get(i).x = dots.get(i).x + rn.nextInt(20)-10;
                    dots.get(i).y = dots.get(i).y + rn.nextInt(20)-10;
                }
                drawPanel.repaint();
        }
    };

и это, вероятно, не имеет никакого значения, но

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            Movement mf = new Movement();
        }
    });

Похоже, вы называете super.paintComponentпосле, вы рисуете точки. Мало того, вы, кажется, вызываете его внутри цикла, называя его каждый раз, когда вы рисуете точку, после того, как вы его рисуете.

Итак, вы продолжаете рисовать точку, позволяя super.paintComponent нарисовать прозрачную панель, затем закрашиваете другую точку, затем снова удаляете ее, рисуете еще одну, отменяете ... и так далее.

Позвоните super.paintComponent один раз и сделайте это перед тем, как рисовать на заказ.

Другие вопросы по теме