How to make a Timer? - java

I want to make a Timer that waits 400 MSc and then goes and prints "hi !" (e.g.). I know how to do that via javax.swing.Timer
ActionListener action = new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
System.out.println("hi!");
}
};
plus :
timer = new Timer(0, action);
timer.setRepeats(false);
timer.setInitialDelay(400);
timer.start();
but as I know this definitely is not a good way as this kind of Timer is for Swing works. how to do that in it's correct way? (without using Thread.sleep())

Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
System.out.println("Hi!");
}
}, 400);

You can consider Quartz scheduler, it's a really scalable, easy to learn and to configure solution. You can have a look at the tutorials on the official site.
http://quartz-scheduler.org/documentation/quartz-2.1.x/quick-start

import java.text.SimpleDateFormat;
import java.util.Calendar;
public class currentTime {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
System.out.println( sdf.format(cal.getTime()) );
}
}

TimeUnit.MILLISECONDS.sleep(150L);
is an alternative;
You could also take a look at this Question
Which suggests using a while loop which just waits
or a ScheduledThreadPoolExecutor

Related

Scheduling java process for a specific time interval with a given delay

We want to schedule a java process to run till a specific time interval. Currently I am thinking to using TimerTask to schedule this process. In the start of every loop, will check the current time and then compare with the given time and stop the process if the time is elapsed.
Our code is something like below:
import java.util.Timer;
import java.util.TimerTask;
public class Scheduler extends TimerTask{
public void run(){
//compare with a given time, with getCurrentTime , and do a System.exit(0);
System.out.println("Output");
}
public static void main(String[] args) {
Scheduler scheduler = new Scheduler();
Timer timer = new Timer();
timer.scheduleAtFixedRate(scheduler, 0, 1000);
}
}
Is there a better approach for this?
Instead of checking if the time limit has been reached in every single iteration you could schedule another task for the said time limit and call cancel on your timer.
Depending on the complexity you might consider using a ScheduledExecutorService such as ScheduledThreadPoolExecutor. See in this answer when and why.
Simple working example with timer:
public class App {
public static void main(String[] args) {
final Timer timer = new Timer();
Timer stopTaskTimer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
System.out.println("Output");
}
};
TimerTask stopTask = new TimerTask() {
#Override
public void run() {
timer.cancel();
}
};
//schedule your repetitive task
timer.scheduleAtFixedRate(task, 0, 1000);
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse("2015-06-09 14:06:30");
//schedule when to stop it
stopTaskTimer.schedule(stopTask, date);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
You can use RxJava, a very powerful library for reactive programming.
Observable t = Observable.timer(0, 1000, TimeUnit.MILLISECONDS);
t.subscribe(new Action1() {
#Override
public void call(Object o) {
System.out.println("Hi "+o);
}
}
) ;
try {
Thread.sleep(10000);
}catch(Exception e){ }
You can even use the lambda syntax:
Observable t = Observable.timer(0, 1000, TimeUnit.MILLISECONDS);
t.forEach(it -> System.out.println("Hi " + it));
try {
Thread.sleep(10000);
}catch(Exception e){ }

Actionlistener of a Timer object displays nothing

i am usin the timer class and in the docs it is written that i should import javax.swing.Timer to use it. does it mean that i can not use it in my normal java file? because i tried the below code, and it displays nothing:
static ActionListener timeStampListener = new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
System.out.println("action listener");
for (int i = 1; i <= logfile.getTotalLines(); i++) {
System.out.println("Engine Time(ms): " +
logfile.getFileHash().get(i).getTimeStampInSec());
}
}
};
Timer t = new Timer(2, timeStampListener);
t.setRepeats(true);
t.start();
the problem is your main thread exist before starting timer thread .since your application is non-gui use util.Timer instead Swing.Timer ..if you want to work this code using swing timer then add a swing component .add new jframe() and see it's working ..you don't need swing.timer use util timer .
static ActionListener timeStampListener1 = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("hi");
}
};
public static void main(String[] args) {
new JFrame(); //add this line
Timer t = new Timer(2, timeStampListener1);
t.setRepeats(true);
t.start();
}
or give some times by adding thread.sleep to timer to on and see it's working
Timer t = new Timer(2, timeStampListener1);
t.setRepeats(true);
t.start();
Thread.sleep(1000);
this is how can u use util timer for this
imports
import java.util.Timer;
import java.util.TimerTask;
code
public static void main(String[] args) {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println("action listener");
for (int i = 1; i <= logfile.getTotalLines(); i++) {
System.out.println("Engine Time(ms): "
+ logfile.getFileHash().get(i).getTimeStampInSec());
}
}
}, 500, 2);
}
No, it means that you should import which Timer class you will use. When you import javax.swing.Timer you specifies Timer class in javax.swing package. You can use it in your java file.
Anyway, have you tried not using static keyword with your timeStampListener?

Counting and printing time in java using swing

I'm trying to implement a timer using one thread and print it on a JButton using another thread.
my class for time is like this:
public class Time extends Thread
{
int counter = 0;
public String currentTime = new String();
public String printFormat(int second)
{
return String.format("%d:%d", second/60, second%60);
}
synchronized public void count(int minute) throws InterruptedException
{
minute *= 60;
while(minute >= 0)
{
wait(1000);
minute--;
currentTime = printFormat(minute);
System.out.println(currentTime);
}
}
and my main thread is like this:
button.setText(time.currentTime);
what is wrong with this piece of code?
"if you can explain it using java swing timer , I would appreciate that"
If you want to use a javax.swing.Timer do the following, it really simple.
The same way you set a ActionListener to a button, you do the same for the timer. Except instead of the button firing the event, it's fired by the timer, every duration period you set for it.
In the case of a clock like timer, you would set it to 1000,
indication do something every 1000 milliseconds.
In this particular
example, I just set the text of the button with a count value that I
increment by one every time the timer event is fired. Heres the Timer code
Timer timer = new Timer(1000, new ActionListener(){
public void actionPerformed(ActionEvent e) {
button.setText(String.valueOf(count));
count++;
}
});
timer.start();
As you can see it' pretty simple
You can run this example
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class ButtonTimer {
private JButton button = new JButton(" ");
private int count = 1;
public ButtonTimer() {
Timer timer = new Timer(1000, new ActionListener(){
public void actionPerformed(ActionEvent e) {
button.setText(String.valueOf(count));
count++;
}
});
timer.start();
JFrame frame = new JFrame();
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ButtonTimer();
}
});
}
}
If you want help trying to figure out your current code, consider posting a runnable program we can test out. So we can see where you're going wrong.
Here's a tutorial on Concurrency With Swing

converting to ScheduledThreadPoolExecutor

I am still a beginner at Java so I have not learned much about threads and concurrency. However, I would like to be able to use the ScheduledThreadPoolExecutor as a timer because of the problems I am having with java.util.Timer and TimerTask. I am extremely interested in the creation of threads and know that I will be learning about them in a few weeks. However, if possible could someone give me a basic example on how to convert my current mini test program using util.timer to using a ScheduledThreadPoolExecutor?
I would like to complete this example ASAP so I don't have much time to learn about threads - no matter how much I would like to. Having said this please include anything you feel is important that a java beginner should know with regards to ScheduledThreadPoolExecutor.
Example program
I have made a quick small example to represent the problem I am having in a larger program. What this program should do is allow the user to press a button to start a counter. The user must then be able to stop and restart the counter when ever s/he wants. In the larger program it is vital that this counter remains equal so I have used the
scheduleAtFixRate()
method. It is also important that the initial delay is always the same (in this case 0).
The problem (as I am sure you will see) is that once the timer is cancelled it cannot be restarted - something that I hope the ScheduledThreadPoolExecutor will resolve.
code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.TimerTask;
import java.util.Timer;
public class Tester extends JFrame {
JButton push = new JButton("Push");
static JTextArea textOut = new JTextArea();
Timer timer = new Timer();
boolean pushed = false;
static int i = 1;
public Tester() {
super();
add(push, BorderLayout.NORTH);
add(textOut);
push.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!pushed) {
timer.scheduleAtFixedRate(new Task(), 0, 1000);
pushed = true;
} else {
timer.cancel();
pushed = false;
}
}
});
}
static class Task extends TimerTask {
public void run() {
textOut.setText("" + i++);
}
}
public static void main(String[] args) {
Tester a = new Tester();
a.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
a.pack();
a.setVisible(true);
}
}
I use this class a lot for testing so there may be extra code (I think I removed it all).
Replace
Timer timer = new Timer();
with
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
and
class Task extends TimerTask
with
class Task implements Runnable
and
timer.scheduleAtFixedRate(new Task(), 0, 1000);
with
service.scheduleAtFixedRate(new Task(), 0, 1000, TimeUnit.MILLISECONDS);
BTW You should not be attempting to update the GUI on another thread. Instead you have to add a task to the Swing GUI Thread to perform the task
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
textOut.setText("" + i++);
}
});

Creating digital clock using a thread

I am trying to create a digital clock using a Thread as this seems to me the logical way one would do it.
I am not sure if I am going about it the right way but what I had in mind is to create the initial current System time using the JFrame constructor and display it as text using a label. In the constructor I then create the thread object with which to update the time.
Struggling a bit and was hoping for some advice as to how to do it right.
setDefaultCloseOperation((JFrame.EXIT_ON_CLOSE));
setBounds(50, 50, 200, 200);
JPanel pane = new JPanel();
label = new JLabel();
//Font localTime = new Font("Lumina", Font.BOLD , 24);
pane.add(label);
add(pane);
sdf = new SimpleDateFormat("HH:mm:ss");
date = new Date();
s = sdf.format(date);
label.setText(s);
setVisible(true);
runner = new Thread(this);
while(runner == null)
{
runner = new Thread(this);
runner.start();
}
This is then my run() method to update the clock every second.
public void run()
{
while(true)
{
try
{
Thread.sleep(1000);
sdf = new SimpleDateFormat("HH:mm:ss");
date = new Date();
s = sdf.format(date);
label.setText(s);
}
catch(Exception e){}
}
Main method.
public static void main(String[] args)
{
new DigitalClock().setVisible(true);
}
The label state should be updated in the Event Dispatch Thread.
You need to add the following modification:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
label.setText(s);
}
});
instead of simply updating the label from the separate thread.
It's worth to have a look at the simple description of The Swing GUI Freezing Problem and it's simple solution.
What do you want to improve? It looks ok, while(runner == null) not necessary, you're initialising runner just above.
Check this class http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Timer.html
scheduleAtFixedRate(TimerTask task, long delay, long period) is probably what you need.

Categories