如何在与其他延迟Java分开工作的GUI中产生延迟?

时间:2019-01-08 08:14:57

标签: java user-interface delay

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毫秒并说“ Uploading Jarvis”,而是等待2000毫秒,然后同时说“ Uploading Jarvis”和“ Login In”。我需要计时器单独工作。我尝试过的其他类型也最终失败了。如果不在GUI中,我尝试过的其他工具也很有效。东西说要添加更多细节,所以在这里我说的是随机的东西。

3 个答案:

答案 0 :(得分:0)

您可以检查repaint()方法的使用情况,并明确调用repaint()到您正在处理的内容窗格中。

以下是相关的documentation

答案 1 :(得分:0)

首先,而不是:

        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中睡觉,等待或做大量事情(EDT执行actionPerformed)。这样,您将在该操作/等待/睡眠期间冻结您的应用程序。如果您需要在后台执行某项操作,则可以使用专门的解决方案:SwingWorker。如果您想等待之后再执行一些操作,则可以在Swing中使用Timer

答案 2 :(得分:0)

在Swing UI中执行异步代码需要在单独的Thread中执行。可以通过创建新线程或使用现有的ExecutorService来完成。

请注意,必须在事件调度线程中运行UI的更新-可以通过使用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);