Java Applet flickering when running? (not everybody sees flickering)

余生颓废 提交于 2019-12-11 19:33:34

问题


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.

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);
}

}

回答1:


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

You should employ some kind of double buffering...

For example...

@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);

}

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);

}

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...



来源:https://stackoverflow.com/questions/18584009/java-applet-flickering-when-running-not-everybody-sees-flickering

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!