Java Applet 运行时闪烁?(不是每个人都看到闪烁) [英] Java Applet flickering when running? (not everybody sees flickering)

查看:23
本文介绍了Java Applet 运行时闪烁?(不是每个人都看到闪烁)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Java Applet,每次重绘 GUI 时它都会不断闪烁.大多数人看不到闪烁.其他人可以毫无问题地运行小程序,但我不能.

I have a Java Applet that is flickering constantly for me every time the GUI is redrawn. Most people don't see the flickering. Others are able to run the applet without any problems at all but I am not.

我不确定这是我重绘 UI 的方式的问题,还是我的 JRE 或其他方面的问题.我已经筋疲力尽地查找其他人的类似问题,但我还没有看到适用于此的答案.

I am not sure if this is a problem with the way in which I am redrawing the UI or if this is a problem with my JRE or what. I've exhausted myself looking up other people's similar problems but I have not yet seen an answer that applies here.

我已将我正在运行的小程序缩短到相对较小的一点.这只是一艘向右移动的火箭飞船,非常简单,而且(对我而言)它不断闪烁.

I have shortened the applet I am running down to a relatively small bit. This is just a rocket ship being moved to the right, pretty simple and (for me) it flickers constantly.

import java.applet.Applet;
import java.awt.Button;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;


public class Lander extends Applet implements KeyListener,ActionListener{

Button start;
Ship s;

private static final long serialVersionUID = 1L;
public void init(){
    s = new Ship(10,50);
    start = new Button("START");
    this.setSize(800,400);
    this.setBackground(Color.black);
    this.add(start);
    start.addActionListener(this);
}

public void paint(Graphics g){

    g.setColor(Color.LIGHT_GRAY);
    g.fillRoundRect(s.getx(),s.gety(), 10, 30, 10, 10);
    g.setColor(Color.GREEN);
    g.fillRoundRect(s.getx()-5, s.gety()+10, 5, 20, 10, 10);
    g.fillRoundRect(s.getx()+10, s.gety()+10, 5, 20, 10, 10);

}

javax.swing.Timer t = new javax.swing.Timer(30, new ActionListener(){
    public void actionPerformed(ActionEvent e){

        s.setx(s.getx()+2);
        repaint();
    }
});

public void keyPressed(KeyEvent e) {
}

public void keyReleased(KeyEvent arg0) {
}

public void keyTyped(KeyEvent arg0) {   
}

public class Ship{
    int xcor,ycor;

    public Ship(int x,int y){
        xcor=x;ycor=y;
    }
    public void setx(int x){
        xcor=x;
    }
    public void sety(int y){
        ycor=y;
    }
    public int getx(){
        return xcor;
    }
    public int gety(){
        return ycor;
    }
}

@Override
public void actionPerformed(ActionEvent x) {
    if(x.getSource()==start)
        reset();
        t.start();

}
public void reset(){
    s.setx(10);s.sety(50);
}

}

推荐答案

这是 Applet 没有以任何方式开始缓冲的结果.

This is a result of the Applet not begin buffered in any way.

你应该使用某种双缓冲...

You should employ some kind of double buffering...

例如...

@Override
public void paint(Graphics g) {
    BufferedImage bi = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics2D g2d = bi.createGraphics();

    super.paint(g2d);

    g2d.setColor(Color.LIGHT_GRAY);
    g2d.fillRoundRect(s.getx(), s.gety(), 10, 30, 10, 10);
    g2d.setColor(Color.GREEN);
    g2d.fillRoundRect(s.getx() - 5, s.gety() + 10, 5, 20, 10, 10);
    g2d.fillRoundRect(s.getx() + 10, s.gety() + 10, 5, 20, 10, 10);
    g2d.dispose();

    g.drawImage(bi, 0, 0, this);

}

现在,因为可以很安全地假设小程序的大小不会发生太大变化,所以您可以创建 BufferedImage 的类实例并重用它,例如...

Now, because it's pretty safe to assume the size of the applet won't change a lot, you could create a class instance of the BufferedImage and reuse it, for example...

private BufferedImage backingBuffer;

@Override
public void invalidate() {
    backingBuffer = null;
    super.invalidate();
}

@Override
public void paint(Graphics g) {
    if (backingBuffer == null) {
        backingBuffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
    }
    Graphics2D g2d = backingBuffer.createGraphics();

    super.paint(g2d);

    g2d.setColor(Color.LIGHT_GRAY);
    g2d.fillRoundRect(s.getx(), s.gety(), 10, 30, 10, 10);
    g2d.setColor(Color.GREEN);
    g2d.fillRoundRect(s.getx() - 5, s.gety() + 10, 5, 20, 10, 10);
    g2d.fillRoundRect(s.getx() + 10, s.gety() + 10, 5, 20, 10, 10);
    g2d.dispose();

    g.drawImage(backingBuffer, 0, 0, this);

}

我也会质疑从 Applet 扩展的需要/使用.如果要使用 JApplet,则可以使用 JPanel 作为基础画布,覆盖它的 paintComponent 方法并通过 Swing 获得自动双缓冲API...

I would also question the need/use of extending from an Applet. If you were to use JApplet, you could use a JPanel as you base canvas, override it's paintComponent method and gain automatic double buffering via the Swing API...

这篇关于Java Applet 运行时闪烁?(不是每个人都看到闪烁)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆