Как сделать задержку в графическом интерфейсе, который работает отдельно от другой задержки Java - PullRequest
0 голосов
/ 08 января 2019
package Login;
import java.awt.BorderLayout;    
import java.awt.event.ActionEvent;    
import java.awt.event.ActionListener;        
import java.io.IOException;    
import javax.swing.JButton;       
import javax.swing.JFrame;    
import javax.swing.JLabel;    
import javax.swing.JTextArea;  

public class GUI {

    public static void main(String[] args) {
        JLabel label = new JLabel("Delay");
        JFrame jarvis = new JFrame("JARVIS");
        jarvis.setSize(400, 400);
        jarvis.setLocation(500,250);
        label.setBounds(50,50,200,40);
        final JTextArea textArea = new JTextArea(10, 40);
        jarvis.getContentPane().add(BorderLayout.CENTER, textArea);
        final JButton button = new JButton("Activate Jarvis");
        jarvis.getContentPane().add(BorderLayout.NORTH, button);
        button.addActionListener(new ActionListener() {



            @Override
            public void actionPerformed(ActionEvent e) {

                try {
                    Login.jSpeech("/Users/C21/Desktop/JARVISSpeech/Ready.wav");
                } catch (IOException e1) {
                    e1.printStackTrace();
                }

                long now = System.currentTimeMillis();
                long later = now + 1000;
                while (System.currentTimeMillis() < later) {
                    int i = 0;
                    i++;
                }

                textArea.append("Uploading JARVIS...\n");

                 now = System.currentTimeMillis();
                 later = now + 1000;
                while (System.currentTimeMillis() < later) {
                    int i = 0;
                    i++;
                }

                textArea.append("Logged In...\n");


        }
    });


    jarvis.setVisible(true);



    }

}

Вместо того, чтобы ждать 1000 мс и говорить «Загрузка Jarvis», он ждет 2000 мс, а затем одновременно говорит «Загрузка Jarvis» и «Вход в систему». Мне нужны таймеры для работы отдельно. Другие типы, которые я пробовал, также заканчивались таким же провалом. Другие, которые я пробовал, работали, если их не было в графическом интерфейсе. Эта вещь говорит, добавьте больше деталей, так что здесь я говорю случайные вещи.

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Выполнение асинхронного кода в пользовательском интерфейсе Swing требует его выполнения в отдельном Thread. Это можно сделать, создав новый поток или используя существующий ExecutorService.

Обратите внимание, что обновления пользовательского интерфейса должны запускаться в потоке Event Dispatch - это можно сделать с помощью SwingUtilities.invokeLater(..) или SwingUtilities.invokeAndWait(..)

Пример кода:

Runnable runnable = () -> {

    // execute asynchronous code
    try {
        // wait for 1000ms = 1sec
        Thread.sleep(1000);
    } catch (InterruptedException ex) {
        ex.printStackTrace();
    }

    SwingUtilities.invokeLater(() -> {
        // update UI
    });
};

Thread thread = new Thread(runnable);
thread.setDaemon(true);
thread.start();

В качестве альтернативы вы можете использовать ScheduledExecutorService с фиксированным пулом потоков (который вы можете создать один раз для своего приложения и затем использовать повторно). ScheduledExecutorService позволяет планировать код, который должен выполняться после заданной задержки :

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);

Runnable runnable = () -> {
    // execute asynchronous code
    SwingUtilities.invokeLater(() -> {
        // update UI

    });
};

scheduledExecutorService.schedule(runnable, 1, TimeUnit.SECONDS);
0 голосов
/ 08 января 2019

Сначала вместо этого:

        long later = now + 1000;
        while (System.currentTimeMillis() < later) {
            int i = 0;
            i++;
        }

Вы должны использовать Thread.sleep(1000)

Второй выпуск:

Когда вызывается ActionListener public void actionPerformed(ActionEvent e) {, выполняется все тело. Так как у вас есть 2 цикла ожидания, каждый по 1000 с, вы будете ждать 2 секунды. Измени это.

Третий, последний и самый важный: Никогда не спите, не ждите и не делайте тяжелые вещи в потоке рассылки событий - EDT (actionPerformed выполняется EDT). Тем самым вы заставите приложение зависать во время этой операции / ожидания / сна. Если вам нужно что-то сделать в фоновом режиме, для этого есть специальное решение: SwingWorker. Если вы хотите подождать и выполнить некоторые действия после этого, в Swing вы можете использовать Timer

...