GWT: Timer and Scheduler Classes
Use Scheduler when you need a browser to complete whatever it is currently doing before you tell it to do something else. For example:
myDialogBox.show();
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
myTextBox.setFocus();
}
});
In this example, focus will not be set until the browser completes rendering of the dialog, so you tell the program to wait until the browser is ready.
Use Timer if you want some action to happen after a specified period of time. For example:
notificationPanel.show();
Timer timer = new Timer() {
@Override
public void run() {
notificationPanel.hide();
}
};
timer.schedule(10000);
This code will show notificationPanel, and then it will hide it after 10 seconds.
What is the difference between Scheduler and Timer in GWT?
Use the Timer class to
schedule work
to be done in the future.Use the Scheduler for
deferring some logic
into the immediate future
Scheduler says:
If you are using a timer to schedule a UI animation, use AnimationScheduler
instead. The browser can optimize your animation for maximum performance.
For detailed description please have a look at DevGuideCodingBasicsDelayed.
GWT provides three classes that you can use to defer running code until a later point in time:
Timer
DeferredCommand
IncrementalCommand
Please have a look on below posts:
- Using the GWT Scheduler
- GWT: Timer and Scheduler Classes
GWT Timer UnsatisfiedLinkError when testing with Jukito
Avoid using Timer
and use com.google.gwt.core.client.Scheduler
instead. Then you can bind an actual scheduler in prod code, and the StubScheduler
in tests.
You can make Timer
works using gwtmockito, but I as you are already using injection, you really should hide any native or GWT.create
call behind abstractions, and use alternative implementation for tests.
Using the GWT Scheduler
JavaScript (in a browser) is single threaded. The event loop model means, we're always in exactly one of two states:
- in the event loop
- executing an event handler
There are many kinds of events: Click events, onload events, XHR events, timer events, ... You'll have to declare some handlers (at least one during page load), otherwise none of your code will ever be executed. One of them is the handler you specify by implementing onModuleLoad
.
It's important to keep all handlers short, because there's no parallelism and no interrupts (except for the last resort "unresponsive script" interrupt). This means, that users can't interact with the interface, until the browser returns to the event loop - and that doesn't happen before the current handler is finished.
So if you want to defer some code until after the other event handlers had a chance, then you can use Scheduler.scheduleDeferred
.
Scheduler.scheduleIncremental
helps you to split really long running tasks into multiple steps, giving the other event handlers a chance between each of the steps.
Scheduler.scheduleFinally
just means: After handling our current handler (even if an exception occurs), but before returning to the event loop, execute my command.
See com.google.gwt.core.client.impl.Impl.entry0()
GWT Timer lifecycle
The Timer.schedule(int delayMillis)
method adds itself (the instance of Timer) to a List of Timers (source code from 2.5.0-rc1):
/**
* Schedules a timer to elapse in the future.
*
* @param delayMillis how long to wait before the timer elapses, in
* milliseconds
*/
public void schedule(int delayMillis) {
if (delayMillis < 0) {
throw new IllegalArgumentException("must be non-negative");
}
cancel();
isRepeating = false;
timerId = createTimeout(this, delayMillis);
timers.add(this); // <-- Adds itself to a static ArrayList<Timer> here
}
From comment by @veer explaining the scheduler thread:
The timer is going to be handled by a scheduler thread that holds a
reference to the Timer and thus righfully prevents it from being
garbage collected.
Timer is not working in GWT,
Your code tells the browser to redirect immediately, with no delay.
If you want to redirect after a delay, then
Window.Location.assign(Url) ;
should be called inside the run
method of a Timer.
How to add a timer for a specific method in java?
You can organize an asynchroneous method execution with a timeout with java.util.concurrent
package
ExecutorService executorService = ...
Object res = executorService.submit(new Callable<Object>() {
public Object call() throws Exception {
... your logic
}
}).get(timeout, TimeUnit.MILLISECONDS);
Timer Based Application In GWTP
Could try something like:
Timer t = new Timer() {
@Override
public void run() {
popUpPanel.hide();
}
};
popUpPanel.show();
t.schedule(5000);
Where 5000
is how long you want to show the pop up for.
Understanding schedule deferred in GWT
JavaScript (in the browser at least) works with an event queue and the main thread polling that queue. When you call Scheduler.scheduleDeferred
, setTimeout
is called in JavaScript with a delay of 1 millisecond. This will queue a "timer fired" event in the browser after the delay has expired, with the SchedulerCommand
you passed as argument (actually, there's another queue involved within Scheduler
, but that doesn't change the overall flow of actions).
So, what your code is saying here is: delay "In task1" by 1 millisecond, then print "In task2", then after 1 millisecond (and after possibly processing other events present in the queue), print "In task1".
See http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout for the gory details of how setTimeout
works in browsers.
Countdown clock in GWT
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).
Related Topics
Java - Regular Expression Finding Comments in Code
Retrieving Servlet Context, Session and Request in a Pojo Outside Container
Parsing a Hexadecimal String to an Integer Throws a Numberformatexception
Incompatible Jvm in Ggts (Eclipse) and Java 1.8
Create a List of Primitive Int
Best Practices to Create and Download a Huge Zip (From Several Blobs) in a Webapp
How to Display Bar Value on Top of Bar Javafx
JPA SQL Server No Dialect Mapping for Jdbc Type: -9
How to Change Java Logging Console Output from Std Err to Std Out
Null Pointer Exception While Using Java Compiler API
Drag and Drop Custom Object from Jlist into Jlabel
Extended Server_Name (Sni Extension) Not Sent with Jdk1.8.0 But Send with Jdk1.7.0
How to Search in a List of Java Object
Collision Detection Between Two Images in Java
Printing a Large Swing Component
String S = New String("Xyz"). How Many Objects Has Been Made After This Line of Code Execute