简体   繁体   中英

Applet flickering

I know a lot of people had the same problem as me, but I can't seem to able to fix my applet looking at their solutions. I should probably use JApplet, JFrames and JPanel to do this project but I want to do a project first with Applet before I move on to using Japplet(I want to see the difference between those two). Could someone please look at my paint method and see why it flickers? Can't seem to be able to double buffer it.

    import java.applet.*;

    import java.awt.*;

    import java.awt.event.*;


    import java.net.*;

public class Main extends Applet implements Runnable, KeyListener {
    private Ninja ninja;
    private Image character;
    private URL base;

    @Override
    public void init() {
        setSize(800, 480);
        setBackground(Color.WHITE);
        setFocusable(true);

        Frame frame = (Frame) this.getParent().getParent();
        frame.setTitle("NinjaGirl");
        addKeyListener(this);
        try {
            base = getDocumentBase();
        } catch (Exception e) {

        }
        character = getImage(base, "data/FrontStanding.png");
        super.init();

    }

    @Override
    public void start() {
        ninja = new Ninja();
        Thread thread = new Thread(this);
        thread.start();
        super.start();

    }

    @Override
    public void stop() {
        super.stop();
    }

    @Override
    public void destroy() {
        super.destroy();
    }

    @Override
    public void update(Graphics g) {
        super.update(g);


    }


    @Override
    public void paint(Graphics g) {


        g.drawImage(character, ninja.getCenterX(), ninja.getCenterY(), this);



    }

    @Override
    public void run() {
        while (true) {
            ninja.update();
            repaint();
            try {
                Thread.sleep(17);
            } catch (InterruptedException e) {

                e.printStackTrace();
            }

        }

    }

    @Override
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
        case KeyEvent.VK_UP:
            ninja.moveUp();
            System.out.println("Up key pressed");

            break;
        case KeyEvent.VK_DOWN:
            ninja.moveDown();
            break;
        case KeyEvent.VK_RIGHT:
            ninja.moveRight();
            break;
        case KeyEvent.VK_LEFT:
            ninja.moveLeft();
            break;
        }

    }

    @Override
    public void keyReleased(KeyEvent e) {
        switch (e.getKeyCode()) {
        case KeyEvent.VK_UP:
            ninja.stop();
            break;
        case KeyEvent.VK_DOWN:
            ninja.stop();
            break;
        case KeyEvent.VK_RIGHT:
            ninja.stop();
            break;
        case KeyEvent.VK_LEFT:
            ninja.stop();
            break;
        }

    }
    @Override
    public void keyTyped(KeyEvent arg0) {

    }

}

You're primary problem is here...

@Override
public void update(Graphics g) {
    super.update(g);
}


@Override
public void paint(Graphics g) {
    g.drawImage(character, ninja.getCenterX(), ninja.getCenterY(), this);
}

Applet (and all top level containers) is not double buffered, this means, you are drawing directly onto the screen device. Some of the these functions can be slow (flood fill for example) which, if done fast enough, can cause flickering.

Instead, you need to implement your own double buffering process

@Override
public void update(Graphics g) {
    GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    BufferedImage image = gc.createCompatibleImage(getWidth(), getHeight(), Transparency.OPAQUE);
    Graphics2D g2d = image.getGraphics();
    super.update(g2d);
    g2d.dispose();
    g.drawImage(image, 0, 0, this);
}


@Override
public void paint(Graphics g) {
    g.drawImage(character, ninja.getCenterX(), ninja.getCenterY(), this);
}

Now, having said that, Applet is over 15 years out of date and was replaced with JApplet and the Swing API.

Instead, you should start creating your UI on something like a JPanel and override it's paintComponent method and do your custom painting there.

Swing components are double buffered by default, so you don't need to go to the extra trouble...unless you really, really want to

You can then add this to whatever top level container you like JFrame , JWindow , JDialog , JApplet

Take a look at Performing Custom Painting for more details

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM