ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
logger.finest("Reading SMTP Info.");
}
};
Timer timer = new Timer(100 ,taskPerformer);
timer.setRepeats(false);
timer.start();
According to the documentation this timer should fire once but it never fires.
I need it to fire once.
This simple program works for me:
import java.awt.event.*;
import javax.swing.*;
public class Test {
public static void main(String [] args) throws Exception{
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
System.out.println("Reading SMTP Info.");
}
};
Timer timer = new Timer(100 ,taskPerformer);
timer.setRepeats(false);
timer.start();
Thread.sleep(5000);
}
}
This Program will work fine...
setRepeats(boolean flag) function used to set call the function(actionPerformed) repeatedly or only one time if
timer.setRepeats(false) == timer calls the actionperformed method for only one time
timer.setRepeats(true) == timer calls the actionPerformed method repeatedly based on specified time
Swing Timer Work
do the task one time
do the task repeated time
steps to create swing timer:
create the actionlistener
create the timer constructor then pass time and actionlistener in that
implement the actionPerformed() function in which do your task
use timer.start() for start the task between the time specified in timer constructor, use timer.stop() for stop the task
Example:
ActionListener al=new ActionListener() {
public void actionPerformed(ActionEvent ae) {
//do your task
if(work done)
timer.stop();//stop the task after do the work
}
};
Timer timer=new Timer(1000,al);//create the timer which calls the actionperformed method for every 1000 millisecond(1 second=1000 millisecond)
timer.start();//start the task
Your task likely only needs to report results on the event thread (EDT) but do the actual work in a background thread at some periodic rate.
ScheduledExecutorService is EXACTLY what you want. Just remember to update the state of your UI on the EDT via SwingUtility.invokeLater(...)
I'm guessing from the log statement that you're doing some sort of SMTP operation. I think I'm right in saying the java.swing.Timer is intended for UI related timed operations, hence why it needs and EDT running. For more general operations you should use java.util.Timer.
This article is linked from the JavaDocs - http://java.sun.com/products/jfc/tsc/articles/timer/
Related
I hava a simple countdown that checks every few Milliseconds if a variable is false.
When it is false, the timer should be stopped. But it does not work for me. Why? And how would I fix this? I tried multiple ways I found in other threads, but none seem to work.
> final Timer countdown = new Timer(10, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (Fight.isStatus()== false) {
((Timer)evt.getSource()).stop();
((Timer)evt.getSource()).setRepeats(false);
}
}
});
countdown.setRepeats(true);
countdown.start();
You can create a TimerTask instance with your task. TimerTask task = new YourTask(); And say task.cancel();
I do not know how to use cancel method in your code.
So i want to print out a word every second for 10 seconds, but nothing is working
Here's my code:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
public class Main{
public static void main (String[] args){
class TimerListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
System.out.println("helo");
}
}
ActionListener dummy = new TimerListener();
Timer power_up_time = new Timer(10000,dummy);
power_up_time.addActionListener(dummy);
power_up_time.start();
}
}
EDIT: so i added the start function and it still doesnt work
I believe that you need to start a Timer in order to make it work.
Something like this:
Timer timer = new Timer(500, new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
timer.start();
In newer versions of Java (from the last ten years or so) I would suggest using a ScehduledExecutorService
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleAtFixedRate(() -> System.out.println("hello"), 0, 1, TimeUnit.SECONDS);
TimeUnit.SECONDS.sleep(10);
ses.shutdown();
If the code you posted is complete you are starting the timer right before the application (i.e. the main thread) terminates. Thus the scheduler won't run long enough to execute the timer.
Try sleeping or running in a loop with some exit condition (that's probably what you'll want to do anyways).
You do not initialize and start the Swing toolkit, hence your application immediately terminates.
If you really want to use the Swing Timer, you need to show at least some window or dialog, so that the Swing event thread is running, e.g. by adding the following to the end of your main() method:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new JFrame("Frame title").setVisible(true);
}
});
See the other answers for alternatives outside of Swing.
I need to make a GUI where a worker enters a station (a spot on the panel) and stays there for a set amount of seconds, shown in a countdown about the workers head (so, once the workers moves to the spot, the station's label shows 3s -> 2s -> 1s and then the worker leaves, and the label reverts back to "OPEN"). I'm having trouble with making this happen, as I'm not too good with the Timer(s?) that Java has. I tried with something like this:
Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e)
{
//change label text/color, decrement countdown
panel.repaint();
Thread.sleep(1000);
}
});
But I can't reach the number of seconds to count down from from inside the timer, and I'm not sure how to pass that value to the timer. If someone can help me out, I'd really appreciate it.
Get rid of the Thread.sleep(). That's what the 1000 in Timer(1000, new ActionListener() does. It sets an interval for each timer event. Every time a timer event is fired, the actionPerformed is called. So you need to determine what needs to happen every "tick", and put that code in the actionPerformed. Maybe something like
Timer timer = new Timer(1000, new ActionListener() {
private int count = 5;
#Override
public void actionPerformed(ActionEvent e) {
if (count <= 0) {
label.setText("OPEN");
((Timer)e.getSource()).stop();
count = 5;
} else {
label.setText(Integer.toString(count);
count--;
}
}
});
You need to decide when to call timer.start().
For general information, see How to Use Swing Timers
Problem #1: You are calling Thread.sleep() from within the Swing GUI thread. That causes the thread to stop taking input and freeze. Delete that line. It does you no good! While you are at it, delete the repaint call as well.
Now that that's said and done, instead of creating an anonymous instance of ActionListener, you can create an actual class that implements ActionListener and provides a constructor. That constructor can have as an argument the number of seconds you want to start counting down. You can declare that class inside the method you are using, or you can declare it inside the class.
Here's a skeletal example:
public class OuterClass {
JLabel secondsLabel = ...;
Timer myTimer;
private void setupTimer(int numSecondsToCountDown) {
secondsLabel.setText(Integer.toString(numSecondsToCountDown));
myTimer = new Timer(1000, new CountdownListener(numSecondsToCountDown));
myTimer.start();
}
// ...
class CountdownListener implements ActionListener {
private int secondsCount;
public CountdownListener(int startingSeconds) { secondsCount = startingSeconds; }
public void actionPerformed(ActionEvent evt) {
secondsLabel.setText(Integer.toString(secondsCount);
secondsCount--;
if (secondsCount <= 0) { // stop the countdown
myTimer.stop();
}
}
}
}
I need to wait a few seconds between invoking two different methods in a program with Swing interface. Those methods are not related to the GUI.
firstMethod();
//The interface is changed by other methods
...
//I want to Wait five seconds
secondMethod();
I have tried using a Swing Timer but it does not work. Apparently, the Timer starts but is a non-blocking action, so secondMethod() is executed immediately. I can use sleep(), but that freezes the GUI for those five seconds, so the interface is not updated until after that, which I would prefer to avoid.
I have found here some recommendations to use Future<V> and I have read the Javadoc but I have never used ExecutorService before and I am afraid I may write a too complex piece of code for something that simple.
Any idea on how to do it?
Sounds like your code is something like:
firstMethod();
startTimer();
secondMethod();
I have tried using a Timer but it does not work
You can't just start a Timer and do nothing. When the timer fires you need to invoke the secondMethod(...) in the actionPerformed of the Timer.
Use Swing Timer instead of Java Timer and Thread.sleep.
Please have a look at How to Use Swing Timers
Timer timer = new Timer(5000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
secondMethod();
}
});
timer.setRepeats(false);
timer.start()
A timer won't just stop code execution like sleep does.
You have to assign an ActionListener to it which will be notified when the time is up.
It goes something like this:
firstMethod();
Timer t = new Timer(5000);
t.setRepeats(false);
t.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
secondMethod();
}
})
t.start();
Basically, I have this game where once guesses the correct answer it starts a new game with a new word. I want to display Correct! but after three seconds, change it to a empty string. How do I do that?
My attempt:
if (anagram.isCorrect(userInput.getText()))
{
anagram = new Anagram();
answer.setText("CORRECT!");
word.setText(anagram.getRandomScrambledWord());
this.repaint();
try
{
Thread.currentThread().sleep(3000);
}
catch (Exception e)
{
}
answer.setText("");
} else
{
answer.setForeground(Color.pink);
answer.setText("INCORRECT!");
}
Edit:
My solution:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)
{
// TODO add your handling code here:
if (anagram.isCorrect(userInput.getText()))
{
answer.setText("CORRECT!");
ActionListener taskPerformer = new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
anagram = new Anagram();
word.setText(anagram.getRandomScrambledWord());
answer.setText("");
userInput.setText("");
}
};
Timer timer = new Timer(3000, taskPerformer);
timer.setRepeats(false);
timer.start();
} else
{
answer.setForeground(Color.pink);
answer.setText("INCORRECT!");
}
}
I am not sure, but I hope that I am following MadProgrammer's advice and not blocking the event itself, but the new thread. I will look up Java Timer also.
Swing is an event driven environment. While you block the Event Dispatching Thread, no new events can be processed.
You should never block the EDT with any time consuming process (such as I/O, loops or Thread#sleep for example).
You might like to have a read through The Event Dispatch Thread for more information.
Instead, you should use a javax.swing.Timer. It will trigger a ActionListener after a given delay.
The benefit of which is that the actionPerformed method is executed with the context of the Event Dispatching Thread.
Check out this or this or this or this for an examples
it works after 3 seconds..
ActionListener taskPerformer = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
statusbar.setText("Status");
}
};
Timer timer = new Timer(3000, taskPerformer);
timer.setRepeats(false);
timer.start();
if these piece of code is in the event handlers, then you are holding up the UI thread, and it is not going to work as UI update will only happens after you finished your work in the event handlers.
You should create another thread do the work of "sleep 3 second, and change the text field, and trigger repaint". Using Timer or similar utilities is the easiest way to achieve what I am describing.