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

问题描述 投票:2回答:2

我使用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)显示所有数字,但实际输出只是前一个数字。

java swing awt
2个回答
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!");
    }
}

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++;     
    }
}    

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

© www.soinside.com 2019 - 2024. All rights reserved.