Swing Timer FastForward按钮

时间:2013-05-31 18:28:58

标签: java swing timer

我想尝试一个简单的快进按钮。我的理解是初始化一个计时器

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 
    }
按下每个按钮,应该将速度降低一半,三分之一,四分之一等。问题是我的模拟完全没有做到这一点。这里有什么我想念的吗?

1 个答案:

答案 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已经过去时执行您的逻辑(依此类推)。