0

我试图让一个简单的快进按钮工作。我的理解是这样初始化一个计时器

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 
    }

每按一次按钮,就应该将速度减半,第三,第四等。问题是我的模拟完全没有这样做。我在这里缺少什么吗?

4

1 回答 1

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则会在下一帧触发之前经过几秒。这可以解释为什么对您“它不起作用”。

为避免此问题,您可以创建一个以某个固定速率触发的计时器,但仅在经过足够的时间后才执行您的逻辑。然后更改用户快进时的“足够时间”。例如,计时器可以触发 every ,但您仅在自上次执行以来已过去50ms时才执行您的逻辑。500ms当用户快进时,如果250ms已经通过(等等),您可以然后执行您的逻辑。

于 2013-05-31T20:58:39.873 回答