【问题标题】:Timer start/stop parameters定时器启动/停止参数
【发布时间】:2011-11-28 17:42:53
【问题描述】:

自从加入这个社区以来,我的技能和进步都取得了长足的进步。你们都是很大的帮助。我无法提供一个计时器,我已经为它的启动和停止实现了某些参数。

我要么收到错误提示“局部变量计时器可能尚未初始化”,要么我没有收到任何错误,但没有任何反应。也许我把计时器放错地方了?

如果我将timer.start(); 也放入构造函数中,一切正常,但是在程序初始化时必须启动计时器。我真的很想让计时器在满足某个参数之前不启动。比如说,直到int p1Laps=1;,但如果我将timer.start(); 放入构造函数中的if 语句中(即if(p1Laps>=1) { timer.start(); },则计时器永远不会启动。

我尝试将timer.start(); 放在不同的地方,但要么没有得到响应,要么生成了一个关于缺少局部变量timer 的错误。

我遇到的第二个有点相关的问题是,如果没有出现上述“局部变量计时器可能尚未初始化”错误,就无法将任何参数放在适当的位置以调用 timer.stop();。我已将 timer.stop(); 留在了我认为它需要在代码中的位置,但它收到了该错误。

简而言之,我希望能够告诉计时器在满足某个参数时启动,即当玩家完成一圈时。而且我希望能够告诉计时器在达到某个值时停止。

在此先感谢您提供的非常棒的建议,我相信我会收到的。注意:这不是全部代码,只是相关信息。

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;

public class RacerDoom extends JFrame {
    int counter = 0;
    int p1Laps = 0;
public RacerDoom() {
        //create JFrame
        super("Racer Doom Squared");
        setSize(WIDTH,HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        //set up Timer
        final Timer timer=new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(counter>=10) {
                    timer.stop(); //error here reads "local variable timer may
                                    //not have been initialized"
                }
                else{
                   counter++;
                   }
                System.out.println(counter);
            }
        });
        //inner class threads
        Move1 m1 = new Move1();
        m1.start();
        //start timer
        if(p1Laps>=1) {
            timer.start(); //error here is that timer will not start when
                            //p1Laps>=1
        }
    }
    private class Move1 extends Thread implements KeyListener {
        public void run() {
            addKeyListener(this);
            while(true) {
                try {
                    repaint();
                    //collisions
                    if(p1.intersects(finishtop)&&p1Direction==UP&&p1cross!=true){
                        p1cross=true;
                        p1Laps++;
                        p1Boost++;
                        counter=0;
                        System.out.println(p1Laps);
                    }
                    if(p1.intersects(finishtop)==false) {
                        p1cross=false;
                    }
    public static void main (String [] args) {

        new RacerDoom();
    }
}

【问题讨论】:

    标签: java timer if-statement conditional


    【解决方案1】:

    快速修复:

    而不是

    timer.stop();
    

    ((Timer)e.getSource()).stop();
    

    ActionEvent 的 getSource 方法将返回对调用 actioPerformed 方法(Timer)的对象的引用,所以这应该可以工作。

    您的代码可能存在其他问题,包括没有 Thread.sleep(...) 的后台线程、使用 KeyListeners 而不是 Key Binding、在后台线程中添加 KeyListener...

    【讨论】:

    • 对不起,我的后台线程确实有一个Thread.sleep(...);,我只是忘了包含它。
    【解决方案2】:

    当您想在代码中的不同位置启动和停止计时器时,您应该将其设为成员变量。这将解决您尝试在动作侦听器中停止计时器的问题。

    变量 p1Laps 在构造函数中不会改变(在你将它初始化为 0 之后),所以你需要在你改变 plLaps 值的地方启动计时器。我不确定从另一个线程(Move1)调用 timer.start() 是否安全。因此使用 SwingUtilities.invokeLater() 启动计时器可能更安全。

    【讨论】:

    • 我需要查看SwingUtilities.invokeLater(),因为我在这个网站上多次提到过它,但我完全不熟悉它。
    • 嗨,我可以问一些问题吗?在java中,如果我们将一个定时器对象赋值为空值(timer = null;)而不调用timer.stop(),定时器会停止向监听器触发吗?
    • 不,它不会停止计时器,因为计时器引用仍将存在于内部队列或要触发的计时器中(由内部线程维护)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-31
    • 2013-06-12
    相关资源
    最近更新 更多