I want to run a function every hour, to email users a hourly screenshot of their progress. I code set up to do so in a function called sendScreenshot()
How can I run this timer in the background to call the function sendScreenshot() every hour, while the rest of the program is running?
Here is my code:
public int onLoop() throws Exception{
if(getLocalPlayer().getHealth() == 0){
playerHasDied();
}
return Calculations.random(200, 300);
}
public void sendScreenShot() throws Exception{
Robot robot = new Robot();
BufferedImage screenshot = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
screenshotNumber = getNewestScreenshot();
fileName = new File("C:/Users/%username%/Dreambot/Screenshots/Screenshot" + screenshotNumber +".");
ImageIO.write(screenshot, "JPEG", fileName);
mail.setSubject("Your hourly progress on account " + accName);
mail.setBody("Here is your hourly progress report on account " + accName +". Progress is attached in this mail.");
mail.addAttachment(fileName.toString());
mail.setTo(reciepents);
mail.send();
}
Use a ScheduledExecutorService:
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
sendScreenShot();
}
}, 0, 1, TimeUnit.HOURS);
Prefer using a ScheduledExecutorService over Timer:
Java Timer vs ExecutorService?
According to this article by Oracle, it's also possible to use the #Schedule annotation:
#Schedule(hour = "*")
public void doSomething() {
System.out.println("hello world");
}
For example, seconds and minutes can have values 0-59, hours 0-23, months 1-12.
Further options are also described there.
java's Timer works fine here.
http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
public void run() {
// ...
}
}, delay, 1 * 3600 * 1000); // 1 hour between calls
For this type of period execution, meaning every day or every hour, all you need is using a Timer like this :
public static void main(String[] args) throws InterruptedException {
Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, 7);
today.set(Calendar.MINUTE, 45);
today.set(Calendar.SECOND, 0);
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
System.out.println("I am the timer");
}
};
// timer.schedule(task, today.getTime(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); // period: 1 day
timer.schedule(task, today.getTime(), TimeUnit.MILLISECONDS.convert(5, TimeUnit.SECONDS)); // period: 5 seconds
}
this exemple will execute the timetask every 5 seconds from the current date and 7:45 am.
Good Luck.
while (true) {
DateTime d = new DateTime();
switch(d.getMinuteOfHour()) {
case 56:
runHourly();
break;
case 41:
if(d.getHourOfDay() == 2) {
runAt0241Daily();
}
break;
}
SUM.wait(59000);
}
How about this for something you can control and understand?
Related
This is my code.
public class SetTimer extends Thread{
// set it on false from outside you want to stop
private boolean runSignal = true;
// sleep time
private final long SLEEP_TIME = 10*1000; //900 detik = 15 menit
PageReaderKontan pn = new PageReaderKontan();
PageReaderBisnis pb = new PageReaderBisnis();
FileListener fileListener = new FileListener();
Timer timer = new Timer();
boolean keep = true;
public void run(){
while (runSignal){
pn.run();
System.out.println("Kontan Finished.\n");
pb.run();
System.out.println("Bisnis Finished.\n");
fileListener.run();
doSleep(); //go to sleep
checkTime();
}
}
public void checkTime(){
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date alarmTime = calendar.getTime();
timer.schedule(new TimerTask() {
#Override
public void run() {
stopRunning();
System.out.println("Compiling runs here...");
timer.cancel();
timer.purge();
return;
}
}, alarmTime);
System.out.println("Time checked.");
}
//sleep between listening folder iteration
public void doSleep(){
try{
System.out.println("I go to sleep for 10 seconds now...");
sleep(SLEEP_TIME);
}
catch (InterruptedException e){
System.out.println(e.getMessage());
}
}
//stop running this thread when application stops
public void stopRunning(){
System.out.println("Bye!");
this.runSignal = false;
}
}
after the application prints "Compiling runs here...", it returns to run the thread over and over again. how is my code wrong?? please help me i'm really having a hard time understand how thread works. thanks a lot. :)
EDIT 1 - this is the console output.
Kontan Finished.
Bisnis Finished.
I go to sleep for 10 seconds now...
Time checked.
Bye!
Compiling runs here...
Kontan Finished.
Bisnis Finished.
I go to sleep for 10 seconds now...
Time checked.
Bye!
Compiling runs here...
...........
EDIT 2 - Update... I'm using System.exit() to jump out of the endless loop and end the application.
public void checkTime(){
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date alarmTime = calendar.getTime();
timer.schedule(new TimerTask() {
#Override
public void run() {
stopRunning();
System.out.println("Compiling runs here...");
System.out.println("Application is closing...");
System.exit(0);
}
}, alarmTime);
System.out.println("Time checked.");
}
Please declare your runSignal boolean as volatile. Volatile guarantees that the thread reading the variable sees the changes done to it by another thread just before reading it. In your case it looks like the Timer thread which is changing the value of runSignal is not read by your other thread which is executing run and hence it is not stopping.
private volatile boolean runSignal = true;
EDIT:-
By doing the below changes your code works absolutely fine. The reason for doing this change is to avoid any exceptions trying to schedule a timer which is already cancelled.
Write a method called:-
public void stopTimer() {
timer.cancel();
timer.purge();
}
Call this method from your run method as below:-
public void run(){
while (runSignal){
pn.run();
System.out.println("Kontan Finished.\n");
pb.run();
System.out.println("Bisnis Finished.\n");
fileListener.run();
doSleep(); //go to sleep
checkTime();
}
stopTimer();
}
And remove the timer cancel from your timer schedule method as below:-
timer.schedule(new TimerTask() {
#Override
public void run() {
stopRunning();
System.out.println("Compiling runs here...");
return;
}
}, alarmTime);
I actually have a video streaming application and I want to show the time for how much the two people have chatted with eachother. I have used Timer and TimerTask of java.util class but it gives error as "Not on FX application thread" which means I cant setText to a java fx component using swing thread. This is what I have tried so far:-
int timerx=0 //global variable
private void timer(){
/*SHOWING TIME PASSED*/
int x=0;
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
System.out.println("working");
setTime();
}
};
timer.schedule(timerTask, 50, 50);
}
And updating the javafx Label as:-
private void setTime(){
timerx = timerx +1;
Platform.runLater(new Runnable(){
public void run(){
time.setText(String.valueOf((timerx)));
System.out.println(time.getText());
}
});
}
I think the main problem is javafx component not being able to update and be accessed from swing thread. I would be glad to get any kind of help.
Thank you
You can use something like this:
long timeStart = System.currentTimeMillis();
when the chat start and get how long two guys chatted with something like this:
long timePassed = System.currentTimeMillis() - timeStart;
This will get you how many millisecond have passed. If you want to get second divide it by 1000. Oh and if you want it on thread, just create a thread for this thingy..
ok thank you all for your answers. I solved my problem by running a thread and using algorithm that will show the time in 00:00:00 format which I wanted to make. Here is the code
private void startTime(){
if(timerStats==false)
{
timerStats = true;
timer = new Timer();
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
System.out.println("working" + x);
timersec ++;
Platform.runLater(new Runnable(){
public void run(){
if (timersec == 60)
{
timersec = 0;
timermin++;
}
if (timermin == 60)
{
timermin = 0;
timerhr++;
}
String seconds = Integer.toString(timersec);
String minutes = Integer.toString(timermin);
String hours = Integer.toString(timerhr);
if (timersec <= 9)
{
seconds = "0" + Integer.toString(timersec);
}
if (timermin <= 9)
{
minutes = "0" + Integer.toString(timermin);
}
if (timerhr <= 9)
{
hours = "0" + Integer.toString(timerhr);
}
time.setText(hours + ":" + minutes +":"+ seconds);
System.out.println(time.getText());
}
});
}
};
timer.schedule(timerTask, 50, 50); //lastone is time, milli second
}
}
Thank you
So I wanted to try out something for a bit with the Timer and TimerTask classes.
I was able to get a line of code to execute after 30 seconds elapsed.
What I've been trying to do now is to get this line of code to execute for 5 minuets.
This is what I originally tried
public static void main(String[] args)
{
for ( int i = 0; i <= 10; i ++ )
{
Timer timer = new Timer();
timer.schedule( new TimerTask()
{
public void run()
{
System.out.println("30 Seconds Later");
}
}, 30000
);
}
}
I used the number 10 in the for loop to see if the timer.schedule would wait for another 30 seconds during the next iteration of the loop.
Any idea how I should go about this? I tried using the schedule method with a parameter passed in for period, but that only made it re-execute and it never stopped.
Java has provided a rich set of APIs in java.util.concurrent package to achieve such tasks. One of these APIs is ScheduledExecutorService. For example consider the code given below: This code will execute the Runnable task after every 30 seconds for upto 5 minutes:
import java.util.concurrent.*;
class Scheduler
{
private final ScheduledExecutorService service;
private final long period = 30;//Repeat interval
public Scheduler()
{
service = Executors.newScheduledThreadPool(1);
}
public void startScheduler(Runnable runnable)
{
final ScheduledFuture<?> handler = service.scheduleAtFixedRate(runnable,0,period,TimeUnit.SECONDS);//Will cause the task to execute after every 30 seconds
Runnable cancel = new Runnable()
{
#Override
public void run()
{
handler.cancel(true);
System.out.println("5 minutes over...Task is cancelled : "+handler.isCancelled());
}
};
service.schedule(cancel,5,TimeUnit.MINUTES);//Cancels the task after 5 minutes
}
public static void main(String st[])
{
Runnable task = new Runnable()//The task that you want to run
{
#Override
public void run()
{
System.out.println("I am a task");
}
};
Scheduler sc = new Scheduler();
sc.startScheduler(task);
}
}
The issue you're running into is that the scheduled Timer runs on a different thread - that is, the next iteration of your for loop starts running immediately after scheduling, not 30 seconds later. It looks like your code starts ten timers all at once, which means they should all print (roughly) 30 seconds later, all at once.
You were on the right track when you tried using the recurring version of schedule (with the third parameter). As you noted, this isn't quite what you want because it runs indefinitely. However, Timer does have a cancel method to prevent subsequent executions.
So, you should try something like:
final Timer timer = new Timer();
// Note that timer has been declared final, to allow use in anon. class below
timer.schedule( new TimerTask()
{
private int i = 10;
public void run()
{
System.out.println("30 Seconds Later");
if (--i < 1) timer.cancel(); // Count down ten times, then cancel
}
}, 30000, 30000 //Note the second argument for repetition
);
here's a workaround I'm ashamed of presenting:
package test;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class FiveMinutes {
private static int count = 0;
// main method just to add example
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
System.out.println("Count is: " + count);
if (count == 1) {
System.err.println("... quitting");
System.exit(0);
}
count++;
}
},
// starting now
new Date(),
// 5 minutes
300000l
);
}
}
Also please note that the application might not run exactly 5 minutes - see documentation for TimerTask.
Your solution is pretty close to working, you just have to multiply the delay by the counter (in your case, i):
public static void main(String[] args)
{
for (int i = 1; i <= 10; i++) // start i at 1 for initial delay
{
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run()
{
System.out.println("30 Seconds Later");
}
}, 30000 * i); // 5 second intervals
}
}
I don't know if this solution has problems with the garbage collector or not, but I throw it in here anyways. Maybe someone clears that out, and I learn something as well. Basically a timer sets a new timer if there is time left, and it should stop after 5 minutes.
Main.java:
public class Main {
public static void main(String[] args) {
MyTimer myTimer = new MyTimer(300000,30000);
myTimer.startTimer();
}
}
MyTimer.java:
import java.util.Timer;
import java.util.TimerTask;
public class MyTimer {
private int totalRunningTime;
private int currentTime = 0;
private int intervalTime;
private Timer timer = new Timer();
public MyTimer(int totalRunningTime, int intervalTime) {
this.totalRunningTime = totalRunningTime;
this.intervalTime = intervalTime;
}
public void startTimer() {
startTimer(intervalTime);
}
private void startTimer(int time) {
timer.schedule(new TimerTask() {
public void run() {
if (currentTime <= totalRunningTime - intervalTime) {
printTimeSinceLast(intervalTime / 1000);
currentTime += intervalTime;
startTimer(intervalTime);
} else if (currentTime < totalRunningTime) {
int newRestIntervalTime = totalRunningTime - currentTime;
printTimeSinceLast(newRestIntervalTime / 1000);
currentTime += newRestIntervalTime;
startTimer(newRestIntervalTime);
}
}
}, time);
}
private void printTimeSinceLast(int timeSinceLast) {
System.out.println(timeSinceLast + " seconds later.");
}
}
Hi m using the following timer task,and i want to increase the time of this task when a certain condition occurs
Timer timer2=new Timer();
timer2.schedule(new TimerTask(){
public void run(){
//whatevr
}
}, 4000);
examlpe
if(mycondition)
{
increase time????
}
how can i do that
Extract the TimerTask in an inner or standalone class. Cancel currently running timer task and schedule a new instance with increased time period.
You can't. You'll have to schedule a new task with the incremented period. And if the previous task has become obsolete, make sure that you cancel() it.
For future reference, I recommend you utilize the Executors framework.
Submit another one task from run() if necessary:
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimerTaskTest {
private static class MyTimerTask extends TimerTask {
private final Timer timer;
private boolean fire;
private MyTimerTask(Timer timer) {
this(timer, false);
}
private MyTimerTask(Timer timer, boolean fire) {
this.timer = timer;
this.fire = fire;
}
#Override
public void run() {
if (!fire) {
System.out.println(new Date() + " - steady...");
timer.schedule(new MyTimerTask(timer, true), 2000);
} else {
System.out.println(new Date() + " - go!");
}
}
}
public static void main(String args[]) {
Timer timer = new Timer(true);
MyTimerTask timerTask = new MyTimerTask(timer);
System.out.println(new Date() + " - ready...");
timer.schedule(timerTask, 4000);
try {
Thread.sleep(7000);
} catch (Exception ignore) {
}
}
}
I want to implement a clock within my program to diusplay the date and time while the program is running. I have looked into the getCurrentTime() method and Timers but none of them seem to do what I would like.
The problem is I can get the current time when the program loads but it never updates. Any suggestions on something to look into would be greatly appreciated!
What you need to do is use Swing's Timer class.
Just have it run every second and update the clock with the current time.
Timer t = new Timer(1000, updateClockAction);
t.start();
This will cause the updateClockAction to fire once a second. It will run on the EDT.
You can make the updateClockAction similar to the following:
ActionListener updateClockAction = new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Assumes clock is a custom component
yourClock.setTime(System.currentTimeMillis());
// OR
// Assumes clock is a JLabel
yourClock.setText(new Date().toString());
}
}
Because this updates the clock every second, the clock will be off by 999ms in a worse case scenario. To increase this to a worse case error margin of 99ms, you can increase the update frequency:
Timer t = new Timer(100, updateClockAction);
You have to update the text in a separate thread every second.
Ideally you should update swing component only in the EDT ( event dispatcher thread ) but, after I tried it on my machine, using Timer.scheduleAtFixRate gave me better results:
java.util.Timer http://img175.imageshack.us/img175/8876/capturadepantalla201006o.png
The javax.swing.Timer version was always about half second behind:
javax.swing.Timer http://img241.imageshack.us/img241/2599/capturadepantalla201006.png
I really don't know why.
Here's the full source:
package clock;
import javax.swing.*;
import java.util.*;
import java.text.SimpleDateFormat;
class Clock {
private final JLabel time = new JLabel();
private final SimpleDateFormat sdf = new SimpleDateFormat("hh:mm");
private int currentSecond;
private Calendar calendar;
public static void main( String [] args ) {
JFrame frame = new JFrame();
Clock clock = new Clock();
frame.add( clock.time );
frame.pack();
frame.setVisible( true );
clock.start();
}
private void reset(){
calendar = Calendar.getInstance();
currentSecond = calendar.get(Calendar.SECOND);
}
public void start(){
reset();
Timer timer = new Timer();
timer.scheduleAtFixedRate( new TimerTask(){
public void run(){
if( currentSecond == 60 ) {
reset();
}
time.setText( String.format("%s:%02d", sdf.format(calendar.getTime()), currentSecond ));
currentSecond++;
}
}, 0, 1000 );
}
}
Here's the modified source using javax.swing.Timer
public void start(){
reset();
Timer timer = new Timer(1000, new ActionListener(){
public void actionPerformed( ActionEvent e ) {
if( currentSecond == 60 ) {
reset();
}
time.setText( String.format("%s:%02d", sdf.format(calendar.getTime()), currentSecond ));
currentSecond++;
}
});
timer.start();
}
Probably I should change the way the string with the date is calculated, but I don't think that's the problem here
I have read, that, since Java 5 the recommended is: ScheduledExecutorService I leave you the task to implement it.
This sounds like you might have a conceptual problem. When you create a new java.util.Date object, it will be initialised to the current time. If you want to implement a clock, you could create a GUI component which constantly creates a new Date object and updates the display with the latest value.
One question you might have is how to repeatedly do something on a schedule? You could have an infinite loop that creates a new Date object then calls Thread.sleep(1000) so that it gets the latest time every second. A more elegant way to do this is to use a TimerTask. Typically, you do something like:
private class MyTimedTask extends TimerTask {
#Override
public void run() {
Date currentDate = new Date();
// Do something with currentDate such as write to a label
}
}
Then, to invoke it, you would do something like:
Timer myTimer = new Timer();
myTimer.schedule(new MyTimedTask (), 0, 1000); // Start immediately, repeat every 1000ms
public void start(){
reset();
ScheduledExecutorService worker = Executors.newScheduledThreadPool(3);
worker.scheduleAtFixedRate( new Runnable(){
public void run(){
if( currentSecond == 60 ) {
reset();
}
time.setText( String.format("%s:%02d", sdf.format(calendar.getTime()), currentSecond));
currentSecond++;
}
}, 0, 1000 ,TimeUnit.MILLISECONDS );
}
For those preferring an analog display: Analog Clock JApplet.
Note the method scheduleAtFixedRate is used here
// Current time label
final JLabel currentTimeLabel = new JLabel();
currentTimeLabel.setFont(new Font("Monospace", Font.PLAIN, 18));
currentTimeLabel.setHorizontalAlignment(JTextField.LEFT);
// Schedule a task for repainting the time
final Timer currentTimeTimer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
currentTimeLabel.setText(TIME_FORMATTER.print(System.currentTimeMillis()));
}
};
currentTimeTimer.scheduleAtFixedRate(task, 0, 1000);
Timer timer = new Timer(1000, (ActionEvent e) -> {
DateTimeFormatter myTime = DateTimeFormatter.ofPattern("HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
jLabel1.setText(String.valueOf(myTime.format(now)));
});
timer.setRepeats(true);
timer.start();