Reputation: 55
I'm still very new to the world of programming and have recently noticed, that whenever I tell the programm to idle for some seconds between the code, it instead sleeps at the start and then goes through the remaining code.
I've tried various ways like thread.sleep()
or Timers but I never get what I want.
Here is an example:
public void Console(){
Console.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Console.setSize(500, 500);
Console.setLocationRelativeTo(null);
Console.setResizable(false);
Console.setVisible(true);
Console.setTitle("Console");
JPanel contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
Console.setContentPane(contentPane);
contentPane.setLayout(null);
contentPane.setBackground(new Color(47, 79, 79));
cinput.setBounds(10, 442, 353, 20);
contentPane.add(cinput);
cinput.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
in();
cinput.requestFocus();
}
});
cinput.setColumns(10);
cinput.requestFocus();
JButton Enter = new JButton("Enter");
Enter.setBounds(373, 439, 111, 23);
contentPane.add(Enter);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 10, 474, 421);
contentPane.add(scrollPane);
cmd.setEditable(false);
cmd.setFont(new Font("Courier New", Font.PLAIN, 18));
cmd.setForeground(Color.GREEN);
cmd.setText("CONSOLE\n");
cmd.setBackground(Color.BLACK);
cmd.setLineWrap(true);
cmd.setWrapStyleWord(true);
scrollPane.setViewportView(cmd);
Enter.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
in();
cinput.requestFocus();
}
});
}
private void addText(JTextArea textArea, String text) {
String input = textArea.getText();
String output = input + text;
textArea.setText(output);
}
private void in()
{
String input = cinput.getText();
cinput.setText("");
String text;
text = input;
addText(cmd, "> " + text + "\n");
if(text.equals("start"))
{
addText(cmd, "1");
// SLEEP HERE
Thread.sleep(1000);
// -------------------
addText(cmd, "2");
}
else if(text.equals("exit"))
{
Console.dispose();
}
}
It should look something like this:
In this very basic 'Console', whenever I type 'start' in the textbox and hit enter, I want the number '1' to appear first and after 1000 mseconds the number '2' should appear, which it doesn't!
Is there any way to tell the programm to sleep between statements instead of always sleeping at the beginnig of the function?
Thanks in advance
Upvotes: 1
Views: 1773
Reputation: 1482
It looks like you are trying to put to sleep the main Thread
which is not the best idea. Run your own Thread
and put it to sleep.
Try this:
System.out.println(1);
SwingUtilities.invokeLater(() -> {
new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(2);
}
}).start();
});
You can also do this without Thread.sleep()
:
long tick = 1000;
long startTime = System.currentTimeMillis();
while (true) {
long now = System.currentTimeMillis();
while (now - startTime > tick) {
System.out.println("Seconds from start time: " + (int) (tick / 1000));
tick += 1000;
}
}
If it suites you just tweak the above example for your needs(it also accounts for possible lag so the number of seconds will still be correct).
Upvotes: 2
Reputation: 658
While technically the answers above are true, your problem is
What you want to do instead is create a helper class that wraps the javax.swing.Timer (NOT the java.util.timer) that allows you to easily run code on the event thread after a certain number of milliseconds has passed.
public abstract class LazyAction implements Runnable {
public LazyAction(int millis) {
Timer t = new Timer(millis, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try{
LazyAction.this.run();
catch(Exception e){
//Your error handling code
}
}
});
t.setRepeats(false);
t.start();
}}
Now, to use this code, you then call it by:
addText(cmd, "1");
new LazyAction(300){
@Override
public void run() {
addText(cmd, "2");
}
}
(Note if you are using Java 8 you could use Lambdas instead, in that case LazyAction would take in a Runnable rather than implementing Runnable...)
Upvotes: 4
Reputation: 8651
Put a sleep statement before adding the first line of text:
Thread.sleep(1000);
addText(cmd, "1");
// SLEEP HERE
Thread.sleep(1000);
// -------------------
addText(cmd, "2");
Upvotes: 0