timer in java button - java

I don't know how to put this code insid emy programs . Likee..if I click on the button or by mouse in JPanel (that's inside the original panel), the program will run
static class Action implements ActionListener(){
public void actionPerformed (ActionEvent e){
long serialVersionUID = 1L;
Timer timer;
long startTime = -1;
long duration = 1200000 ;
JLabel label = new JLabel;
timer = new Timer(10, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (startTime < 0) {
startTime = System.currentTimeMillis();
}
long now = System.currentTimeMillis();
long clockTime = now - startTime;
if (clockTime >= duration) {
clockTime = duration;
timer.stop();
}
SimpleDateFormat df = new SimpleDateFormat("mm:ss:SSS");
label.setText(df.format(duration - clockTime));
}
});

This is a typical problem of new programmers finding code then copying it and pasting it wherever they think is might work. As you've already realized....it's not that simple otherwise you obviously wouldn't be here seeking assistance.
There are a number of things going wrong with your provided code and this is exactly why I'll provide you with code to show you how this can work using a Local Timer within a JButton Action Event and point out some of the specific problems so that you can realize them for later on should you encounter this sort of thing again.
You don't need to declare your timer variable and then initialize it later on down the road. You can declare and initialize the timer variable right on the same line, for example:
final Timer timer = new Timer(10, new ActionListener() {
..................
..................
..................
});
Your Long data type startTime variable will never work within a Local Timer or any Inner (local) Class for that matter where value changes will need to be made. For your startTime variable to be used within the Local Timer Class it needs to carry full scope there and to do that the variable needs to be declared as final. Uhhh, there is a problem with this though, you can not change the value within a final variable which is a requirement for this countdown timer to function properly. If we don't declare the startTime variable as final then we'll just end up with a "local variables referenced from an inner class must be final or effectively final" compile error. The solution to this then is to declare and initialize the startTime variable within the Local Timer class itself like this:
final Timer timer = new Timer(10, new ActionListener() {
long startTime = -1;
#Override
public void actionPerformed(ActionEvent event) {
..................
..................
}
});
That solves that little problem. Now you have yet another problem, you can't just up and stop your Timer from within itself using the Timer.stop() method as you've done (ie: timer.stop(); ) within the Timer's actionPerformed event for the simple reason the variable timer has no proper scope there and can't see that it's been initialized. Yes, it'll probably compile and it'll most likely run right up until the timer.stop() method is called and then you'll end up getting a Runtime Exception ("variable timer might not have been initialized"). Not good, and don't think about catching the exception and letting bygones be bygones because your ultimately not stopping the Timer (crappy practice). You just need to get a little fancier with your stop and this will do the trick:
((Timer)event.getSource()).stop();
//event is the ActionEvent variable (usually evt in some IDE's).
Now, your duration variable, there is nothing wrong with this if you like to supply long number values for even 1 minute of timing. Works great if that's your thing but for me personally, I like simply entering 60 instead of 60000. It really doesn't matter if the value will be hard coded into place but if it will actually be a supplied value (regardless from where) then it's just better to supply seconds (IMHO) which would of course entail the use of an additional variable, for example:
int seconds = 10;
final long duration = seconds * 1000;
Now you only need to supply the number of seconds you want your Countdown Timer to be set at.
Another problem you have is that you've declared a variable named label to represent a JLabel but nowhere do you either reference that variable to an actual JLabel somewhere or add it to a frame or panel component. I thinking that you've already installed a JLabel within your GUI (if you have a GUI) in which case you will need to supply that JLabel variable name when you declare the label variable, like this:
JLabel label = (JLabel)jLabel1;
This way the label variable represents the JLabel named jLabel1 within your GUI.
And finally (and this is a biggy) your Timer simply wont run if you don't tell it to do so. Where do you do this, well, right under your Local Timer Class of course :) like this:
final Timer timer = new Timer(10, new ActionListener() {
long startTime = -1;
#Override
public void actionPerformed(ActionEvent event) {
..................
..................
}
});
timer.start();
Anyways, here's is the full code as promised:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
int seconds = 10; // supply timer duration in seconds
final long duration = seconds * 1000; // calculate to milliseconds
JLabel label = (JLabel)jLabel1; //whichever JLabel is in GUI
final Timer timer = new Timer(10, new ActionListener() {
long startTime = -1;
#Override
public void actionPerformed(ActionEvent event) {
if (startTime < 0) {
startTime = System.currentTimeMillis();
}
long now = System.currentTimeMillis();
long clockTime = now - startTime;
if (clockTime >= duration) {
clockTime = duration;
((Timer)event.getSource()).stop(); // stop the Timer
label.setText("Time Is UP"); // remove if you want or maybe just ""
return;
}
SimpleDateFormat df = new SimpleDateFormat("mm:ss:SSS");
label.setText(df.format(duration - clockTime));
}
});
timer.start();
}

Related

"local variables referenced from an inner class must be final or effectively final" in MouseEvent

I am trying to get the integer input from a jtextfield and set it as the integer for a timer jlabel when the jbutton is clicked but I keep getting this error inside the MouseEvent method
local variables referenced from an inner class must be final or effectively final
Code:
private void timerStartMouseClicked(java.awt.event.MouseEvent evt) {
int a = Integer.parseInt(timerInput.getText());
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
timeLeft.setText(Integer.toString(a));
--a;
if (a == -1){
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
timer.cancel();
} else if(isRunning){
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
}
}
};
timer.scheduleAtFixedRate(task, 1000, 1000);
}
I am still new with Timer Events and Mouse Events, I tried to declare a as a global var which still gives me the same error unless I declare it a value within the method but I need to get the input from the jtextfield.
Not tested, but I think this will work.
private void timerStartMouseClicked(java.awt.event.MouseEvent evt) {
final int a = Integer.parseInt(timerInput.getText());
Timer timer = new Timer();
TimerTask task = new TimerTask() {
int localCount = a;
public void run() {
timeLeft.setText(Integer.toString(localCount));
--localCount;
if (localCount == -1){
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
timer.cancel();
} else if(isRunning){
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
}
}
};
timer.scheduleAtFixedRate(task, 1000, 1000);
What's going on is that a is a local variable and is going to vanish into the ether when this method ends, therefore it's not safe to use. If the variable is final then it's safe for Java to copy the value of a into your inner class. However you need to modify a so a constant value won't work.
So we just copy the value into a different variable, one inside the inner class. This makes everything work fine, because now the inner class has its own variable to work with.

Change panel color for an interval

I want to create a program that when a button is clicked, a panel may or may not change it's color. I have an array of panels that will turn red if a wrong combination is chosen. But I just want to make it red for about 1-2 seconds. After that I will change again the panel background to null. I want every panel to have it's own timer when it goes red. So far here is my code:
javax.swing.Timer timer = new javax.swing.Timer (250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
pnlArray [count - 2][count2].setBackground (Color.RED);
};
});
pnlArray [count - 2][count2].setBackground (null);
This code generates an error: local variables referenced from an inner class must be final or effectively final. Obviously, pnlArray[][] is not a final panel. Thread.sleep() method however, freezes the whole program. How can I achieve this?
I found a solution to my question using java.util.Timer package. Since the Timer() class needs final to run the run() method, I assigned the JPanel to a final variable. Then I canceled the timer once the first delay is over.
final JPanel pnlChange = pnlArray [count - 2][count2];
pnlChange.setBackground (Color.RED);
java.util.Timer timer = new java.util.Timer ();
TimerTask task = new TimerTask () {
int seconds = 4;
int divisor = 0;
#Override
public void run() {
divisor++;
if (divisor % seconds == 0) {
timer.cancel ();
pnlChange.setBackground (null);
}
}
};
timer.schedule(task, 0, 1000);

Associating timer with tables

I am new to timer's and don't know much about them .My problem is i am creating 2 tables dynamically, and when ever a table is create a timer for 10 mins is assigned to it. I.e. the user has to fill that table in 10 mins else the table will be destroyed. I tried a making a small demo in which i print stuff
The code is :
final Timer mytimers = new Timer();
Timer mytimers1 = new Timer();
mytimers1 = new Timer();
final long delay1 = 5*1000;
// mytimers = new Timer();
mytimers.schedule(new TimerTask() {
Long current1 = System.currentTimeMillis();
long check = current1;
#Override
public void run() {
Long current = System.currentTimeMillis();
System.out.println(current);
System.out.println("\n");
if((current1 + delay1)<current)
{
System.out.println("mytimmer is about to stop");
mytimers.cancel();
}
}
}, 100, 1000);
mytimers1.schedule(new TimerTask() {
#Override
public void run() {
Long current = System.currentTimeMillis();
System.out.println("in" + current);
}
}, delay1, 1000);
}
but when i tried implementing this int he final project it does not work as i have to make any variable inside the run a final , thus its value can not to be changed !!!
Please let what should i do !!Thank you
i have to make any variable inside the run a final , thus its value can not to be changed!
Either turn these variables into member variables or encapsulate these values in a proper class, instantiate the class and give a reference to that object to the timer task.
Even though the reference is final, the timer task will still be able to do things such as myTableController.destroyTable().
do it like this :
class YourClass{
Timer mytimers = new Timer();
Timer mytimers1 = new Timer();
long delay1 = 5*1000;
mytimers.schedule(new TimerTask() {
Long current1 = System.currentTimeMillis();
long check = current1;
#Override
public void run() {
Long current = System.currentTimeMillis();
System.out.println(current);
System.out.println("\n");
if((current1 + delay1)<current) {
System.out.println("mytimmer is about to stop");
mytimers.cancel();
}
}
}, 100, 1000);
mytimers1.schedule(new TimerTask() {
#Override
public void run() {
Long current = System.currentTimeMillis();
System.out.println("in" + current);
}
}, delay1, 1000);
}
in your case you have created anonymous 'concrete' class ie TimerTask, and you are trying to access variables which are not in its scope.
So, if the variables you are trying to access are local(method) variables then they should be declared final or the other way around is to declare those variables as instant(member) variables that what i have done above.

Flashing color of a JTextField

I have a JTextField that is cleared if it has invalid content. I would like the background to flash red one or two times to indicate to the user that this has happened. I have tried:
field.setBackground(Color.RED);
field.setBackground(Color.WHITE);
But it is red for such a brief time that it cannot possibly be seen. Any tips?
The correct solution, almost arrive at by just eric, is to use a Swing Timer, since all the code in the Timer's ActionListener will be called on the Swing event thread, and this can prevent intermittent and frustrating errors from occurring. For example:
public void flashMyField(final JTextField field, Color flashColor,
final int timerDelay, int totalTime) {
final int totalCount = totalTime / timerDelay;
javax.swing.Timer timer = new javax.swing.Timer(timerDelay, new ActionListener(){
int count = 0;
public void actionPerformed(ActionEvent evt) {
if (count % 2 == 0) {
field.setBackground(flashColor);
} else {
field.setBackground(null);
if (count >= totalCount) {
((Timer)evt.getSource()).stop();
}
}
count++;
}
});
timer.start();
}
And it would be called via flashMyField(someTextField, Color.RED, 500, 2000);
Caveat: code has been neither compiled nor tested.
You need to extend public class Timer
Do it like so:
private class FlashTask extends TimerTask{
public void run(){
// set colors here
}
}
You can set Timer to execute in whatever intervals you prefer to create the flashing effect
From documentation:
public void scheduleAtFixedRate(TimerTask task, long delay, long period)
Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay.

Countdown clock in GWT

I want to create a countdown clock in GWT but I cannot find the right function that waits for one second. I tried with Thread.Sleep() but I think it is for another purpose.
Can you help me? This is my code.
int count=45;
RootPanel.get("countdownLabelContainer").add(countdown);
for(int i=count; i>=0; i--)
{
countdown.setText(Integer.toString(i));
// Place here the wait-for-one-second function
}
Give Timer a try (See Here).
Changing the example code real quick to something close to what you want, you'll want to buff this up for your purposes though:
public class TimerExample implements EntryPoint, ClickListener {
int count = 45;
public void onModuleLoad() {
Button b = new Button("Click to start Clock Updating");
b.addClickListener(this);
RootPanel.get().add(b);
}
public void onClick(Widget sender) {
// Create a new timer that updates the countdown every second.
Timer t = new Timer() {
public void run() {
countdown.setText(Integer.toString(count));
count--;
}
};
// Schedule the timer to run once every second, 1000 ms.
t.schedule(1000);
}
}
This sounds like something in the general area of what your looking for. Note that you can use timer.cancel() to stop the timer. You'll want to tie this in with your count (when 45 hits 0).
The following snippet showing the use of the timer works too. It shows how to schedule the timer properly and how to cancel it.
// Create a new timer that updates the countdown every second.
Timer t = new Timer() {
int count = 60; //60 seconds
public void run() {
countdown.setText("Time remaining: " + Integer.toString(count) + "s.");
count--;
if(count==0) {
countdown.setText("Time is up!");
this.cancel(); //cancel the timer -- important!
}
}
};
// Schedule the timer to run once every second, 1000 ms.
t.scheduleRepeating(1000); //scheduleRepeating(), not just schedule().

Categories