How to prevent DoubleSubmit in a GWT application? - gwt

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();
}
});
}
});

Related

JavaFX MediaPlayer "Error: 80de0001 in CallbackToJava..."

I am making a media player which allows users to drag and drop media thumbnails onto a media player (using JavaFX MediaPlayer).
When I run it and try the drag/drop functionality, some of the time it works just as expected. However sometimes it produces a weird error.
The error in its fullness is:
Error:80de0001 in CallbackToJava(javaIDs.View.notifyDragDrop, grfKeyState, pt, pdwEffect)
COM Error:80de0001 Unknown Error 0x80DE0001
Error:80de0001 in :: DoDragDrop( pcd, IDropSourcePtr(new GlassDropSource(obj), getDROPEFFECT(supportedActions, &performedDropEffect)
COM Error:80de0001 Unknown error 0x80DE0001
The print-out in Eclipse looks like: (all double-spaced)
I really have no idea why this is happening - I'm clearly doing something wrong. The error doesn't point me to any line of code. I would suggest that the error is referring to a memory address? Are you able to help me, please?
The listeners/handlers which perform the Drag/Drop functionality are:
root.setOnMouseEntered(new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent arg0) {
root.setStyle(highlightBackgroundStyle);
parentScene.setCursor(Cursor.OPEN_HAND);
}
});
root.setOnMouseExited(new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent arg0) {
root.setStyle(backgroundStyle);
//parentScene.setCursor(Cursor.DEFAULT);
}
});
root.setOnDragDetected(new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent arg0) {
parentScene.setCursor(Cursor.CLOSED_HAND);
Dragboard db = parentScene.startDragAndDrop(TransferMode.COPY);
ClipboardContent content = new ClipboardContent();
content.putString(mediaFile.toURI().toString());
db.setContent(content);
arg0.consume();
}
});
mediaPanel.getDropZoneA().setOnDragDropped(new EventHandler<DragEvent>(){
#Override
public void handle(DragEvent arg0) {
mediaPanel.getMixerA().dragGraphicsOff();
Dragboard db = arg0.getDragboard();
if (db.hasString())
{
//System.out.println(db.getString());
String mediaURI = db.getString();
System.out.println(mediaURI);
mediaPanel.getMixerA().getJfxMediaPlayer().loadAndPlayMediaA(new Media(mediaURI));
mediaPanel.getMixerA().prepareMedia();
arg0.setDropCompleted(true);
}else{System.out.println("Drag error");arg0.setDropCompleted(false);}
arg0.consume();
}
});
mediaPanel.getDropZoneA().setOnDragExited(new EventHandler<DragEvent>(){
#Override
public void handle(DragEvent arg0) {
mediaPanel.getMixerA().dragGraphicsOff();
arg0.consume();
}
});
mediaPanel.getDropZoneA().setOnDragOver(new EventHandler <DragEvent>() {
public void handle(DragEvent arg0) {
mediaPanel.getMixerA().dragGraphicsOn();
if (arg0.getGestureSource() != mediaPanel.getDropZoneB() && arg0.getDragboard().hasString())
{
arg0.acceptTransferModes(TransferMode.COPY);
}
arg0.consume();
}
});
Update 1
I am wondering whether this is caused by the way I 'change' the media for the MediaPlayer. I do the following:
public void loadAndPlayMediaA(Media playableMedia)
{
if((player != null))
{
player.stop();
}
media = playableMedia;
player = new MediaPlayer(media);
player.play();
}
I then immediately call:
public void prepareMedia()
{
view.setMediaPlayer(jfxMediaPlayer.getMediaPlayer());
view.setPreserveRatio(preserveRatio);
view.setFitWidth(miniaturePlayerX);
view.setFitHeight(miniaturePlayerY);
playerSlider.setValue(0.0);
}
...The key line being player = new MediaPlayer(media);. I wonder whether occasionally I am hitting the split second where the MediaView is trying to get the next frame, but failing because the media has been re instantiated. (?)
What's the best way to load up a new video?
I don't know if you haven't found a solution yet...
I had the same problem and solved it by following code:
setOnDragDropped(new EventHandler<DragEvent>()
{
#Override
public void handle(DragEvent event)
{
System.out.println("onDragDropped");
event.setDropCompleted(true);
}
});
setOnDragExited(new EventHandler<DragEvent>()
{
#Override
public void handle(DragEvent event)
{
System.out.println("onDragExited");
Dragboard db = event.getDragboard();
ArrayList<Object> f = (ArrayList<Object>) db.getContent(DataFormat.FILES);
for(Object o:f)
System.out.println(o.getClass().getName() + ":" + o);
File file = (File) f.get(0);
newMedia(file.toURI());
}
});
setOnDragOver(new EventHandler<DragEvent>()
{
#Override
public void handle(DragEvent event)
{
System.out.println("onDragOver");
event.acceptTransferModes(TransferMode.ANY);
}
});
public void newMedia(URI uri)
{
m = new Media(uri.toASCIIString());
mp = new MediaPlayer(m);
mV = new MediaView(mp);
mp.setOnReady(new Runnable()
{
#Override
public void run()
{
mp.play();
}
});
}
In the DragDropped handler I call setDropCompleted to call the DragExited handler. Then I get the File out of the Dragboard and create a new MediaPlayerInstance. And then, you aren't allowed to call play immideately, else nothing will happen. You need to call play in the OnReady Handler, or at least after the MediaPlayer's status has been changed to Ready.
The Error will still appear, but it should work now ;)

execute asynccallback first

I have this code:
searchButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
statusLabel.setText("Searching...");
final String query = searchField.getText();
RootPanel.get("flickr").clear();
AsyncCallback<Flickr> ac=new AsyncCallback<Flickr>(){
#Override
public void onFailure(Throwable caught) {
}
#Override
public void onSuccess(Flickr result) {
for(Photo p:result.getPhotos().getPhoto())
{
flck.add(p);
}
statusLabel.setText("");
}
};
mashupService.getFlickrPhotos(query, ac);
if(!flck.isEmpty())
{
for(int i=0;i<flck.size();i++)
{
RootPanel.get("flickr").add(new HTML("<img src='http://farm"+flck.get(i).getFarm()+".staticflickr.com/"+flck.get(i).getServer()+"/"+flck.get(i).getId()+"_"+flck.get(i).getSecret()+".jpg'/><br/>"));
}
}
}
});
I want execute first onSuccess (have flick.add)... but it executes after of if(!flck.isEmpty)... and I need have flck with data but I can't...
When I press secont time the same button, flck have data of first onClick...
Thanks in advance
Move the code inside the onSuccess() method that is depended on the result of AsyncCallback.
It's clear from the name that AsyncCallback is just like a AJAX request that talks to server asynchronously means the execution of code is not sequential.
Just move if(!flck.isEmpty)... inside onSuccess() method.

GWT: How to disable the anchor link event when clicked

I want to disable the anchor link event when it clicked one time. I used anchor.setenabled(false) but nothing happend. When I click the same button again the event e is true. I want false at that time.
public void onCellClick(GridPanel grid, int rowIndex, int colindex,EventObject e)
{
if(rowIndex==0 && colindex==2){
tomcatHandler = "Start";
anchorStart.setEnabled(false);
}else if(rowIndex==0 && colindex==3){
tomcatHandler = "Stop";
****anchorStop.setEnabled(false);
anchorStart.setEnabled(false);
anchorRestart.setEnabled(true);****
}else if(rowIndex==0 &&colindex==4){
tomcatHandler = "Restart";
anchorRestart.setEnabled(false);
}
AdminService.Util.getInstance().tomcat(tomcatHandler,new AsyncCallback<String>() {
#Override
public void onSuccess(String result) {
imageChangeEvent(result);
}
#Override
public void onFailure(Throwable caught) {
}
});}
Anchors in GWT have always had a problem with setEnabled() because HTML doesn't support such a property. A quick workaround is to create a new widget that subclasses GWT's Anchor, adding the following override:
#Override
public void onBrowserEvent(Event event) {
switch (DOM.eventGetType(event)) {
case Event.ONDBLCLICK:
case Event.ONFOCUS:
case Event.ONCLICK:
if (!isEnabled()) {
return;
}
break;
}
super.onBrowserEvent(event);
}
This disables the passing of the browser event to GWT's Anchor class (summarily disabling all related handlers) when the link is double clicked, focused or clicked and is in a disabled state.
Source
It doesn't seem to actually disable the anchor, but it does retain the status that has been set with anchor.setEnabled(), so just test that within your handler e.g.
myAnchor.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent evt) {
// write to filter and then call reload
if (((Anchor) evt.getSource()).isEnabled()) {
//do stuff
}
}
});

gwt client session time out

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);

GWT : print button

I am trying to create a button that prints the current browser window.
This is my current code, that uses (or at least it tries to use) JSNI:
private Button print = new Button(constants.print(), new ClickHandler() {
#Override
public void onClick(final ClickEvent event) {
/*-{
if ($wnd.print) {
$wnd.print();
return true;
} else {
return false;
}
}-*/
}
});
But when I click the button, nothing happens. It is my first GWT application, so I am not sure about how to implement it.
new Button(constants.print(), new ClickHandler() {
#Override
public void onClick(final ClickEvent event) {
print();
}
private native boolean print( ) /*-{
if ($wnd.print) {
$wnd.print();
return true;
} else {
return false;
}
}-*/; });
Should work! Always place JSNI within a native method.
Since GWT version 1.5, there's a built-in print function:
import com.google.gwt.user.client.Window
public class PrintHandler implements ClickHandler {
public void onClick (ClickEvent event) {
Window.print()
}
}
Here is my 2 cents:
Create a re-usable class:
public class PrintHandler implements ClickHandler {
public void onClick (ClickEvent event) {
print();
}
private native boolean print ()
/*-{
if ($wnd.print) {
$wnd.print();
return true;
} else {
return false;
}
}-*/;
}
And use it anywhere you like:
new Button( constants.print(), new PrintHandler() )