timer.setDelay()
为我工作。这是一个在屏幕上移动红色方块的快速示例。按下快进按钮可以通过调用计时器使其移动得更快setDelay
(您会注意到我的逻辑ActionListener
与您的逻辑相同,尽管变量名称不同):
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TimerTest extends JFrame {
public static void main(String[] args) { new TimerTest().setVisible(true); }
private static final int DEFAULT_SPEED = 500;
private int speedCounter = 1;
private int currentSpeed = DEFAULT_SPEED / speedCounter;
private int squareX = 150;
public TimerTest() {
super("Test");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setMinimumSize(new Dimension(300, 200));
setLayout(new BorderLayout());
setLocationRelativeTo(null);
JPanel displayPanel = new JPanel(null) {
@Override
public void paintComponent(Graphics g) {
g.setColor(Color.RED);
g.fillRect(squareX, getHeight() / 2, 25, 25);
}
};
final Timer timer = new Timer(currentSpeed, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
squareX = (squareX + 15) % getWidth();
repaint();
}
});
timer.setRepeats(true);
JButton fastForwardButton = new JButton(new AbstractAction(">>") {
@Override
public void actionPerformed(ActionEvent e) {
speedCounter++;
currentSpeed = DEFAULT_SPEED / speedCounter;
timer.stop();
timer.setDelay(currentSpeed);
timer.start();
}
});
add(displayPanel, BorderLayout.CENTER);
add(fastForwardButton, BorderLayout.SOUTH);
timer.start();
}
}
这种方法的一个明显缺陷是启动/停止计时器会导致额外的延迟。例如,假设计时器设置为每秒钟触发一次,并且自上一帧以来2
已经过了几秒钟。1.5
如果您将延迟设置为1
秒并重新启动计时器,2.5
则会在下一帧触发之前经过几秒。这可以解释为什么对您“它不起作用”。
为避免此问题,您可以创建一个以某个固定速率触发的计时器,但仅在经过足够的时间后才执行您的逻辑。然后更改用户快进时的“足够时间”。例如,计时器可以触发 every ,但您仅在自上次执行以来已过去50ms
时才执行您的逻辑。500ms
当用户快进时,如果250ms
已经通过(等等),您可以然后执行您的逻辑。