【发布时间】:2023-04-10 04:22:02
【问题描述】:
我目前正在学习 NetBeans 中的 Java 动画和图形。
我决定从 JPanel 中的一个简单的球运动开始。
我在解决闪烁问题时遇到了一些问题。我看过很多论坛,但大多数都是针对使用双缓冲的 AWT,但我知道 SWING 组件不需要双缓冲。我试过 - 使用 repaint() 和 .clearRect()。
在这 2 个中,我发现使用 .clearRect() 给了我更好的结果,但不是一直无缝的无闪烁动画。所以我想知道是否有更好的方法来消除闪烁。
这是我的代码:
public class NewJFrame extends javax.swing.JFrame {
int x;
int y;
int xspeed = 1;
int yspeed = 1;
int width;
int height;
Graphics g;
/**
* Creates new form NewJFrame
*/
public NewJFrame() {
initComponents();
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
g = jp.getGraphics();
width = jp.getWidth();
height = jp.getHeight();
final Timer timerCHK = new Timer();
timerCHK.schedule(new TimerTask() {
public void run() {
move();
time();
}
}, 1000, 10);
}
void time() {
final Graphics g = jp.getGraphics();
final Timer timerCHK = new Timer();
timerCHK.schedule(new TimerTask() {
public void run() {
g.clearRect(0, 0, jp.getWidth() - 3, jp.getHeight() - 3);
}
}, 1000, 12);
}
void move() {
x = x + xspeed;
y = y + yspeed;
Graphics mk = jp.getGraphics();
if (x < 0) {
x = 0;
xspeed = -xspeed;
} else if (x > width - 20) {
x = width - 20;
xspeed = -xspeed;
}
if (y < 0) {
y = 0;
yspeed = -yspeed;
} else if (y == height - 20) {
y = height - 20;
yspeed = -yspeed;
}
mk.drawOval(x, y, 20, 20);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}
}
【问题讨论】:
-
1)
Thread.sleep(5);不要阻塞 EDT(事件调度线程)——当这种情况发生时,GUI 会“冻结”。而不是调用Thread.sleep(n)实现一个SwingTimer用于重复任务或SwingWorker用于长时间运行的任务。有关详细信息,请参阅Concurrency in Swing。 2) 为了尽快获得更好的帮助,请发布SSCCE。 3)g来自哪里?它有一种“不好的代码气味”。当我看到 SSCCE 时会知道更多。 4)jp.setDoubleBuffered(true);-JComponent对象默认是双缓冲的。 -
@AndrewThompson 感谢您的回复。我已将我的代码编辑得简短而简单,但我仍然不确定如何将其设为“SSCCE”代码。“g”是图形变量(我现在已将其添加到代码中)。我尝试给出另一个方法 timer() 在 move() 之后 timer() 由我在主代码中使用的相同计时器组成。我仍然在动画中闪烁。
-
“我仍然不确定如何将其设为“SSCCE”代码。”您在理解 S-SC-C-E 的哪个部分有困难?
-
SO上有很多动画例子,你可以试试this example
-
还有this一个
标签: java swing animation graphics ide