我想尝试一个简单的快进按钮。我的理解是初始化一个计时器
timer = new Timer(setspeed, listener);
将计时器事件之间的延迟设置为int setspeed(以毫秒为单位)。
我有一个快进按钮,其代码如下:
public void doFastForward()
{
speedcounter++;
setspeed = speed / speedcounter;
System.out.print(speedcounter + " " + setspeed + ". "); //checker
timer.stop();
timer.setDelay((setspeed));
timer.start();
System.out.print(timer.getDelay() + ".. "); //checker
}
按下每个按钮,应该将速度降低一半,三分之一,四分之一等。问题是我的模拟完全没有做到这一点。这里有什么我想念的吗?
答案 0 :(得分:0)
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
秒。这可以解释为什么“它不起作用”。
要避免此问题,您可以创建以某些固定费率触发的计时器,但只有在足够的时间过去后才执行您的逻辑。然后改变用户快进的“足够时间”。例如,计时器可以触发每个50ms
,但是如果自上次执行以来已经过500ms
,则只执行逻辑。当用户快进时,您可以在250ms
已经过去时执行您的逻辑(依此类推)。