Search code examples
javaswinggraphicsjapplet

Java JApplet doesn't remove an old rectangle once it is moved


I am new to graphics and japplets, and I made a rectangle that goes across the screen. But for some reason, it just draws a line across, not removing the old instance of the rectangle once it moves.

Main:

public class Main extends JApplet implements Runnable {
    private static final long serialVersionUID = 1L;
    private static int width = 900;
    private static int height = 600;
    public static int fps = 60;
    public Thread thread = new Thread(this);
    public static Ailoid ailoid = new Ailoid();

    public void init() {
        setSize(width, height);
        setBackground(Color.white);

        ailoid.setLocation(new Location(100, 100));
        AlienManager.registerAlien(ailoid);
    }

    public void paint(Graphics g) {
        g.setColor(Color.green);
        for (Alien alien : AlienManager.getAliens()) {
            Location loc = alien.getLocation();
            int x = loc.getX();
            int y = loc.getY();
            g.fillRect(x, y, 10, 20);
        }
    }

    // Thread start
    @Override
    public void start() {
        thread.start();
    }
    // Thread stop
    @SuppressWarnings("deprecation")
    @Override
    public void destroy() {
        thread.stop();
    }

    @Override
    public void run() {
        while (true) {
            Updater.run();
            repaint();
            try {
                // 1000 divided by fps to get frames per millisecond
                Thread.sleep(1000 / fps);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Updater:

public class Updater {
    public static void run() {
        for (Alien alien : AlienManager.getAliens()) {
            Location loc = alien.getLocation();
            int x = loc.getX();
            int y = loc.getY();
            alien.setLocation(new Location(x, y));
        }
    }
}

Why doesn't it remove the old graphics? thank you!


Solution

  • Your main problem is that your paint(...) method does not call the super method, the method that allows the component to redraw its contents:

    public void paint(Graphics g) {
        super.paint(g);
        //....
    

    Having said that, you're far better off not drawing in a top level window but rather in the paintComponent method of a JPanel that is displayed by the applet. If you do this correction, then do the same thing -- call the super method.

    class MyPanel extends JPanel {
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            //....
    

    As an aside, this code:

    public class Updater {
        public static void run() {
            for (Alien alien : AlienManager.getAliens()) {
                Location loc = alien.getLocation();
                int x = loc.getX();
                int y = loc.getY();
                alien.setLocation(new Location(x, y));
            }
        }
    }
    

    Doesn't look like it's moving things all that much. In fact per this code, your aliens should stay completely still.


    Edit
    Also, this is never code, code you should never have in your application:

    @SuppressWarnings("deprecation")
    @Override
    public void destroy() {
        thread.stop();
    }
    

    There's a reason that thread's stop() method is deprecated and should never be called. If you're curious as to why, please check out the API.