Timer Schedule - Java - java

new java.util.Timer().scheduleAtFixedRate(timeleft(), 0, 1000);
This is my code for a method timeleft() that i want to happen every second.
My class is called Timer.
Not sure why I'm getting an error.
It says "void type not allowed here" when I hover over the line.
I am using a JFrame for a GUI and put this inside an event when I press a button along with a timer that counts down from whatever number you enter in a text field.

You state:
I am using a JFrame for a GUI and put this inside an event when I press a button along with a timer that counts down from whatever number you enter in a text field.
I'm going to recommend that you consider throwing out the code that you're asking your question on, to completely re-think your approach.
If you want to create and run a repeated event in a Swing GUI, don't use a java.util.Timer as you're doing, since you can easily run into serious Swing threading issues. Instead use a Swing Timer, a Timer that works well with Swing, since all code in the Timer's ActionListener is guaranteed to run on the Swing event thread.
To start you out, your code could look something like:
int timerDelay = 1000; // 1000 msecs or 1 second
Timer timer = new Timer(timerDelay, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// code that needs to be repeated goes here
}
});
timer.setInitialDelay(0);
timer.start();
Although for a count-down timer, I'm not sure that I'd set the initial delay to 0. Instead, I'd let it wait the period.

As you can see from the javadoc, the scheduleAtFixedRate method accepts a TimerTask as a first argument. You seem to be trying to pass the result of a method, named timeleft(), with a void return type.
If you need to execute some code at a fixed rate, then you need to create a TimerTask object with an appropriate run implementation and pass that to scheduleAtFixedRate.

Related

Periodic calls to repaint over time

So, I have an object that extends JPanel and displays dots in a matrix via paintComponent. The dots of the matrix can move, disappear or multiply given certain conditions, and I want to show their evolution over time automatically like so:
for(int i = 0; i < 100; ++i){
matrix = calculateNextMatrix(); //Calculate possible movements, deaths or births of dots
myGraphic.updateMatrix(matrix); //Pass new dots to the JPanel object
myGraphic.repaint(); //Draw new dots
Thread.sleep(100); //Wait 0.1 seconds for next iteration (yes, this should be in a
//try-catch)
}
However, I only get drawn the last iteration after the loop is finished, and all the previous calls to repaint() are basically ignored. If I do the iterations only one at a time (for example, via a manual button press), I have no problem.
Is there any way to get multiple, periodic repaint calls automatically?
I had a simile problem with JComponent in my library and I found a solution with swing timer, I reported the java description of timer
In general, we recommend using Swing timers rather than general-purpose timers for GUI-related tasks because Swing timers all share the same, pre-existing timer thread and the GUI-related task automatically executes on the event-dispatch thread. However, you might use a general-purpose timer if you don't plan on touching the GUI from the timer, or need to perform lengthy processing.
You can use Swing timers in two ways:
To perform a task once, after a delay.
For example, the tool tip manager uses Swing timers to determine when to show a tool tip and when to hide it.
To perform a task repeatedly.
For example, you might perform animation or update a component that displays progress toward a goal.
I think you are in one of this cases.
Without a minimal example reproducible, I can use the my code.
You should create the Swing action listener, like this:
public class UpdateComponentListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
count += 10;
timeLabel.setText(count + "");
//The label call repaint
//in your app you should be call the repaint
//In your cases
/*
matrix = calculateNextMatrix(); //Calculate possible movements, deaths or births of dots
myGraphic.updateMatrix(matrix); //Pass new dots to the JPanel object
myGraphic.repaint();
*/
}
}
The timer constructor get in input the delay and the action listener, so you can build your timer, with this code:
Timer timer = new Timer(1000, new UpdateComponentListener());
timer.start();
You can stop, restart your timer, so you should be set how propriety the timer.
The GUI example:
I wrote the post and after I see the #camickr comment. I post the answer because my work is finished but, the comment answered your question.
I hope to have to build a food example

JTextfield not updating till end of JButton action performed method? Tried using repaint,sleep still no use [duplicate]

I'm creating a board game using a GUI and JFrames/JPanels where you can play against the computer. I have a method called showPieces() which updates board GUI by changing the image icons on an array of buttons (which are laid out in a grid format). Once the icons have been updated the revalidate() and repaint() methods to update the GUI.
The showPieces() method has a parameter that needs to be passed to it every time it is called.
The main issue I'm having is I want the human to make a move, update the GUI, wait 1 second, the computer makes it's move and then loop until someone wins.
My basic code is the following:
do{
human.makeMove();
gui.showPieces(data);
try {
Thread.sleep(1000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
computer.makeMove()
gui.showPieces(data);
}while(playing);
This cause the issue where when the human player makes their move, the GUI will freeze for one second and then after the delay, both moves are made at the same time.
I hope it makes sense, but I'm a novice with Java and may have to look more into threading as I don't understand it well enough.
Thread.sleep() is done on the Event Dispatch Thread which will lock the GUI.
So If you need to wait for a specific amount of time, don't sleep in the event dispatch thread. Instead, use a timer.
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
}
};
new Timer(delay, taskPerformer).start();
As with most all similar Swing questions, you're putting your entire Swing GUI to sleep by calling Thread.sleep(...) on the GUI's event thread (the EDT or Event Dispatch Thread), and when during this period the GUI will not be able to update its images or interact with the user whatsoever. The solution here is not to use Thread.sleep(...) but rather to use a Swing Timer to cause your 1 second delay.
Swing Timer Tutorial.

JFrame not updating before thread.sleep()

I'm creating a board game using a GUI and JFrames/JPanels where you can play against the computer. I have a method called showPieces() which updates board GUI by changing the image icons on an array of buttons (which are laid out in a grid format). Once the icons have been updated the revalidate() and repaint() methods to update the GUI.
The showPieces() method has a parameter that needs to be passed to it every time it is called.
The main issue I'm having is I want the human to make a move, update the GUI, wait 1 second, the computer makes it's move and then loop until someone wins.
My basic code is the following:
do{
human.makeMove();
gui.showPieces(data);
try {
Thread.sleep(1000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
computer.makeMove()
gui.showPieces(data);
}while(playing);
This cause the issue where when the human player makes their move, the GUI will freeze for one second and then after the delay, both moves are made at the same time.
I hope it makes sense, but I'm a novice with Java and may have to look more into threading as I don't understand it well enough.
Thread.sleep() is done on the Event Dispatch Thread which will lock the GUI.
So If you need to wait for a specific amount of time, don't sleep in the event dispatch thread. Instead, use a timer.
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
}
};
new Timer(delay, taskPerformer).start();
As with most all similar Swing questions, you're putting your entire Swing GUI to sleep by calling Thread.sleep(...) on the GUI's event thread (the EDT or Event Dispatch Thread), and when during this period the GUI will not be able to update its images or interact with the user whatsoever. The solution here is not to use Thread.sleep(...) but rather to use a Swing Timer to cause your 1 second delay.
Swing Timer Tutorial.

Java-Swing : The ImageIcon cannot change in runtime?

I have this code in java
private void buttonShowImageActionPerformed(java.awt.event.ActionEvent evt)
{
if(folderFiles != null)
{
for(int i=0; i<folderFiles.size(); i++)
{
icon = new ImageIcon(folderFiles.get(i));
labelImage.setIcon(icon);
timeDelay(2); // A method that delays 2 secs - it works
}
}
}
When I push the button, it waits some time, and from the 1st goes to the last image, and skips the images from the folder one-by-one
The delay method works (I tested it)
Thanks in advance !
Regarding:
timeDelay(2); // A method that delays 2 secs - it works
No, it doesn't work, regardless of how you tested it. Swing doesn't work that way, and you would do well to avoid making such assumptions. Use a Swing Timer.
You will ask, how do I know that it doesn't work, and I'll tell you: that code does not call a background thread, nor does it start a Swing Timer, so the only thing it can do is delay the current thread, likely somewhere with a Thread.sleep(...). If you call this and "test" this, yes, it will cause delays that will show up in your System.out.println(...) statements to the console, but it will also sleep the Swing event thread, and put your application to sleep. So you really don't want to do this.
And in fact the best test to see if this works in Swing is your current code. What happens then? You state:
When I push the button, it waits some time, and from the 1st goes to the last image, and skips the images from the folder one-by-one
So in fact you know for a fact that your delay doesn't work for Swing, as you describe the classic symptoms of code that stomps on the Swing event thread, bringing it to its knees. So again, use a Swing Timer. Here's a link to the Swing Timer Tutorial.
If this were my code, I'd not read in the images each time the button is pushed, but instead read them all at once, and one time only and put them in an ArrayList<ImageIcon> say called iconList. Assuming that you did this, then the code could look like:
private void buttonShowImageActionPerformed(java.awt.event.ActionEvent evt) {
// !! I'd use a variable or constant instead of the magic number 2000
new Timer(2000, new ActionListener() {
int count = 0;
actionPerformed(ActionEvent e) {
if (count != iconList.size()) {
labelImage.setIcon(iconList.get(count));
count++;
} else {
// stop the Timer
((Timer) e.getSource()).stop();
}
}
}).start();
}
Edit
You ask:
My friend one last question ..... I put the "int count = 0;" inside the actionPerformed and nothing happend ... I cannot understand why it works only if it is outside the method .... ?
Please understand that the way a Swing Timer works is that the actionPerformed method is called repeatedly, here every 2000 seconds. What my code does is that when the timer is started, the count is set to 0. Each time the actionPerformed method is called, count increments by 1, and the next ImageIcon is displayed.
With your code, when the actionPerformed method is called, the count is re-set to 0, the first image is displayed, and the count is then incremented. But each time the actionPerformed method is called, your code resets the count back to 0, so the incrementation has no effect.

Destroy messageBox by Timer

I show some messageBox in my program. For example, if i save the data successfully, messageBox shows me "Successfull". But I want to make it close by timer. When it passes two second, it should be closed.I don't need prepared code. It's enough if you tell me the way to do it. My platform is GWT by the way.
Best Regards..
There might be better ways to do this other than Timer. However with timer you would be
using the GWT's com.google.gwt.user.client.Timer class.
http://code.google.com/p/google-web-toolkit/source/browse/trunk/user/javadoc/com/google/gwt/examples/TimerExample.java
Timer t = new Timer() {
public void run() {
Window.alert("Nifty, eh?");
// your messageBox code
t.cancel(); // Since you only need this run once.
}
};
// Schedule the timer to run once in 2 seconds.
t.schedule(2000);

Categories