1

Good day, I'm new to StackOverflow and Java programming. I currently have a school project that needs multi threading and I just need your advice on how to fix my code. I have spent too much time looking for answers on how to create a moving multiple images using a thread. I knew I'm almost near to find the solution but I'm running out of time as the submission is fast approaching. I believed I'll be more efficient if I seek help from somehow who knows better in Java.

Many thanks in advance.

Below is my current code, and it seems that image is flickering while moving.

// Bounce.java

import javax.swing.JFrame;
public class Bounce {

    public static void main(String args[]) {
        myBall s = new myBall(10, 20, 2, 2);
        myBall s1 = new myBall(100, 10, 2, 2);
        myBall s2 = new myBall(40, 10, 2, 2);
        JFrame f = new JFrame();
        f.add(s);
        f.add(s1);
        f.add(s2);
        f.setVisible(true);
        f.setSize(600, 400);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setTitle("Moving Ball");
    }   
}

The next code is in separate file.

// myBall.java

import java.awt.*;
import java.awt.geom.Ellipse2D;    
import javax.swing.*;

public class myBall extends JPanel implements Runnable {
    private Thread animator;
    int x = 0, y = 0, velX = 2, velY = 2;
    Timer t;

    public myBall(int x, int y, int velX, int velY) {
        JFrame jf = new JFrame();
        jf.setSize(600,400);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.add(this);
        jf.setVisible(true);

        this.x = (int )(Math.random() * 560);
        this.y = (int )(Math.random() * 360);
        this.velX = velX;
        this.velY = velY;
    }

    @Override
    public void addNotify() {
        super.addNotify();
        animator = new Thread(this);
        animator.start();

    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        Ellipse2D ellipse = new Ellipse2D.Double(x, y, 40, 40);
        g2.fill(ellipse);       
    }

    public void cycle() {
        if(x < 0 || x > 560) {
            velX = -velX;
        }
        if(y < 0 || y > 360) {
            velY = -velY;
        }
        x += velX;
        y += velY;
        System.out.println(x);
    }

    @Override
    public void run() {
        while(true) {
            for (int i = 0; i < 600; i++) {
                cycle();
                repaint();

                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    System.out.println("interrupted");
                }
            }   
        }


    }

}    
Rajeev Sreedharan
  • 1,753
  • 4
  • 20
  • 30
  • The first thing to realize is that every time you create a new ball, you're also creating a new JFrame. This is why you have 3 frames running. Your gui class breaks the Single Responsibility principle - it controls the GUI and also creates new balls. I would create a Gui class and then a ball class. – Nick Ziebert Apr 04 '17 at 01:31

1 Answers1

1

Here you go. I normally don't do this, but you asked nicely and your code was pretty clean, so I assumed you been working a lot on it.

public class Start {

    public static void main(String args[]) {
        JFrame f = new JFrame();
        Gui gui = new Gui();
        gui.addBalls();
        f.add(gui);

        f.setSize(600, 400);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setTitle("Moving Ball");
        f.setVisible(true);
    }   
}

Class GUI:

public class Gui extends JPanel implements Runnable {
    private Thread animator;
    int x = 0, y = 0, velX = 2, velY = 2;
    Timer t;

    ArrayList<myBall> myBalls = new ArrayList<>();

    @Override
    public void addNotify() {
        super.addNotify();
        animator = new Thread(this);
        animator.start();

    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        for (myBall ball: myBalls) {
            int x = ball.getX();
            int y = ball.getY();
            Ellipse2D ellipse = new Ellipse2D.Double(x, y, 40, 40);
            g2.fill(ellipse); 
        }
    }

    public void cycle() {
        for (myBall ball: myBalls) {
            int x = ball.getX();
            int y = ball.getY();

            if(x < 0 || x > 560) {
                ball.reverseX();
            }
            if(y < 0 || y > 360) {
                ball.reverseY();
            }

            ball.move();
            System.out.println(x);
        }
    }

    @Override
    public void run() {
        while(true) {
            for (int i = 0; i < 600; i++) {
                cycle();
                repaint();

                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    System.out.println("interrupted");
                }
            }   
        }
    }

    public void addBalls() {
        for (int i = 0; i < 4; i++) {
            int x = (int )(Math.random() * 560);
            int y = (int )(Math.random() * 360);
            int velX = -5;
            int velY = 5;
            myBalls.add(new myBall(x, y, velX, velY));
        }
    }
}

Class Ball:

public class myBall {

    int x;
    int y;
    int velX;
    int velY;


    public myBall(int x, int y, int velX, int velY) {
        this.x = (int )(Math.random() * 560);
        this.y = (int )(Math.random() * 360);
        this.velX = velX;
        this.velY = velY;
    }

    public void move() {
        x+=velX;
        y+=velY;

    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public void reverseX() {
        velX = -velX;
    }

    public void reverseY() {
        velY = -velY;
    }
}
Nick Ziebert
  • 1,258
  • 1
  • 9
  • 17
  • that was awesome! Thank you so much for this! Works perfectly. I actually have the Traffic Light Simulation project and I just wanted to learn how thread and moving object works so I can learn to do my actual project on my own. Really wanted to learn Java and you really saved my day. Thanks heaps! =) – newProgramm3r Apr 04 '17 at 02:06