我理解其背后的逻辑,但不知道如何将其转换为代码。有人可以告诉我我写的这个例子吗?
小程序所做的只是中心矩形自行向上、向下、向右和向左移动。我想用双缓冲区消除恼人的闪烁,但我不知道要进行哪些更改/添加才能实现这一点。
import java.applet.*;
import java.awt.*;
public class Broadway extends Applet implements Runnable {
Thread animation;
int locx,locy; // location of rectangle
int width, height; // dimensions of rectangle
// direction of motion
static final byte UP = 0;
static final byte DOWN = 1;
static final byte LEFT = 2;
static final byte RIGHT = 3;
byte state; // state the rect is in
// length of pausing interval in ms
static final int REFRESH_RATE = 100;
public void init() {
setBackground(Color.black);
locx = 80; // parameters of center rect
locy = 100;
width = 110;
height = 90;
state = UP;
}
public void start() {
animation = new Thread(this);
if (animation != null) {
animation.start();
}
}
public void paint(Graphics g) {
g.setColor(Color.yellow);
g.fillRect(0,0,90,90);
g.fillRect(250,0,40,190);
g.fillRect(80,110,100,20);
g.setColor(Color.blue);
g.fillRect(80,200,220,90);
g.fillRect(100,10,90,80);
g.setColor(Color.lightGray);
g.fillRect(locx,locy,width,height);
g.setColor(Color.red);
g.fillRect(200,0,45,45);
g.fillRect(0,100,70,200);
g.setColor(Color.magenta);
g.fillRect(200,55,60,135);
}
//update the center rectangle
void updateRectangle() {
switch (state) {
case DOWN:
locy += 2;
if (locy >= 110) {
state = UP;
}
break;
case UP:
locy -= 2;
if (locy <= 90) {
state = RIGHT;
}
break;
case RIGHT:
locx += 2;
if (locx >= 90) {
state = LEFT;
}
break;
case LEFT:
locx -= 2;
if (locx <= 70) {
state = DOWN;
}
break;
}
}
public void run() {
while (true) {
repaint();
updateRectangle();
try {
Thread.sleep (REFRESH_RATE);
} catch (Exception exc) { };
}
}
public void stop() {
if (animation != null) {
animation.stop();
animation = null;
}
}
}
最佳答案
导入java.awt.*;
将其更改为
导入javax.swing.*;
public class Broadway 扩展 Applet ..
将其更改为
public class Broadway 扩展 JApplet ..
- 将所有自定义绘画移至
JPanel
中。覆盖paintComponent(Graphics)
而不是paint(Graphics)
。JPanel
默认情况下是双缓冲的。 - 使用 Swing
Timer
制作动画。
作为一般提示
编写一个框架并使用 Java Web Start 从链接启动它在考虑使用小程序之前。
更新
此代码实现了上面的大部分建议,并在选项 Pane 中显示生成的平滑缓冲动画。它可以显示在 JFrame
或 JApplet
中。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Broadway extends JPanel {
int locx, locy; // location of rectangle
int width, height; // dimensions of rectangle
Timer timer;
// direction of motion
static final byte UP = 0;
static final byte DOWN = 1;
static final byte LEFT = 2;
static final byte RIGHT = 3;
byte state; // state the rect is in
// length of pausing interval in ms
static final int REFRESH_RATE = 100;
public Broadway() {
setBackground(Color.black);
locx = 80; // parameters of center rect
locy = 100;
width = 110;
height = 90;
state = UP;
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
repaint();
updateRectangle();
}
};
timer = new Timer(this.REFRESH_RATE, listener);
}
public void start() {
timer.start();
}
public void stop() {
timer.stop();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.yellow);
g.fillRect(0, 0, 90, 90);
g.fillRect(250, 0, 40, 190);
g.fillRect(80, 110, 100, 20);
g.setColor(Color.blue);
g.fillRect(80, 200, 220, 90);
g.fillRect(100, 10, 90, 80);
g.setColor(Color.lightGray);
g.fillRect(locx, locy, width, height);
g.setColor(Color.red);
g.fillRect(200, 0, 45, 45);
g.fillRect(0, 100, 70, 200);
g.setColor(Color.magenta);
g.fillRect(200, 55, 60, 135);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
//update the center rectangle
void updateRectangle() {
switch (state) {
case DOWN:
locy += 2;
if (locy >= 110) {
state = UP;
}
break;
case UP:
locy -= 2;
if (locy <= 90) {
state = RIGHT;
}
break;
case RIGHT:
locx += 2;
if (locx >= 90) {
state = LEFT;
}
break;
case LEFT:
locx -= 2;
if (locx <= 70) {
state = DOWN;
}
break;
}
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
Broadway bw = new Broadway();
bw.start();
JOptionPane.showMessageDialog(null, bw);
bw.stop();
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
SwingUtilities.invokeLater(r);
}
}
关于java - 我需要帮助了解如何在 Java 小程序中编写双缓冲代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14167412/