0

Okay, so I'm trying to make a program that draws a bunch of rectangles that move around the screen randomly. I have a Dot class where each dot holds its x and y values, and in my paint class I randomly change the x and y values and then repaint(). What I have right now doesn't load any thing other than a blank JFrame. I suspect that I'm drawing each dot wrong. The following is my code:

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

Dot class:

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

}

Any and all help is appreciated.

1
  • Doe your ActionListener ever trigger? Did you debug your code? Commented Nov 15, 2018 at 16:36

2 Answers 2

2

If you call super.paintComponent(g); after you paint your own components you have wiped out your own painting. So,

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

Also,

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

and

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

and it probably doesn't make any difference, but

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            Movement mf = new Movement();
        }
    });
Sign up to request clarification or add additional context in comments.

Comments

0

You appear to be calling super.paintComponent after you paint dots. Not only that, you appear to be calling it inside the loop, calling it every time you paint a dot, after you paint it.

So you keep painting a dot, letting super.paintComponent paint a clear panel, then painting another dot, then undoing it again, paint another, undo... and so on.

Call super.paintComponent one time, and do it before you do your custom painting.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.