Rob
Rob

Reputation: 15992

Java : Need some help to use Threads and Graphics simultaneously

As a beginner at this, I still need some explanations of how to use Threads and Graphics at the same time. What I want to do is very basic : only make two balls move simultaneously in a frame. Here is what I tried :

public class Main extends JFrame
{
    private static final long serialVersionUID = 1L;
    private static final int _HEIGHT = 320, _WIDTH = 480;
    private MyPanel panel;

    public Main()
    {
        super("Test");

        panel = new MyPanel();

        this.setContentPane(panel);
        this.setBounds(350,100,_HEIGHT,_WIDTH);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    public static void main(String[] args)
    {
        new Main();
    }
}


public class MyPanel extends JPanel
{
    private static final long serialVersionUID = 1L;
    ArrayList<Ball> listBalls;

    public MyPanel()
    {
        this.setBackground(Color.WHITE);
        listBalls = new ArrayList<Ball>();
        listBalls.add(new Ball(30,30));     
    }

    @Override
    public void paint(Graphics gr)
    {
        Graphics2D g = (Graphics2D) gr;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setStroke(new BasicStroke(3f));
        super.paint(g);
        synchronized (listBalls) {
            for(Ball b : listBalls)
            {
                b.drawItself(g);
            }   
        }
    }
}



public class Ball extends JPanel implements Runnable
{
    private static final long serialVersionUID = 1L;
    private int x, y;
    private Thread thread;

    public Ball(int x, int y)
    {
        this.x = x;
        this.y = y;
    }

    public void drawItself(Graphics2D g)
    {
        g.setColor(Color.BLACK);
        g.fillOval(x, y, 13, 13);
    }

    public void run() 
    {
        Thread currentThread = Thread.currentThread();
        while (thread == currentThread) 
        {
            x+=2;
            y+=2;
            repaint();
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

But this won't work (the balls don't appear), and I've no idea of what to do.. please help!

Upvotes: 1

Views: 2769

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347204

  1. There's no need for Ball to extend JPanel, you're not using any of the functionality from JPanel or it's children.
  2. You shouldn't override paint, it is recommended that you use paintComponent instead. Lots of reasons, but the one you will like is the fact that paint isn't double buffered, but paintComponent is - less likelihood of flickering
  3. If you must us a Thread, I would recommend that you use a single Thread and update ALL the balls in it and then update the display. This will generally reduce the number of resources you're using and make it more scalable.
  4. You never start your Thread, meaning the run method of Ball is never called

There are special concerns with concurrency in Swing. I would recommend taking a look at Concurrency in Swing for an overview.

Updated

There are a number of excellent examples to be found on SO, here are some I've done in the past...

Upvotes: 2

Related Questions