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 ;)
Related
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.
I'd like to make a draggable popup control, which is independent of its parent Window, and does not have the system's title bar.
I tried is to rewrite the JavaFx example for draggable panels in order to move an undecorated stage based on mouse events on a node, see code below. Unfortunately this doesn't seem to work properly, it's not smooth and jumps around the screen erratically for multiple screens. I read that some others used similar methods, however is this the only way to do this currently or did anyone find a nice solution ?
Thanks,
private Node makeDraggable(final Node node) {
final DragContext dragContext = new DragContext();
final Node wrapGroup = node;
wrapGroup.addEventFilter(
MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>() {
public void handle(final MouseEvent mouseEvent) {
dragContext.mouseAnchorX = mouseEvent.getX();
dragContext.mouseAnchorY = mouseEvent.getY();
dragContext.initialTranslateX =
stage.getX();
dragContext.initialTranslateY =
stage.getY();
}
});
wrapGroup.addEventFilter(
MouseEvent.MOUSE_DRAGGED,
new EventHandler<MouseEvent>() {
public void handle(final MouseEvent mouseEvent) {
stage.setX(
dragContext.initialTranslateX
+ mouseEvent.getX()
- dragContext.mouseAnchorX);
stage.setY(
dragContext.initialTranslateY
+ mouseEvent.getY()
- dragContext.mouseAnchorY);
dragContext.initialTranslateX =
stage.getX();
dragContext.initialTranslateY =
stage.getY();
}
});
return node;
}
I used this sample method below when making a clock.
I've only tested it on one screen, because I don't have multiple screens available.
/** holder structure for drag delta amounts */
private static class Delta { double x, y; }
/** makes a stage draggable using a given node */
public static void makeDraggable(final Stage stage, final Node byNode) {
final Delta dragDelta = new Delta();
byNode.setOnMousePressed(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
// record a delta distance for the drag and drop operation.
dragDelta.x = stage.getX() - mouseEvent.getScreenX();
dragDelta.y = stage.getY() - mouseEvent.getScreenY();
byNode.setCursor(Cursor.MOVE);
}
});
byNode.setOnMouseReleased(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
byNode.setCursor(Cursor.HAND);
}
});
byNode.setOnMouseDragged(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
stage.setX(mouseEvent.getScreenX() + dragDelta.x);
stage.setY(mouseEvent.getScreenY() + dragDelta.y);
}
});
byNode.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
byNode.setCursor(Cursor.HAND);
}
}
});
byNode.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
if (!mouseEvent.isPrimaryButtonDown()) {
byNode.setCursor(Cursor.DEFAULT);
}
}
});
}
I'm stuck on integrating gwt with JCrop or imgareaselect javascript libraries
I have an image, which url is changing each time the client change the file choosen from its filesystem (using an upload widget).
I want the user select the area in its image, this way i will be able to have images with aspect ratio respected respect to the client wishes.
Problem is i can't succed in making imgareaselect or jcrop called on load event, each time i have null, if i try jquery ("imagepreview") jquery is unknow at execution time, if i try some $("#imagepreview") i get a $ is undefined...
PLEASE any help...
Regards.
public class ThisWidget extends LayoutContainer {
public void onRender(Element parent, int index) {
super.onRender(parent, index);
setLayout(new VBoxLayout());
setWidth("100%");
final FormPanel uploadPhotoPanel = new FormPanel();
uploadPhotoPanel.setWidth("100%");
uploadPhotoPanel.setHeight("150px");
Label label = new Label("Ajouter une photo");
add(label);
uploadPhotoPanel.setAction(GWT.getModuleBaseURL()
+ "photoload/uploadpreview.ctz");
uploadPhotoPanel.setEncoding(FormPanel.ENCODING_MULTIPART);
uploadPhotoPanel.setMethod(FormPanel.METHOD_POST);
final FileUploadField file = new FileUploadField();
file.setName("FILE");
uploadPhotoPanel.add(file);
file.addHandler(new ChangeHandler() {
#Override
public void onChange(ChangeEvent event) {
uploadPhotoPanel.submit();
}
}, ChangeEvent.getType());
final Button btn = new Button("Ajouter",
new SelectionListener<ButtonEvent>() {
#Override
public void componentSelected(ButtonEvent ce) {
uploadPhotoPanel.submit();
}
});
final Image previewimage;
previewimage = new Image();
DOM.setElementAttribute(previewimage.getElement(), "id",
"previewimage");
previewimage.setSize("200px", "200px");
previewimage.addLoadHandler(new LoadHandler(){
protected native void onPreviewLoad() /*-{
document.getElementById("previewimage").imgAreaSelect({
aspectRatio : '1:1',
handles : true,
fadeSpeed : 200
});
}-*/;
#Override
public void onLoad(LoadEvent event) {
onPreviewLoad();
}});
uploadPhotoPanel
.addSubmitCompleteHandler(new SubmitCompleteHandler() {
#Override
public void onSubmitComplete(SubmitCompleteEvent event) {
previewimage.setUrl(GWT.getModuleBaseURL()
+ "photoload/downloadpreview.ctz?tsp="
+ System.currentTimeMillis());
}
});
add(uploadPhotoPanel);
add(previewimage);
add(btn);
}
Use $wnd.$("#imagepreview") or $wnd.jquery("#imagepreview").
(Updated to fix the forgotten #)
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);
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();
}
});
}
});