简体   繁体   English

小程序闪烁

[英]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). 我可能应该使用JApplet,JFrames和JPanel来执行此项目,但是在继续使用Japplet之前,我想先使用Applet进行一个项目(我想看看两者之间的区别)。 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. Applet (以及所有顶级容器)没有双重缓冲,这意味着您将直接绘制到屏幕设备上。 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. 话虽如此,Applet已过时15年, JApplet和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. 相反,您应该开始在JPanel类的对象上创建UI,并覆盖它的paintComponent方法,然后在此处进行自定义绘制。

Swing components are double buffered by default, so you don't need to go to the extra trouble...unless you really, really want to 默认情况下,Swing组件是双缓冲的,因此,您无需麻烦……除非您真的非常希望

You can then add this to whatever top level container you like JFrame , JWindow , JDialog , JApplet 然后,您可以将其添加到喜欢的任何顶级容器中,如JFrameJWindowJDialogJApplet

Take a look at Performing Custom Painting for more details 请看表演自定义绘画以了解更多详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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