Mover una etapa sin decoración en javafx 2

He intentado mover un escenario sin decorar alrededor de la pantalla, usando los siguientes oyentes de mouse:

  • onPressed
  • onReleased
  • onDragged

Estos eventos son de un rectángulo. Mi idea es mover la ventana sin decoración haciendo clic en el rectángulo y arrastrando toda la ventana.

 @ FXML
 protected void onRectanglePressed (Evento MouseEvent) {
     X = primaryStage.getX () - event.getScreenX ();
     Y = primaryStage.getY () - event.getScreenY ();
 }

 @ FXML
 protected void onRectangleReleased (evento MouseEvent) {
     primaryStage.setX (event.getScreenX ());
     primaryStage.setY (event.getScreenY ());
 }

 @ FXML
 protected void onRectangleDragged (evento MouseEvent) {
     primaryStage.setX (event.getScreenX () + X);
     primaryStage.setY (event.getScreenY () + Y);
 }

Todo lo que tengo con estos eventos es cuando presiono el rectángulo y comienzo a arrastrar la ventana, se mueve un poco. Pero cuando suelto el botón, la ventana se mueve al lugar donde está el rectángulo.

Gracias por adelantado.

Creé una muestra de un reloj animado en una ventana sin decoración que puedes arrastrar.

El código relevante de la muestra es:

// allow the clock background to be used to drag the clock around. final Delta dragDelta = new Delta(); layout.setOnMousePressed(new EventHandler() { @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(); } }); layout.setOnMouseDragged(new EventHandler() { @Override public void handle(MouseEvent mouseEvent) { stage.setX(mouseEvent.getScreenX() + dragDelta.x); stage.setY(mouseEvent.getScreenY() + dragDelta.y); } }); ... // records relative x and y co-ordinates. class Delta { double x, y; } 

El código es bastante similar al tuyo, por lo que no estoy seguro de por qué tu código no está funcionando para ti.

Estoy usando esta solución para arrastrar estadios no asociados arrastrando cualquier nodo contenido.

 private void addDraggableNode(final Node node) { node.setOnMousePressed(new EventHandler() { @Override public void handle(MouseEvent me) { if (me.getButton() != MouseButton.MIDDLE) { initialX = me.getSceneX(); initialY = me.getSceneY(); } } }); node.setOnMouseDragged(new EventHandler() { @Override public void handle(MouseEvent me) { if (me.getButton() != MouseButton.MIDDLE) { node.getScene().getWindow().setX(me.getScreenX() - initialX); node.getScene().getWindow().setY(me.getScreenY() - initialY); } } }); } 

Yo creo que tu:

 onRectangleReleased() 

está pasando las mismas coordenadas de su

 onRectanglePressed() 

Esto sucede porque como se indica en la documentación, el método getX () de la clase MouseEvent regresa

Posición horizontal del evento en relación con el origen del origen de MouseEvent.

luego, cuando sueltas el mouse, pone tu rectángulo en el lugar donde estaba cuando presionaste el primer mouse.

Por cierto, uso un StackPane con un rectángulo adentro y luego aplico el siguiente código:

 private void addDragListeners(final Node n){ n.setOnMousePressed(new EventHandler() { @Override public void handle(MouseEvent me) { if(me.getButton()!=MouseButton.MIDDLE) { initialX = me.getSceneX(); initialY = me.getSceneY(); } else { n.getScene().getWindow().centerOnScreen(); initialX = n.getScene().getWindow().getX(); initialY = n.getScene().getWindow().getY(); } } }); n.setOnMouseDragged(new EventHandler() { @Override public void handle(MouseEvent me) { if(me.getButton()!=MouseButton.MIDDLE) { n.getScene().getWindow().setX( me.getScreenX() - initialX ); n.getScene().getWindow().setY( me.getScreenY() - initialY); } } }); } addDragListeners(mainStackPane); 

Además de eso, uso el botón central del mouse para centrar mi ventana en la pantalla. Esperaba que ayudara. ¡Aclamaciones!

 double x, y; private void addDragListeners(final Node n, Stage primaryStage){ n.setOnMousePressed((MouseEvent mouseEvent) -> { this.x = n.getScene().getWindow().getX() - mouseEvent.getScreenX(); this.y = n.getScene().getWindow().getY() - mouseEvent.getScreenY(); }); n.setOnMouseDragged((MouseEvent mouseEvent) -> { primaryStage.setX(mouseEvent.getScreenX() + this.x); primaryStage.setY(mouseEvent.getScreenY() + this.y); }); } public void start(Stage primaryStage) { try { ... addDragListeners(mainPane, primaryStage); } catch (Exception e) { e.printStackTrace(System.out); } } 

Basado en la respuesta de jewelsea hice dos expresiones de lamba para configurar los MouseListeners directamente en la escena en mi método de inicio (). Funciona bien 🙂

 private double xOffset; private double yOffset; /* The two following lambda expressions makes it possible to move the application without the standard StageStyle */ //Lambda mouse event handler scene.setOnMousePressed(event -> { xOffset = primaryStage.getX() - event.getScreenX(); yOffset = primaryStage.getY() - event.getScreenY(); }); //Lambda mouse event handler scene.setOnMouseDragged(event -> { primaryStage.setX(event.getScreenX() + xOffset); primaryStage.setY(event.getScreenY() + yOffset); });enter code here 
Intereting Posts