web-dev-qa-db-fra.com

Déplacement d'une scène non décorée dans javafx 2

J'ai essayé de déplacer une scène non décorée sur l'écran en utilisant les écouteurs de souris suivants:

  • onPressed 
  • onReleased 
  • onDragged

Ces événements proviennent d'un rectangle. Mon idée est de déplacer la fenêtre non décorée en cliquant sur le rectangle et en faisant glisser toute la fenêtre.

] ) - event.getScreenY (); 
} 
 
 @ FXML 
 protected void onRectangleReleased (événement MouseEvent) {
 primaryStage.setX (événement. getScreenX ()); 
 primaryStage.setY (event.getScreenY ()); 
} [.________.]. ) {
 primaryStage.setX (event.getScreenX () + X); 
 primaryStage.setY (event.getScreenY () + Y); 
} 

Tout ce que j'ai avec ces événements, c'est quand j'appuie sur le rectangle et commence à faire glisser la fenêtre, ça bouge un peu. Mais lorsque je relâche le bouton, la fenêtre est déplacée à l'emplacement du rectangle.

Merci d'avance.

22
Antonio J.

J'ai créé un échantillon d'une horloge animée dans une fenêtre non décorée que vous pouvez faire glisser.

Le code pertinent de l'exemple est:

// allow the clock background to be used to drag the clock around.
final Delta dragDelta = new Delta();
layout.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();
  }
});
layout.setOnMouseDragged(new EventHandler<MouseEvent>() {
  @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; } 

Le code est assez similaire au vôtre, donc ne savez pas vraiment pourquoi votre code ne fonctionne pas pour vous.

25
jewelsea

J'utilise cette solution pour faire glisser des étapes non réclamées en faisant glisser un nœud contenu.

private void addDraggableNode(final Node node) {

    node.setOnMousePressed(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent me) {
            if (me.getButton() != MouseButton.MIDDLE) {
                initialX = me.getSceneX();
                initialY = me.getSceneY();
            }
        }
    });

    node.setOnMouseDragged(new EventHandler<MouseEvent>() {
        @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);
            }
        }
    });
}
14
Zsolt

Je suppose que votre:

onRectangleReleased()

passe les mêmes coordonnées de votre

onRectanglePressed()

Cela se produit car, comme indiqué dans la documentation, la méthode getX () de la classe MouseEvent renvoie

Position horizontale de l'événement par rapport à l'origine de la source de MouseEvent.

puis, lorsque vous relâchez la souris, le rectangle se trouve à la place où il se trouvait lorsque vous avez appuyé pour la première fois.

Au fait, j'utilise un StackPane avec un rectangle à l'intérieur, puis j'applique le code suivant:

private void addDragListeners(final Node n){
       n.setOnMousePressed(new EventHandler<MouseEvent>() {
            @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<MouseEvent>() {
            @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);

En plus de cela, j'utilise le bouton central de la souris pour centrer ma fenêtre sur l'écran. J'espérais que ça aiderait. À votre santé!

3
Bruno Vieira
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);
    }

}
1
Sameer

Basé sur la réponse de jewelsea, j'ai créé deux expressions lamba pour définir les MouseListeners directement sur la scène dans ma méthode start (). Fonctionne 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
1
M. Kahlen