I'm creating a java paint program and can't figure out how to implement a timer that starts when the GUI is opened so the user can see their time spent drawing so far. My code is pasted below. I'm a complete beginner and have searched all the oracle documents and can't understand them so any help is appreciated! Hopefully there's a simple way of implementing this.
I added a JLabel onto my toolbar so I can try and post the "Drawing Time: "+totalTime but it stays at 0 for some reason I don't know how to make it refresh every second...
I would try something like this:
Set up the Global Variables (Make sure you fix your imports)
public class MainWindow extends javax.swing.JFrame implements ActionListener{
//global variable for tracking time
Timer timer;
final int DELAY = 1000; //the delay for the timer (1000 milliseconds)
int myCounter;
then initialize the timer and counter and make sure to send the info from the counter to your label
public MainWindow() {
initComponents();
//initialize the timer and the counter
timer = new Timer(DELAY, this);
timer.start();
myCounter = 0;
}
//method needed for the timer, since this class implements ActionListener
//this method will get called however often the DELAY is set for
#Override
public void actionPerformed(ActionEvent e){
myCounter++;
labelOutput.setText(Integer.toString(myCounter));
}//end of method
This is a pretty basic example of setting up a timer, so if you just apply the steps taken in the code I've given you to your own application, you'll probably be able to get it working. Good luck!
Related
I'm a bit lost on this. So here's some code for an ActionListener:
public static void main(String[] args)
{
ActionListener listener = new ActionListener(){
public void actionPerformed(ActionEvent event){
System.out.println("hello");
}
};
Timer displayTimer = new Timer(5000, listener);
displayTimer.start();
}
And it prints hello over and over... I don't quite understand. why doesn't it just print once?
thanks
Because you are using a Timer and haven't called displayTimer.setRepeats(false);
However, I recommend using a ExecutorService instead of Timer. See this question. There are a few things that a Timer in Java is lacking, see this question which will also help you setup an ExecutorService that will behave just like a Timer that you are used to.
As the documentation to (Timer)[http://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html] says, your constructor initializes the timer with both an initial delay and a between-event delay of five seconds. The timer thus executes your ActionListener every five seconds.
I'm trying to implement a very simple stopwatch widget in my Android activity such that the user can hit start/reset to start the timer, and stop to stop it. All of the functionality is there, but I can't seem to find a way to constantly display the value of this stopwatch.
I'm currently using a custom object that stores a long value representing the time the Stopwatch object was created, a constructor that sets this long value to the current time, and a displayTime method that returns the a double value representing the current time in seconds by subtracting the current time from the original time and divides by 1000.0.
Like I said, functionally it's flawless, but I can't see a way to constantly update a TextView object with the value of displayTime(). Can anyone suggest as simple of a solution as possible to accomplish this? Thank you!
You need to use Timer class for this purpose.
ActionListener timerTask = new ActionListener() {
public void actionPerformed(ActionEvent e) {
lblTime.setText("Set your time here");
}
};
Timer timer = new Timer(500, timerTask);
timer.start();
For Timer Class Information and API
Class Timer API
How to Use Swing Timers
The easiest way is probably to use a Handler.
private Handler h = new Handler();
private Runnable update = new Runnable() {
void run() {
// update the time in the text view here
h.postDelayed(this, 1000); // reschedule the update in 1 sec
}
};
// to start the update process
h.postDelayed(update, 0); // run the update the first time
Can anyone tell me why does this timer run only once?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TimerTest implements ActionListener{
private Robot r;
private Timer t;
private int i;
public TimerTest(){
i = 0;
try {
r = new Robot();
} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t = new Timer(1000, this);
t.setRepeats(true);
t.start();
}
public static void main(String [] args){
new TimerTest();
}
#Override
public void actionPerformed(ActionEvent arg0) {
i++;
System.out.println("Action..." + i);
}
The funny thing is that, if I decrease the delay in the Timer to just 100, it works as expected. And what's even funnier is that if I delete the code in which I initialize the Robot, it doesn't work at all, the program terminates as soon as I run it.
I've tried this on Windows 7 and on Ubuntu (although on Ubuntu I couldn't use the Robot at all, since I get an exception. Something related to rights, maybe).
Your main is processed so the program stops. You can test it by using this code, adding it to TimerTest()
JFrame testFrame = new JFrame();
testFrame.setVisible(true);
testFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
That JFrame keeps your main not from finshing, when you close the Frame the TimerTest ends. Which concludes your main which causes the main to finsh. Ending the program and stoping your swing timer.
See "main exits before javax.swing.Timer's start() can start" at the bug database.
Evaluation
Described behavior - when application exits before Swing timer is started - is correct. Here is what's going then:
Swing timer is created.
Separate thread for swing timer is started. It will notify attached actionListeners when the timeout is passed by posting an instance of InvocationEvent to EDT.
Main thread exits.
At this moment there is no non-daemon threads running in JVM. Application is terminated.
..the evaluator goes on to add..
..This looks like a RFE rather than a defect.
One surefire way to make it behave is to create a GUI element and display it. Which is why I asked earlier..
..why exactly are you creating the timer without any GUI elements? Is this for repeated screen-shots?
To handle that situation, I would typically create and show a frame to allow the user to configure the rate and area for screenshots, then minimize the frame and begin processing when the user clicks:
Screen Capture!
I have an abstract class as follows:
abstract class Grapher implements Runnable{
... member variables...
Timer timer;
boolean Done;
public void run(){
Done = false;
timer.start();
while(!Done){}
}
public void Grapher(){ //create graph}
...
}
The idea is that I want to have this abstract thread that creates a graph. I then want to extend this class to provide the implementation of what data that should be plotted on the graph. For example:
class RandomGraph extends Grapher{
ActionListener taskPerformer;
public RandomGraph(){
timer = new Timer(1000, taskPerformer);
taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// generate random data and add it to the graph data;
// if ... Done = true
}
};
}}
This should then plot random data to the graph. The problem I'm having is that I'm getting completely stuck in the while(!done) loop. Putting System.out.printlns inside the actionListener tell me the timer does not seem to be working as nothing appears on the console.
Am I being stupid for using threads at all? I thought it might be a good idea If I want the graph to plot data every few milliseconds.
You're passing null to the Timer constructor — you need to initialize taskPerformer first :-)
To address your bigger question: No, you're not stupid for using threads. However, I question your use of an abstract class at all here. What you really want is an interface Grapher describing an object that draws graphs, then a concrete subclass of Runnable (say, GrapherRunner) that sets up the timer, then delegates to a grapher to do the work.
(In OO-speak, this means using composition rather than inheritance.)
How can I call a method every n seconds?
I want to do a slideshow with Swing and CardLayout and every n seconds
it must show a different image calling a different method
import java.util.*;
class MyTimer extends TimerTask
{
public void run()
{
//change image
}
}
then in your main you can schedule the task:
Timer t = new Timer();
t.schedule(new MyTimer(), 0, 5000);
first number is initial delay, second is the time between calls to run() of your TimerTask: 5000 is 5 seconds.
As BalusC noted usually you dispatch swing changes on AWT event thread. In this simple cause it shouldn't create problems when changing background from an outside thread, in any case you should use
public static void SwingUtilities.invokeLater(Runnable whatToExecute)
to dispatch your change on the right thread.
If you prefer BalusC approach just use an ActionListener:
public void BackgroundChange implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
//change bg
}
}
javax.swing.Timer t = new javax.swing.Timer(5000, new BackgroundChange());
They both provide same functionality, but this later one is already prepared to work out together with Swing threads mantaining compatibility and avoiding strange synchronizations issues.
Since you're using Swing, you would like to use javax.swing.Timer for this. Here's a Sun tutorial on the subject.
For any more than trivial animation in Swing app, check out Trident: http://kenai.com/projects/trident/pages/Home