Hi, I've started to learn about threads in java. I'm trying to make this simple animation of a rectangle. Where am I going wrong? I was under the impression that if a class implements Runnable, when it is executed, it looks for the start method, which in turn starts the thread and run() is executed. Should I be overriding the start method? I saw that the thread.stop() is now deprecated so I'm skeptical about anything I'm doing now because I must have learnt from an old version of java.

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.util.ArrayList;
import javax.swing.JPanel;

public class AnimationWithThreads extends JPanel implements Runnable {

Thread t;
private int x,y,dx=2,dy=2;

public AnimationWithThreads(){
   
    x=50;
    y=50;
}

    public void start(){
        if(t==null){
             t = new Thread(this);
         t.start();
        }

    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.fillRect(x, y, 40, 40);

    }

    public void run() {   
        x+=dx;
        y+=dy;
        repaint();     
    }



}

how are you running this piece of code? where is the main method

how are you running this piece of code? where is the main method

Its in a separate class, here it is:

public class Main extends JFrame {

    public static void main(String[] args){
       Main m = new Main();
       AnimationWithThreads a = new AnimationWithThreads();
       a.start();
       m.add(a);
        m.setSize(800,600);
        m.setTitle("HEllo");
        m.setDefaultCloseOperation(EXIT_ON_CLOSE);
        m.setVisible(true);
    }


}

Anybody still here?

IF your class extends Thread the it inherits the start() method, and you can start it. Otherwize you need a new Thread(yourRunnableInstance) and start that.

So in my main method, I should have something like:

Thread myThread = new Thread(new AnimationWithThreads());
myThread.start();

Or am I totally wrong?

run() runs only one time

run() runs only one time

How do I change that?

I thought once a thread is started it keeps going until the app exits.

public void run() {
        while (true) {
            x += dx;
            y += dy;
            repaint();
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                //
            }
        }
    }
public void run() {
        while (true) {
            x += dx;
            y += dy;
            repaint();
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                //
            }
        }
    }

Am I right in thinking the 'true' refers to if the thread is running? Also, is it always required to make the thread sleep inside the run method? What is the purpose of this? Does it just control how long it takes for the other code to execute each time?

EDIT: Also, am I right in thinking that I only need to override the start method when I inherit from the Thread class?

Once a thread is started it executes "until the app exits" OR until the run method terminates normally. Unless the run method contains an infinite loop sooner or later it will either execute a "return" statement, or it will drop out of its last statement (or throw an Exception).
The "true" in quuba's code just ensures the loop keeps on running until something else stops it.
The idea of the sleep is to control the speed at which the repaints happen - ie if we flatten the loop it goes
repaint
sleep 100 mSec
repaint
sleep 100 mSec
etc
Without the sleep the JVM will execute repaints as fast as the CPU can go, and this will make it animate far too fast, and it will be difficult or impossible for any other threads to execute.
You don't need to override Thread's start() - just call it.

Having answered all those questions, I now have to tell you that, depending on what else is going to be in your app, this is probably the wrong way to do this (sorry). You can stay with this a bit longer, and you should be able to get a basic animation running, and you will learn good stuff about how Java threads work.
If/when you run into serious problems you can switch your code to use the recommended approach (Swing Timer) to run your animation. This uses and integrates properly with the threading already built into Swing - but if you haven't already mastered the basics of ordinary threads you will find it hard to understand what Swing threads & timers are doing.

Yes well I'm not doing any serious coding here, I just wanted to learn how to start threads etc. Thanks for the help, both of you.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.