gwt client session time out - gwt

I am using gwt 2.3 with gwtp framework.In this application I wan to maintain a session time of 5 mins.This means if current user is not doing up to 5 min and he comes after five min then on his first event/action on screen a he should be be logged out.
In gwt there is class named Timer which can be used in this issues.But I am not getting how to recognize action of user on the screen.I did google on it, & found the code for gwt-ext.Below is the code of gwt-ext
Ext.get(“pagePanel”).addListener(“click”, new EventCallback() {
#Override
public void execute(EventObject e) {
MessageBox.alert(“On Mouse Click”);
}
});
Ext.get(“pagePanel”).addListener(“keydown”, new EventCallback() {
#Override
public void execute(EventObject e) {
MessageBox.alert(“On Key Press Click”);
}
});
In above code tag in working properly so I am attaching link from where I got this code.here
Same type of code I am looking in gwt.If there any other better way to do this then please let me know. Thanks in advance

If action/event can be really everythin, I would solve it with a
NativePreviewHandler in the following way:
boolean expired;
final Timer logoutTimer = new Timer() {
#Override
public void run() {
expired = true;
}
};
NativePreviewHandler nph = new NativePreviewHandler() {
#Override
public void onPreviewNativeEvent(NativePreviewEvent event) {
if (!expired) {
logoutTimer.cancel();
logoutTimer.schedule(300000);
} else {
// do your logout stuff here
}
}
};
Event.addNativePreviewHandler(nph);
If the user shell be logged out without a new action after 5 minutes:
final Timer logoutTimer = new Timer() {
#Override
public void run() {
// do your logout stuff here
}
};
NativePreviewHandler nph = new NativePreviewHandler() {
#Override
public void onPreviewNativeEvent(NativePreviewEvent event) {
// Of course do this only when logged in:
logoutTimer.cancel();
logoutTimer.schedule(300000);
}
};
Event.addNativePreviewHandler(nph);

Related

Second activity is still start on handler although press back button for quiting app

My application has an Introduce activity that show process bar before using app.
pb = (ProgressBar) findViewById(R.id.pb_loader);
final Handler h = new Handler() {
#Override
public void handleMessage(Message message) {
pb.setVisibility(View.INVISIBLE);
Intent it = new Intent(FirstIntroActivity.this, SecondIntroActivity.class);
it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(it);
}
};
h.sendMessageDelayed(new Message(), 3000);
But after I press BACK button to exit application, my phone is turn back to application and go to SECOND activity ( after 3000ms ). How to resolve this error?
Alternative is to use a Timer to schedule start of your second activity.we can cancel starting the second activity by cancelling timer in OnBackPressed() callback.
private Timer timer;
#Override
protected void onResume() {
super.onResume();
timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
// add code to start your second activity
}
}, 2000);
}
#Override
public void onBackPressed() {
timer.cancel();
super.onBackPressed();
}

GWT Fire ValueChangeEvent after a specific time

I have an webapp with a large collection. So my user get a text box to filter the collection.
But every time the user put in one letter the filter action starts. This is very slow some times.
So I want only get the value change event when the user stop typing for one second.
I tried it this way:
#Override
public void onValueChange( ValueChangeEvent<String> event )
{
Timer t = new Timer()
{
#Override
public void run()
{
addChangeHandler( new ChangeHandler()
{
#Override
public void onChange( ChangeEvent event1 )
{
ValueChangeEvent.fire( TextBoxPSG.this, getValue() );
}
} );
}
};
t.schedule( 15000 );
}
But this doesn't work.
Maybe someone has an Idea or the same problem.
Thanks in advance.
Do not use ValueChangeEvent. Use KeyUpEvent.
private static Timer timer = new Timer() {
#Override
public void run() {
// do you filter work;
}
};
...
myTextBox.addKeyUpHandler(new KeyUpHandler() {
#Override
public void onKeyUp(KeyUpEvent event) {
if (timer.isRunning()) {
timer.cancel();
}
timer.schedule(1000);
}
});

Timer is still firing after Clicking on other Links in GWT

So I have a timer and it keeps on firing even though I cleared the Panel and loaded other model... my question is, how to cancel a timer when I unload a model?
So here is part of my code
public Display(List<Clarification> result) {
if (result.size() == 0) {
Window.alert("EMPTY");
} else {
RootPanel.get("Dev1").clear();
t = new Timer() {
public void run() {
cd = new ClarificationDispatcher();
cd.getClarificationsCount(result.size());
}
};
t.scheduleRepeating(5000);
}
I tried to cancel the Timer onUnload() method however, I don't believe it is getting called at all...
Thanks!
Steps to follow
use window.onunload event that is called when page is refreshed
first export cancelTimer() method to java script using JSNI and register cancelTimerFunction as java script function that is called on page unload
cancel timer on window close
Code:
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
private static Timer timer = null;
public void onModuleLoad() {
exportCancelTimer();
final Label label = new Label("Hello ");
timer = new Timer() {
#Override
public void run() {
label.setText("Hello " + Math.random() * 100);
}
};
timer.scheduleRepeating(500);
RootPanel.get().add(label);
Window.addCloseHandler(new CloseHandler<Window>() {
#Override
public void onClose(CloseEvent<Window> event) {
timer.cancel();
}
});
}
public static void cancelTimer() {
if (timer != null) {
System.out.println("cancel");
timer.cancel();
}
}
public static native void exportCancelTimer() /*-{
$wnd.cancelTimerFunction = $entry(#com.x.y.z.GWTProject::cancelTimer());
$wnd.onunload = $wnd.cancelTimerFunction;
}-*/;

Decouple GWT Asynchronous callbacks

I have the following problem:
I am trying to model a process using GWT, where i have a couple of views with a couple of submit buttons. And pressing button1 will create a server interaction and if everything was ok, the next view will be loaded. My problem is now that I get really nasty spaghetti code (just very highlevel to show you what i mean):
onClick {
AsyncCallback {
onSuccess {
load new view with another clickhandler and an asynccallback
}
}
}
Is there some way to create some kind of abstraction or something? Maybe a state pattern? How? Thanks a lot!
This is actually a very good question - and probably one without a definitive answer. It's a problem that applies to many frameworks, not just GWT, so I like your idea to look at this with some simplified code. I'll make this a little bit longer, to show what even just 4 very simple callbacks look like:
Nested callbacks
alice.call("a", new Callback() {
#Override
public void onSuccess() {
bob.call("b", new Callback() {
#Override
public void onSuccess() {
charlie.call("c", new Callback() {
#Override
public void onSuccess() {
daisy.call("d", new Callback() {
#Override
public void onSuccess() {
// finished
}
});
}
});
}
});
}
});
Named callbacks
You can use your IDE to refactor this easily into named callbacks (hint: Please read the callbacks from bottom to top!):
final Callback daisyCallback = new Callback() {
#Override
public void onSuccess() {
// finished
}
};
final Callback charlieCallback = new Callback() {
#Override
public void onSuccess() {
daisy.call("d", daisyCallback);
}
};
final Callback bobCallback = new Callback() {
#Override
public void onSuccess() {
charlie.call("c", charlieCallback);
}
};
final Callback aliceCallback = new Callback() {
#Override
public void onSuccess() {
bob.call("b", bobCallback);
}
};
alice.call("a", aliceCallback);
Problem: The control flow is not so immediately obvious anymore.
Still, an IDE can help by using "Search References" (Ctrl-G in Eclipse) or something similar.
Event Bus (or Observer/Publish-Subscribe pattern)
This is how the same calls look like with an event bus:
alice.call("a", new Callback() {
#Override
public void onSuccess() {
bus.fireEvent(BusEvent.ALICE_SUCCESSFUL_EVENT);
}
});
bus.addEventListener(BusEvent.ALICE_SUCCESSFUL_EVENT, new BusEventListener() {
#Override
public void onEvent(final BusEvent busEvent) {
bob.call("b", new Callback() {
#Override
public void onSuccess() {
bus.fireEvent(BusEvent.BOB_SUCCESSFUL_EVENT);
}
});
}
});
bus.addEventListener(BusEvent.BOB_SUCCESSFUL_EVENT, new BusEventListener() {
#Override
public void onEvent(final BusEvent busEvent) {
charlie.call("c", new Callback() {
#Override
public void onSuccess() {
bus.fireEvent(BusEvent.CHARLIE_SUCCESSFUL_EVENT);
}
});
}
});
bus.addEventListener(BusEvent.CHARLIE_SUCCESSFUL_EVENT, new BusEventListener() {
#Override
public void onEvent(final BusEvent busEvent) {
daisy.call("d", new Callback() {
#Override
public void onSuccess() {
bus.fireEvent(BusEvent.DAISY_SUCCESSFUL_EVENT);
}
});
}
});
bus.addEventListener(BusEvent.DAISY_SUCCESSFUL_EVENT, new BusEventListener() {
#Override
public void onEvent(final BusEvent busEvent) {
// finished
}
});
Under the right circumstances (when it's very clear what each event means, and
if you don't have too many), this pattern can make things very nice and clear.
But in other cases, it can make the control flow more confusing (and you easily get twice the lines of code).
It's harder to use your IDE to find out about the control flow.
The GWT History mechanism is a very positive example for where to use this technique reasonably.
Divide and Conquer
In my experience, it's often a good idea to "divide and conquer" by mixing nesting and named callbacks:
final Callback charlieCallback = new Callback() {
#Override
public void onSuccess() {
daisy.call("d", new Callback() {
#Override
public void onSuccess() {
// finished
}
});
}
};
alice.call("a", new Callback() {
#Override
public void onSuccess() {
bob.call("b", new Callback() {
#Override
public void onSuccess() {
charlie.call("c", charlieCallback);
}
});
}
});
Depending on the situation, two nested callbacks are often still readable, and they reduce jumping around between methods when reading the code by 50%.
(I created a pastebin of my examples here, if you like to play around with them: http://pastebin.com/yNc9Cqtb)
Spaghetti code is a tricky problem in GWT as it is in Javascript, where much of your code is structured around asynchronous callbacks.
Some of the techniques to deal with it that are described in the answers to this question could apply.
The suggested approach to avoid coupling between widgets is to use EventBus. Read more details here https://developers.google.com/web-toolkit/articles/mvp-architecture#events
Hope it helps.
changeview(boolean first){
if(first)
{
firstView.setVisible(true);
secondView.setVisible(false);
}else{
firstView.setVisible(false);
secondView.setVisible(true);
}
}
onClick {
AsyncCallback {
onSuccess {
changeView(false);
}
}
}
Switch between views by above.
Use MVP from very beginning. Use Activities and Places. Your code will be clean.

How to prevent DoubleSubmit in a GWT application?

To clarify what double submit is: When the user clicks on a submit button twice, the server will process the same POST data twice. To avoid this (apart from disabling the button after a single submit), most web frameworks like Struts provide a token mechanism. I am searching for the equivalent of this in GWT.
If you want to avoid submitting twice, how about:
boolean processing = false;
button.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
if (!processing) {
processing = true;
button.setEnabled(false);
// makes an RPC call, does something you only want to do once.
processRequest(new AsyncCallback<String>() {
#Override
public void onSuccess(String result) {
// do stuff
processing = false;
button.setEnabled(true);
});
});
}
}
});
That's the gist of it.
This will be helpfull for you -
final Button btn = new Button("Open");
btn.addSelectionListener(new SelectionListener<ButtonEvent>() {
#Override
public void componentSelected(ButtonEvent ce) {
btn.setEnabled(false);
openMethod(name, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
btn.setEnabled(true);
}
public void onSuccess(Void result) {
MessageBox.alert(info, "Opened Window", null);
btn.setEnabled(true);
window.hide();
}
});
}
});