如何通过setText方法设置计时器?

时间:2019-04-29 09:02:46

标签: java swing awt

我使用setText方法进行更改,但是它不起作用。当我调试程序时,我注意到setText()不能很好地工作,因为它仅显示循环60秒的最后一件事。

例如,我想查看1到60之间的所有数字,但它只显示59。

从我看到的单击JButton的结果来看,我认为Actionlistener似乎没有问题。这就是为什么我多次更改逻辑但总是碰巧相同的原因。

public class Game extends JFrame implements ActionListener {

    JLabel jTimer = new JLabel();//Showing time
    JLabel jScore = new JLabel("");//Showing  score

    Game() {
        JFrame Gframe = new JFrame("Game play");
        Gframe.setBounds(400, 400, 800, 800);
        Gframe.setLayout(null);
        JPanel pScore = new JPanel();

        EtchedBorder border = new EtchedBorder();
        JLabel score = new JLabel(" Score ");
        Font font1 = new Font("굴림", Font.PLAIN, 20);


        jScore.setPreferredSize(new Dimension(5, 5));
        score.setFont(font1);
        score.setBounds(330, 30, 100, 100);
        score.setBorder(border);


        Font font2 = new Font("고딕체", Font.PLAIN, 20);
        JLabel ttime = new JLabel(" Time ");

        JButton start = new JButton("START");
        start.setFont(font2);
        start.setBounds(150, 40, 100, 100);
        start.setBorder(border);
        start.addActionListener(this);

        jTimer.setLayout(null);
        jTimer.setBounds(330, 30, 300, 300);


        ttime.setFont(font2);
        ttime.setBounds(200, 15, 100, 100);
        ttime.setBorder(border);


        pScore.setLayout(new GridLayout(2, 2));
        pScore.setBounds(330, 30, 200, 100);
        pScore.add(score);
        pScore.add(ttime);
        pScore.add(jScore);
        pScore.add(jTimer);
        add(start);
        Gframe.add(pScore);//Including Score&Time
        Gframe.add(start);//Adding Start Butto

        Gframe.setVisible(true);
    }


    public void setTimer() {
        int i = 0;
        while (true) {
            try {
                System.out.println(i);
                jTimer.setText(i + "Sec");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            i++;
            if (i == 60) {
                break;
            }
        }
    }

    // When this method is performed,
    // The result indicates that The println(i) shows correctly as a timer 
    // but jTimer.setText() don't show at all.
    // What's more During the playing time, Jbutton(Start) is clicked until it's finished completely.
    public void actionPerformed(ActionEvent e) {
        String str = e.getActionCommand();
        if (str.equals("START")) {
            System.out.println("Counting");
            setTimer();
        }
    }
}

我希望JLabel(jTimer)显示所有数字,但实际输出只是先前的数字。

2 个答案:

答案 0 :(得分:1)

由于Swing具有单线程特性,因此不能使用循环或Thread.sleep方法。

因此,UI被阻止,并且直到循环完成才更新。由于这些更新是在EDT(事件调度线程)的上下文中执行的,因此在更新UI组件时可以安全地使用它。

public class Game extends JFrame implements ActionListener {
    private int count = 0; 
    // ...

    public void setTimer() {
        count = 0; // initialize variable for timer.
        Timer timer = new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                jTimer.setText(count + " Sec");
                count++;
                if(count == 60) {
                    ((Timer)e.getSource()).stop();
                }
            }
        });
        timer.setInitialDelay(0);
        timer.start();

        // When the timer is over
        System.out.println("done!");
    }
}

答案 1 :(得分:0)

问题出在您的setTimer-Method中。您在将时间写入标签之前会跳出循环。我对您的方法的建议:

public void setTimer()
{
    int i=0;
    while(i <= 60)
    {              
        try {
            System.out.println(i);       
            jTimer.setText(i+"Sec");
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        i++;     
    }
}    

我替换了循环条件,因此在更新时间后循环中断。