每次重绘GUI时,我都会有一个不断闪烁的Java Applet。大多数人都看不到闪烁。其他人可以毫无问题地运行applet,但我不是。
我不确定这是否与我重绘UI的方式有关,或者这是我的JRE的问题还是什么问题。我已经厌倦了自己查找其他人的类似问题,但我还没有看到适用于此的答案。
我缩短了我正在运行的applet。这只是一个向右移动的火箭飞船,非常简单(对我来说)它不断闪烁。
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);
}
}
答案 0 :(得分:3)
这是Applet
未以任何方式开始缓冲的结果。
你应该采用某种双重缓冲......
例如......
@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);
}
现在,因为假设applet的大小不会发生很大变化是非常安全的,你可以创建一个BufferedImage
的类实例并重用它,例如......
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获得自动双缓冲...