Make a timer in swing - java

For this game I'm making for java class, I want a timer display in the corner that counts up from 0
I made a variable that represents seconds, which ==> double s =0;
My idea was that using a Timer object where I could increment the variable every second and use the repaint() method on the string
However, I misinterpreted how the timer object works, and after the delay it counts up rapidly to infinity. I have no idea what to do now. A hint would be appreciated.
Here is my code,thanks for any help:
int delay = 5000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
s=(int)s+1;
}
};
new Timer(delay, taskPerformer).start();
String t = "" + s;
g.drawString(t, 100, 100);
repaint();

How about something like this: (you might have to change it for your needs)
boolean temp=true;
long startTime = System.nanoTime();
while(temp){
float time = (System.nanoTime()-startTime)/ 10000000.000f;
System.out.println(time);
}

What you can try doing is implementing the Runnable interface and then starting a new Thread of the class that you are using to draw your Components. Since Thread implements the Runnable interface, you will be able to create a new point of execution in the program where you can call a delay with Thread.sleep() before repainting your components. Here is an example of what you should try doing:
Thread thread = new Thread(ClassNameHere);
thread.start();
If you are interested in trying this out, more information can be found on the API on Threads and on the Runnable interface.

Related

Java reset timertask based on a mouse movement

I have a Java Swing component that prints "hello" every 1 minute.
timer = new Timer();
timer.schedule(new HelloWordTask(), TIME, TIME);
However, I want to reset timertask when a user moves mouse.
int count = 0;
private CustomMouseAction extends MouseAdapter {
#Override
public void mouseMoved(MouseEvent e) {
timer.cancel();
timer = new Timer();
timer.schedule(new HelloWordTask(), TIME, TIME);
System.out.println("moved " + count++);
}
}
Whenever I am moving a mouse, my timer gets rescheduled, which is the expected behaviour. However, it means that new Timer is created for every "bit" of movement. For example, when I move my mouse around 5 cm, ~30 print statements show up.
Is there a way to make the program more efficient? Moreover, would it be possible to somehow "reduce" the mouseMoved detection rate? For example, instead of being called 30 times, can I make it only being called 10 times (I assume if this was possible, there is a small chance to miss refresh chance).
Test with different n values until you're satisfied.
int count = 0, lastX = 0, lastY = 0, n = 30;
private CustomMouseAction extends MouseAdapter {
#Override
public void mouseMoved(MouseEvent e) {
int ix= e.getX();
int iy= e.getY();
if (Math.abs(lastX-ix)<n && (Math.abs(lastY-iy)<n) return;
lastX= ix;
lastY= iy;
timer.cancel();
timer = new Timer();
timer.schedule(new HelloWordTask(), TIME, TIME);
System.out.println("moved " + count++);
}
}
For example, when I move my mouse around 5 cm, ~30 print statements show up.
Is there a way to make the program more efficient?
This is the whole point of event driven programming. The OS generates the event so you know the user is doing something. You can't control how frequently the events are generated. You can only control the processing you do when the event is generated.
However, it means that new Timer is created for every "bit" of movement.
You should not be using a util.Timer. Instead you should be using a javax.swing.Timer.
Don't keep creating a new Timer in the mouseMoved() method. Instead you should create and start the Timer when your frame is made visible. Then in the mouseMoved() method you just invoke the restart() method of the Timer.
See: Application Acvitity for a reusable class that you may find helpful.

Changing the delay of the timer without creating a new one every time the method runs

So basically I have a timer method in my program which uses the integer z as it's parameter as well as the delay for the timer itself. But every time I run this method, it creates a new timer not deleting the old one. So I decided to add an if else block that made it so that it only created a timer on the first time but now it's saying that it might not have been initialized because it was initialized in the if else block. Can someone help me?
public void timer(int z) {
int count = 0;
Timer tester;
z = (60000 / z);
decide = true;
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {noteDecider();}
};
if(count == 0) {
tester = new Timer(z, taskPerformer);
tester.start();
}
else {
tester.setDelay(z);
tester.start();
}
count++;
}
I would say that if you are concern about optimizing your code you should look into optimizing your Timer class. Like moving the ActionListener object inside Timer itself and more. All your timer(int z) method is doing is trying to use an object to keep track time not managing the lifecycle of Timer objects.

Swing Timer Not Working (Java)

For some reason even though I am using the exact code example from oracle's website for the Swing Timer it is not waiting for 1 second. It just skips to the JOptionPane that says "Your score was etc etc".
Here is my source code for a school project. Why is this not working and not waiting for 1 second before running the rest of the code?
//Check to see if user has enetered anything
if(!answered)
{
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
}
};
new Timer(delay, taskPerformer).start();
afk = true;
incorrect += 1;
answered = true; //This breakes it out of the loop
}
A timer is used to run a callback after a specific amount of time. If you simply want to delay, you can either move the code to be run after the delay into the taskPerformer action listener.
Thread.sleep(1000) is not ideal here, because it will cause the UI to completely freeze as you will make the UI thread sleep.

Keeping timer events equally spaced

I'm attempting to get an animation working in a game I'm developing. The animation works by setting a button size to very small, then gradually growing it to its normal size again. I have it working, except I'm having timing issues.
Sometimes the button will grow almost instantly, sometimes it goes VERY slow. I'm looking for something inbetween, and I need it to ALWAYS grow at that size, not some times fast sometimes slow.
I've looked into it and I found this pseudocode:
distance_for_dt = speed * delta_time
new_position = old_position + distance_for_dt
Unfortunately I don't understand what's being said, and I don't know how to apply this to my code. Can anyone help with that or explain what's being said in the above pseudocode?
Here's my timer code, timer is already defined above as a Timer, and z[] is just a pair of coordinates:
timer = new Timer(18, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Dimension dim = button[z[0]][z[1]].getSize();
if (dim.getHeight() < 79.9) {
button[z[0]][z[1]].setSize((int) (dim.getWidth() + 6), (int) (dim.getHeight() + 6));
} else {
button[z[0]][z[1]].setSize(80, 80);
timer.stop();
}
}
});
timer.start();
Depending on how many updates you're calling on your Swing application, it may be getting "backed up" and slowing down. For instance, if you wanted to accomplish the animation without a Timer, you could just do something like this:
// example method to do animation
public void animateButton(final int wait){
Thread thread = new Thread(){
public void run(){
// some loop structure to define how long to run animation
Dimension dim = button[z[0]][z[1]].getSize();
while (dim.getHeight() < 79.9){
SwingUtilities.invokeLater(new Runnable(){
//update Swing components here
});
try{ Thread.Sleep(wait); }
catch(Exception e){}
}
}
}
}
thread.start();
}
I think this may be similar to how a Timer updates the GUI, as Timers run on a separate thread. I would look into whether or not you need to use invokeLater(new Runnable) inside a timer to properly schedule the task. I had to do this to allow a project I was working on to keep responsive during long tasks. If you really needed to ensure the speed and maybe DROP updates to adjust for system lag, then you'll need to be calculating how complete the animation is vs how much time has passed, using a method call such as System.currentTimeMillis() or System.nanoTime(). Then, adjust accordingly for each step of the animation.

Recurring Countdown Timer in Java

I'm trying to implement a countdown timer into a pre-existing public class and I have a few questions.
An overview: I want to have a timer within a program that counts down from 60 (seconds) once the program is initialized.
If the timer reaches zero, the program quits.
If the user meets certain parameters within the 60 second time frame, the timer resets to 60, presents a new set of parameters, and begins the countdown again. It should be able to do this an infinite number of times, until the user fails to meet parameters within 60 seconds.
There will also be some sort of (TBD) GUI representation of the timer, most likely either numerical countdown or JProgressBar.
I'm semi-new (~3 months) to programming, self-taught, and still learning lots (so be gentle) :)
My questions are:
What is the best way to implement this?
I'm assuming this needs to run in a thread?
Will the timer be easily configurable? (not important, just interesting)
Thanks for your help. If you need to see code, I can find some.
EDIT: Just for some clarification/context:
This is for a timed racing video game I'm working on to develop my skills as a programmer. The idea is that a player has 60 seconds to complete a lap. If the player completes a successful lap, the timer resets to 60 seconds and the track changes to be slightly more difficult. The game runs until the player is unable to complete a lap in 60 seconds due to the difficulty. The game records the number of laps as a high score, and asks to player if they would like to try again.
If I were you, I'd use:
an AtomicInteger variable which would keep the current countdown value;
a timer thread that would wake up every 1s and decrementAndGet() the variable, comparing the result to zero and terminating the app if the result is zero;
(possibly) a thread that would also wake up every 1s to repaint the GUI -- the best approach here depends on your GUI framework.
Finally, whenever you need to reset the count back to 60s, you just call set(newValue) from any thread.
The timer thread's run() method could be as simple as:
for (;;) {
if (counter.decrementAndGet() <= 0) {
// TODO: exit the app
}
Thread.sleep(1000);
}
I think it's much easier to get this right than trying to manage multiple Timer objects.
The best way to impliment timer in your application is using some sheduler frameworks like Quartz
You could use java.util.Timer to schedule an execution of a method and then cancel it if the requirements is met.
Like this:
timer = new Timer();
timer.schedule(new Task(), 60 * 1000);
And then make a class like this to handle the timerschedule:
class Task extends TimerTask {
public void run() {
System.exit(0);
}
}
If the requirements is met, then do this to stop it from executing:
timer.cancel();
If you need to update your GUI better to use SwingWorker http://en.wikipedia.org/wiki/SwingWorker
I would write something like this:
SwingWorker<String, Integer> timer = new SwingWorker<String, Integer>() {
Integer timer=60;
#Override
protected String doInBackground() throws Exception {
//update guiModel
//label.setText(timer.toString());
while(timer>0){
Thread.sleep(1000);
timer--;
}
return null;
}
#Override
public void done(){
System.exit(0);
}
};
JButton restart = new JButton(){
{
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.cancel(true);
timer.execute();
}
});
}
};

Categories

Resources