2

I am trying to move a ball in applet using thread but its not moving. Can anyone help me out as m new to applet and proceeding for game development..for reference here is my code

public class ballGame extends JApplet implements Runnable
{
    int x_pos=50;
    int y_pos=100;
    int rad=10;
    Thread t;

    public void start() 
    {
        super.start();
        t=new Thread("t");
        t.start();
    }

    public void paint(Graphics g) 
    {
        super.paint(g);
        g.setColor(Color.red);
        setBackground(Color.BLACK);
        g.drawOval(x_pos,y_pos,2*rad,2*rad); 

        while(true)
        {
            x_pos++;

            //validate();
            repaint();

            try
            {
                Thread.sleep(100);
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }

        }//end of while
    }//end of paint()
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
anup navare
  • 21
  • 1
  • 1
  • 4
  • This [answer](http://stackoverflow.com/a/9852739/1057230), might be a good learning step in the given direction. – nIcE cOw Jan 22 '13 at 14:03

6 Answers6

2

Having an infinite loop in paint means that not a single pass of the method can complete.

Also you should never call Thread.sleep(100) in the paint method. This blocks the EDT and degrades performance.

Instead use a Swing Timer to do the update and repainting work. Also I would sub-class a JComponent and override paintComponent.

Reimeus
  • 158,255
  • 15
  • 216
  • 276
2

Swing is a single thread environment. That is, all updates and interactions are executed within a single thread. Swing is also NOT thread safe. This means that all updates to the UI MUST be executed within the context of that thread (the Event Dispatching Thread or ETD).

Any code that blocks the EDT will prevent it from (amongst other things), repainting the UI and responding to input from the user.

You're paint code will NEVER update the screen, in fact it will make your application appear to "hang", as the paint method isn't being allowed to complete and is blocking the ETD.

It is an exception that the paint method will return quickly after been called and may be called repeatedly in quick succession.

Generally speaking, a Thread is probably a little over kill, something like a javax.swing.Timer would be more then suitable under these circumstances.

enter image description here

public class AnimatedBoat {

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

    public AnimatedBoat() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new AnimationPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class AnimationPane extends JPanel {

        private BufferedImage boat;
        private int xPos = 0;
        private int direction = 1;

        public AnimationPane() {
            try {
                boat = ImageIO.read(new File("boat.png"));
                Timer timer = new Timer(40, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        xPos += direction;
                        if (xPos + boat.getWidth() > getWidth()) {
                            xPos = getWidth() - boat.getWidth();
                            direction *= -1;
                        } else if (xPos < 0) {
                            xPos = 0;
                            direction *= -1;
                        }
                        repaint();
                    }

                });
                timer.setRepeats(true);
                timer.setCoalesce(true);
                timer.start();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return boat == null ? super.getPreferredSize() : new Dimension(boat.getWidth() * 4, boat.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            int y = getHeight() - boat.getHeight();
            g.drawImage(boat, xPos, y, this);

        }

    }

}

As a side note. You should rarely need to override the paint method of a top level container like JApplet or JFrame, while there are a number of good reasons for this, the one that you're going to most interested in is the fact that they're not double buffered, meaning you are likely to see flickering as the screen is updated.

It's better to use something like JPanel and override it's paintComponent method instead.

Take a look at

For more information

nb While I've used a JFrame for my example, it would be a simple matter to take the animation panel and put it into a JApplet, this is another reasons why you don't need/want to extend from top level containers ;)

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
1

You can not invoke repaint() method inside paint(). And you can not organize infinitely loop inside paint() method - doing so, you are blocking drawing in your applet.

Andremoniy
  • 34,031
  • 20
  • 135
  • 241
0

Have the while loop inside the run method of Runnable.

UPDATE:

Have this in the start method.

t=new Thread(this);
t.start();
shazin
  • 21,379
  • 3
  • 54
  • 71
0

x_posis an int value, thus it is passed to methods by value, not by reference. That is why, when you change its value, the value inside of your circle is not updated...

pushy
  • 9,535
  • 5
  • 26
  • 45
0

You create a Thread without a run() method. This method should contain the runnable code... Furthermore, the paint() method is to paint stuff, not update stuff!

So move your while loop from the paint() method into the run() method of your thread:

t=new Thread("t") {
    @Override
    public void run()
    {
        while(true)
        {
            x_pos++;

            //validate();
            repaint();

            try
            {
                Thread.sleep(100);
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }//end of while
    }
};

Note that ballGame does not require the implement Runnable part. As the thread you created will provide it.

Veger
  • 37,240
  • 11
  • 105
  • 116
  • Actually I have written run() and was writing while loop in that only but it was not working...Still i will try again..thanks fr ur help – anup navare Jan 22 '13 at 10:32
  • I suppose you wrote the `run()` method directly in the `ballGame` class... You should put it in the `Thread` in order to add functionality to the `Thread`, otherwise it won't do a thing! – Veger Jan 22 '13 at 10:34
  • And implementing runnable is required I think otherwise run() will show error – anup navare Jan 22 '13 at 10:35
  • As I said you should remove the `implements Runnable` part of your class definition. – Veger Jan 22 '13 at 10:38
  • Putting run()in thread means exactly where can u just tell me please – anup navare Jan 22 '13 at 10:40
  • My answer shows how to do it: Just replace `t=new Thread("t");` with the provided code. – Veger Jan 22 '13 at 10:43
  • but t=new Thread("t") is in start method shall i write run() in it as you have written in code – anup navare Jan 22 '13 at 10:48
  • Good! You really need to read upon `JApplet` and `Thread` so you know what these methods are used for! – Veger Jan 22 '13 at 10:53
  • but why the same code written inside run() didnt work can u tell – anup navare Jan 22 '13 at 10:58
  • Because `JApplet` does not care about the `run()` method. It is just like any other custom method you could add to the `ballClass`. – Veger Jan 22 '13 at 11:06