I have a simple GUI that can save and get some data out of an .doc file.
When i press a save button, i have a label that says "Succes" or "Error" via label.setText();
Update: The code is meant to be ran in a FXMLDocumentController (built på SceneBuilder)
I want the label to go back to being empty ("") after 3 seconds..
I have tried:
try { Thread.sleep(1000); } catch(InterruptedException ex) {
Thread.currentThread().interrupt();}
but is it like, that the sleep-function freezes the whole GUI so i can't interact with it while it's sleeping. How do i set up an timer that does not affect usability? :)
6 Answers
Create a TimerTask which is started after 3 seconds. This TimerTask has to execute the code which uses gui components via Platform.runLater(new Runnable())
Timer timer = new Timer();
timer.schedule(new TimerTask() { @Override public void run() { Platform.runLater(new Runnable() { @Override public void run() { label.setText(""); } }); } }, 3000); 5 class runnable implements Runnable { private Object obj; public runnable(Object obj) { this.obj = obj; } public void run() { try { Thread.sleep(3000); this.obj.setText("");//right here just execute your method } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Hello from a thread!"); //your code here }
}
public class Test { public static void main(String[] args){ Object myObject; (new Thread(new runnable(myObject))).start(); }
}You could launch another thread to handle this. Just do your processing in the other thread. Sleep for 3 seconds then clear the lbl.
Here is an example showing how it works:
class runnable implements Runnable { Test test; public runnable(Test test) { this.test = test; } public void run() { try { Thread.sleep(3000); this.test.test = "test2"; } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Hello from a thread!"); }
}
public class Test { public String test = "test"; public static void main(String[] args) throws InterruptedException{ Test test = new Test(); System.out.println(test.test); (new Thread(new runnable(test))).start(); Thread.sleep(4000); System.out.println(test.test); }
}************************************************************UPDATE*************************************************************
class runnable implements Runnable { Test test; public runnable(Test test) { this.test = test; } public void run() { try { Thread.sleep(3000); this.test.label.setText("This is a test."); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("Hello from a thread!"); }
}
public class Test { public String test = "test"; JLabel label = new JLabel("Test"); JFrame frame = new JFrame(); JButton button = new JButton(); public static void main(String[] args) throws InterruptedException{ Test test = new Test(); test.label.setText("Test"); test.button.setText("Test Button"); test.button.setSize(50, 50); test.frame.setSize(500, 500); test.frame.add(test.button); test.frame.add(test.label); test.frame.setVisible(true); test.button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub System.exit(0); } }); (new Thread(new runnable(test))).start(); }
} 8 Don't use Thread.sleep(). Instantiate a javax.swing.Timer and have it do an event callback. If you want to keep it in the same method, call wait(), and then have the event handler call notify(), which will resume the program. However, you probably don't need to do that; you can just remove the text directly using the event handler.
To do this you will have to use threading. In case you are using Swing you can use a Swing Timer. The code will look something like this. Put this code where you are 'saving' the file.
int delay = 3000; ActionListener taskPerformer = new ActionListener() { public void actionPerformed(ActionEvent evt) { //Empty the label here. This code will be called once the timeout of three seconds has been passed } }; new Timer(delay, taskPerformer).start(); Your problem is your are blocking the UI thread. It cannot update anything and the main loop breaks. You can accomplish your goal with a timer object as others have answered, or if you don't want to you could implement your own thread to do the same.
You cannot interact with GUI because the code is sleeping in event dispatch thread which is responsible for handling GUI events and so it's blocked. Use this Swing Timer instead.
The given example there is simple. I include the comments.
int delay = 1000; //milliseconds //Create action listener which listens for the event generated by the timer ActionListener taskPerformer = new ActionListener() { public void actionPerformed(ActionEvent evt) { Place here code to execute when the time runs out. } }; //Simply create a timer with the created listener and start it. new Timer(delay, taskPerformer).start(); 1