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中,我尝试过的其他工具也很有效。东西说要添加更多细节,所以在这里我说的是随机的东西。
答案 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);