No events when drag target is removed from the scenegraph while dragging
Sebastian Rheinnecker
sebastian.rheinnecker at yworks.com
Fri Aug 16 07:53:12 PDT 2013
Hello,
we're not sure if we are doing something wrong but in our testing we
noticed a behavior of javafx event processing that is unfortunate.
I attached a SSCCE that shows the issue. In the application, an ellipse
shape is following the mouse, and when you click and drag, a listener
that is called upon MouseEvent.DRAG_DETECTED removes the drag target
from the scene graph (in this case, the ellipse) and immediately places
a newly created ellipse in the same place.
The issue is: as soon as the ellipse (the drag target) is removed from
the scene graph, no events are fired anymore for the entire drag
operation *at all*. The sample application binds listeners to the scene,
the stage and to the window but no mouse events are received until the
user releases the mouse button. This happens in JavaFX 2.x as well as
JavaFX 8.
We'd like to know if this is the intented behavior or a bug and if there
is a way to receive the missing mouse events somehow.
Thanks in advance and kind regards,
Sebastian Rheinnecker
--
Sebastian Rheinnecker
phone: +49 7071 9709050
fax: +49 7071 9709051
yWorks GmbH
Vor dem Kreuzberg 28
72070 Tuebingen
Germany
http://www.yworks.com
Managing Directors: Sebastian Müller, Michael Pfahler
Commercial Registry: Stuttgart, Germany, HRB 382340
-------------- next part --------------
package test;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.DragEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Ellipse;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
/**
* In this test app, an ellipse is moved like a cursor at the mouse position. The ellipses position is updated by
* a MouseEvent handler listening for the MouseEvent.MOUSE_MOVED and MouseEvent.MOUSE_DRAGGED.
* A problem occurs when the child node on which the drag started (another ellipse in this example) is removed from
* the stage during the drag gesture. In this case, no further MOUSE_DRAGGED events are reported.
*/
public class MouseEventTest extends Application {
private Stage primaryStage;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) {
this.primaryStage = primaryStage;
Scene scene = new Scene(createPane(), 600, 600);
primaryStage.setTitle("MouseEvent Test App");
primaryStage.setScene(scene);
primaryStage.show();
}
private Parent createPane() {
final Group contentGroup = new Group();
// the cursor that is updated on mouse move and mouse drag
final Ellipse cursor = new Ellipse(0, 0, 10, 10);
cursor.setFill(Color.ORANGE);
cursor.setMouseTransparent(true);
contentGroup.addEventFilter(MouseEvent.ANY, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
if (MouseEvent.MOUSE_MOVED.equals(mouseEvent.getEventType())
|| MouseEvent.MOUSE_DRAGGED.equals(mouseEvent.getEventType())) {
cursor.setLayoutX(mouseEvent.getX());
cursor.setLayoutY(mouseEvent.getY());
}
}
});
// a background
contentGroup.getChildren().add(new Rectangle(600, 600, Color.BLUE));
// a child that gets removed later
contentGroup.getChildren().add(createChild());
// the cursor
contentGroup.getChildren().add(cursor);
return contentGroup;
}
// creates an ellipse that removes itself from its parent on MouseEvent.DRAG_DETECTED and replaces itself by another
// ellipse
private Node createChild() {
final Ellipse ellipse = new Ellipse(300, 300, 200, 200);
ellipse.addEventHandler(MouseEvent.DRAG_DETECTED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
Group parent = (Group) ellipse.getParent();
parent.getChildren().remove(ellipse);
parent.getChildren().add(1, createChild());
// none of this approaches work; no one receives mouse / drag events anymore!
// window
primaryStage.getScene().getWindow().addEventFilter(MouseEvent.ANY, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
System.out.println(mouseEvent);
}
});
primaryStage.getScene().getWindow().addEventFilter(DragEvent.ANY, new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent dragEvent) {
System.out.println(dragEvent);
}
});
// stage
primaryStage.getScene().addEventFilter(MouseEvent.ANY, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
System.out.println(mouseEvent);
}
});
primaryStage.getScene().addEventFilter(DragEvent.ANY, new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent dragEvent) {
System.out.println(dragEvent);
}
});
// scene
primaryStage.addEventFilter(MouseEvent.ANY, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
System.out.println(mouseEvent);
}
});
primaryStage.addEventFilter(DragEvent.ANY, new EventHandler<DragEvent>() {
@Override
public void handle(DragEvent dragEvent) {
System.out.println(dragEvent);
}
});
}
});
return ellipse;
}
}
More information about the openjfx-dev
mailing list