【问题标题】:Swing Timer FastForward button摆动定时器快进按钮
【发布时间】:2013-05-27 15:32:33
【问题描述】:

我正在尝试使用一个简单的快进按钮。我的理解是这样初始化一个计时器

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 
    }

每按一次按钮,速度就会减半、第三、第四等。问题是我的模拟完全没有这样做。我这里有什么遗漏吗?

【问题讨论】:

  • 它在做什么呢?我们需要更多信息。你有System.out 声明:他们在打印什么?你是如何声明/初始化speedcounterspeed等的?
  • 那些系统输出只是为了检查速度计数器的值,它被打印为正确的值。 Speed 是在类中声明的静态 int,speed counter 是用于更改计时器的 ACTUAL 速度(这是 setspeed)的修饰符。关于计时器的一切都运行良好,但这个。我只是想改变事件触发的速度/速度,我读过的所有内容都说使用 timer.setDelay(DesiredTime);这样做,但显然我错过了一些东西。
  • 作为它正在做什么的评论,基本上没有。我已经为事件计时,无论是否点击“快进”按钮,它都需要很长时间

标签: java swing timer


【解决方案1】:

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 已通过(等等),您就可以执行您的逻辑。

【讨论】:

  • 无论出于什么原因,重新编写它类似于你的工作(即使我的大致相同XD)谢谢!
猜你喜欢
  • 2020-06-13
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多