Как установить таймер методом setText? - PullRequest
2 голосов
/ 29 апреля 2019

Я использовал метод 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 ]

1 голос
/ 30 апреля 2019

Из-за однопоточной природы Swing, вы не можете использовать цикл или Thread.sleep методы.

Следовательно, пользовательский интерфейс заблокирован и не обновляется до завершения цикла. Поскольку эти обновления выполняются в контексте EDT (потока диспетчеризации событий), его можно безопасно использовать при обновлении компонентов пользовательского интерфейса.

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 голосов
/ 29 апреля 2019

Проблема в вашем setTimer-методе.Вы выпрыгиваете из цикла, прежде чем записать время на этикетку.Мое предложение для вашего метода:

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

Я заменил условие цикла, поэтому цикл прерывается по истечении времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...