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);
}
}
Instead of waiting 1000ms and saying "Uploading Jarvis", it waits 2000ms then says "Uploading Jarvis" & "Logging In" simultaneously. I need the timers to work separately. The other types I tried also ended up failing like this. The other ones I tried worked if it wasn't in the GUI thingy. The thing says add more details so here I am saying random stuff.
First, instead of that:
long later = now + 1000;
while (System.currentTimeMillis() < later) {
int i = 0;
i++;
}
You should rather use Thread.sleep(1000)
Second issue:
When ActionListener's public void actionPerformed(ActionEvent e) {
is called, whole body is executed. Since you have 2 waiting loops, 1000s each inside, you will wait 2 seconds. Change that.
Third and last and most important: Never ever sleep or wait or do heavy stuff in Event Dispatch Thread - EDT ( actionPerformed
is executed by EDT). By doing so, you will make your appication freeze during that operation/wait/sleep. If you need to do something in background, there is dedicated solution for that: SwingWorker
. If you want to wait and do some action after that, in Swing you can use Timer
Executing asynchronous code in a Swing UI requires it to be executed in a separate Thread
. This can be done be either creating a new Thread or using an existing ExecutorService
.
Note that updates to the UI must be run in the Event Dispatch Thread - this can be acomplished by using either SwingUtilities.invokeLater(..)
or SwingUtilities.invokeAndWait(..)
Example code:
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();
Alternatively you can use a ScheduledExecutorService
with a fixed thread pool (that you can create once for your application and then reuse). The ScheduledExecutorService
allows to schedule code that is to be run after a given delay :
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
Runnable runnable = () -> {
// execute asynchronous code
SwingUtilities.invokeLater(() -> {
// update UI
});
};
scheduledExecutorService.schedule(runnable, 1, TimeUnit.SECONDS);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.