gpt4 book ai didi

Java Swing Action 卡顿

转载 作者:行者123 更新时间:2023-12-01 11:38:56 29 4
gpt4 key购买 nike

我在 Java Swing 中移动 block 时遇到卡顿问题。

下面的代码将显示该问题。运行时,我希望盒子移动平稳,没有任何卡顿。 Swing中有没有办法实现这一点?或者我应该继续使用 JavaFX?

MovementStutter.java

package movementstutter;

import javax.swing.JFrame;

public class MovementStutter {

public static void main(String[] args) {
JFrame win = new JFrame("Stutter Demo");
win.getContentPane().add(new GamePanel());
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setResizable(false);
win.pack();
win.setVisible(true);
}

}

GamePanel.java

package movementstutter;

import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;

public class GamePanel extends JPanel implements Runnable {

private boolean running;
private Thread thread;
private double x;
private double y;
private double movementFactor;

public GamePanel() {
setPreferredSize(new Dimension(640, 480));
setFocusable(true);
grabFocus();
movementFactor = 1;
running = true;
}

@Override
public void addNotify() {
super.addNotify();
if (thread == null) {
thread = new Thread(this);
thread.start();
}
}

@Override
public void run() {
long time = System.currentTimeMillis();
while (running) {
update();
repaint();
long sleep = 16 - (System.currentTimeMillis() - time);
time += 16;
if (sleep < 0) {
sleep = 16;
}
try {
Thread.sleep(sleep);
} catch (Exception e) {
e.printStackTrace();
}
}
}

private void update() {
if (x < 0) {
movementFactor = 1;
} else if (x > 608) {
movementFactor = -1;
}
x += movementFactor * 200 * 0.016;
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillRect((int) x, (int) y, 32, 32);
}

}

最佳答案

您正在一个不是事件分派(dispatch)线程的线程中更新 swing 组件。你不应该这样做。要执行定时操作,您可以使用 javax.swing.Timer .

例如,不要实现 Runnable,而是让面板实现 ActionListener,删除与线程相关的内容,并添加一个操作监听器:

public void actionPerformed(ActionEvent e) {
update();
repaint();
}

然后,在面板的构造函数中,您可以创建一个计时器javax.swing.Timer 确保操作在事件分派(dispatch)循环中执行。它还简化了时序管理:

public GamePanel() {
setPreferredSize(new Dimension(640, 480));
setFocusable(true);
grabFocus();
movementFactor = 1;
running = true;
new Timer(16,this).start();
}

如果您需要在任何时候停止计时器,那么您应该将其分配给一个字段,例如

Timer blockTimer = new Timer(16,this);

然后你就这么做了

blockTimer.start();

在你的构造函数中,你可以有一个按钮,其操作包括

blockTimer.stop();

关于Java Swing Action 卡顿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29715049/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com