Графический интерфейс Java заморожен, но программа все еще работает в терминале

#java #swing #user-interface

Вопрос:

Я пытаюсь создать простой хронометр с графическим интерфейсом Java, но всякий раз, когда я нажимаю кнопку «Пуск», графический интерфейс зависает и не позволяет мне нажать кнопку «Стоп», но программа продолжает отлично работать на терминале.

Вот код моей кнопки «Пуск»:

 startButton = new JButton();
startButton.setText("START");
startButton.setFont(new Font("RuneScape UF", Font.PLAIN, 16));
startButton.setFocusable(false);
startButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == startButton) {
            System.out.println("Start button pressed!");
            isRunning = true;
            System.out.println(isRunning);

            long startTime = System.currentTimeMillis();
            while (isRunning) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException interruptedException) {
                    interruptedException.printStackTrace();
                }

                long elapsedTime = System.currentTimeMillis() - startTime;
                long elapsedSeconds = elapsedTime / 1000;
                if (elapsedSeconds == 60) {
                    elapsedSeconds = 0;
                    startTime = System.currentTimeMillis();
                }
                if ((elapsedSeconds % 60) == 0) {
                    minutesDisplay  ;
                }
                if ((minutesDisplay % 60) == 0 amp;amp; stupidFix > 0) {
                    stupidFix  ;
                    hoursDisplay  ;
                }
                //System.out.println(elapsedSeconds);
                String h = String.format("d", hoursDisplay);
                String m = String.format("d", minutesDisplay);
                String s = String.format("d", elapsedSeconds);

                timePassed.setText(h   ":"   m   ":"   s);
                System.out.println(h   ":"   m   ":"   s);
            }
        }
    }
});
 

Комментарии:

1. Это связано с тем, что поток пользовательского интерфейса застрял в вашем while (isRunning) цикле, вам придется выполнить этот код в отдельном потоке

2. Может быть, это будет полезно: docs.oracle.com/javase/tutorial/uiswing/concurrency/…

Ответ №1:

Вы используете прослушиватель while loop действий внутри кнопки. Использование цикла while внутри прослушивателя действий кнопки считается тяжелой задачей.Вы должны использовать SwingWorker для этого.

Вы можете посмотреть учебник по этому вопросу здесь:

https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html

Комментарии:

1. » Использование цикла while внутри прослушивателя действий кнопки считается тяжелой задачей.» Это только Thread.sleep(..) то, что будет блокировать EDT, поэтому не обязательно является «тяжелой» задачей. На самом деле, это лучше сделать, установив качели Timer для обновления времени. Обе ситуации описаны в ссылке, предоставленной Анастасией.