【问题标题】:Timer cannot stop (maybe the GUI error)计时器无法停止(可能是 GUI 错误)
【发布时间】:2012-08-30 16:04:38
【问题描述】:

我正在尝试为使用计时器的交通灯模拟创建动画。有一个停止模拟的按钮,但是点击它似乎不影响动画。我确实检查了动画,但动画看起来像是不同的地方。请帮忙。

在主类中:

DataModels dm = new DataModels();
Simulation sm = new Simulation(dm);
sm.go();

这是模拟类:

public class Simulation extends JPanel implements ActionListener {
    DataModels dm;
    Timer tm = new Timer(20, this);
    private boolean ss = false;

    public Simulation(DataModels dm) {
        this.dm = dm;
        // redLightTime= dm.getRedLight()*1000;
    }

    public void go() {
        sm = new Simulation(dm);
        simulation = new JFrame();
        simulation.setTitle("Traffic light and Car park Siumulation");
        simulation.setSize(800, 700);
        simulation.setResizable(false);
        simulation.setVisible(true);
        simulation.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        simulation.add(sm, BorderLayout.CENTER);

        // Command button panel
        JPanel command = new JPanel();
        command.setPreferredSize(new Dimension(800, 100));
        // Pause or play button
        JButton pauseplayB = new JButton("Pause");
        pauseplayB.setSize(new Dimension(50, 50));
        pauseplayB.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                // Execute when button is pressed
                ss = true;
                System.out.println("You clicked the button");
            }
        });
        command.add(pauseplayB);
        JButton stopB = new JButton("Stop");
        JButton saveB = new JButton("Save");

        command.setLayout(new GridLayout(1, 1));
        command.add(stopB);
        command.add(saveB);
        simulation.add(command, BorderLayout.SOUTH);
    }

现在paintComponent 将根据定时器的变化而变化。以下代码也在Simulation 类中。

public void paintComponent(Graphics g) {
    // Many other actions
    // ....
    startAnimation();
}

public void startAnimation() {
    if ( !false) {
        tm.start();
    } else {
        tm.stop();
    }
    // Checking button click
    System.out.println(ss);
}

根据控制台输出,ss 值永远不会改变。

【问题讨论】:

  • 点击按钮后是否正在绘制JPanel?为什么不尝试在单击按钮时强制 JPanel 重新绘制或使其自身无效? 虽然,单击按钮会使 JPanel 无效
  • 另外,考虑将您的 if 声明更改为更多内容,现代: if (!ss) { ... }
  • 画了??在控制台行中:得到检查:您单击了按钮,但值 ss 没有改变
  • System.out.println("You clicked the button"); 是否被打印? (它在你的动作监听器中。)
  • 强调@JTMon 的回答:never-ever 在其paintComponent 中更改组件的状态。另外,我建议更改 startAnimation 的名称,因此很明显它负责启动和停止。顺便说一句:从你的 sn-p 来看,预计 ss 总是相同的,你永远不会改变它 - 可能是它在其他地方改变了 - 更有理由显示 SSCCE 而不是 sn-ps :-) 不相关:a)永远不要调用 setXXSize(而是使用适合您需要的 LayoutManager),b)删除 pausePlayB.setSize,无论如何它都没有效果

标签: java swing timer


【解决方案1】:

按钮的动作监听器应该调用函数以某种方式停止计时器,而不是依赖于绘制事件来完成。

编辑:这是一些代码:)

public void actionPerformed(ActionEvent e) {
    // Execute when button is pressed
    ss = true;
    System.out.println("You clicked the button");
    startAnimation();
}

并且 startAnimation 方法应该有 if(!ss) 而不是 if(!false)

【讨论】:

  • 一个例子可以帮助你完成帖子;)+1 仍然
  • @MadProgrammer 你绝对是对的,但我发帖时已经是晚上 10 点了 :)
  • Tks,请帮助我在这里卡了 2 天!!
  • 因为 startAnimation 实际上是指 toggleAnimation(或 updateAnimationTimer),所以该操作可能应该切换标志 ss = !ss(并且暂停按钮的文本已适当更新)
【解决方案2】:

除了 JTMon 的建议,你的 startAnimation 方法还包含一个逻辑炸弹

public void startAnimation() {
    if ( !false) { //<-- this will ALWAYS be true
        tm.start();
    } else {
        tm.stop();
    }
    // Checking button click
    System.out.println(ss);
}

控制计时器的 if 语句将始终尝试启动计时器

【讨论】:

  • 这一定是对@RedAnwhite 的评论的一个错字,因为原始帖子有 if(ss==false) :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-30
  • 2023-04-11
  • 1970-01-01
相关资源
最近更新 更多