简体   繁体   English

在 Windows 上移动父级时移动子级

[英]Move a child stage when moving parent stage on Windows

I wonder if there is a way to move a JavaFX child Stage with its parent, when we move the parent stage on Windows.我想知道当我们在 Windows 上移动父级时,是否有办法将 JavaFX 子级与其父级一起移动。 Indeed, on MacOS this seems to be the default behavior.事实上,在 MacOS 上,这似乎是默认行为。 As you can see in this video: https://imgur.com/a/r3qIklu , I can move the thumbnail scene independently and when I move the main window, the thumbnail (which is a child scene of the main window btw), remains "attached" to the parent and follows it.正如您在此视频中看到的: https://imgur.com/a/r3qIklu ,我可以独立移动缩略图场景,当我移动主 window 时,缩略图(这是主 Z05B8Ctw35Z05B8C702FBF4Z 的子场景),仍然“依附”到父级并跟随它。

However, on Windows, as you can see here: https://imgur.com/a/SPEkYJ2 , the result is not the same.但是,在 Windows 上,您可以在此处看到: https://imgur.com/a/SPEkYJ2 ,结果不一样。 When the parent stage is moved, the thumbnail stick to its current position.当父级移动时,缩略图会粘到其当前的 position。 How can I reproduce the MacOS behaviour on Windows?如何在 Windows 上重现 MacOS 行为?

For reference, this is how my stages are initialized:作为参考,这是我的阶段的初始化方式:

public void start(Stage primaryStage) {
    //App's main stage
    Parent root = FXMLLoader.load(getClass().getResource("../spaception.fxml"));
    Scene scene = new Scene(root, 1400, 700);
    primaryStage.setScene(scene);
    primaryStage.show();
    //...

    //Child stage (Thumbnail)
    Parent thumbnailRoot = FXMLLoader.load(getClass().getResource("../thumbnail.fxml"));
    Stage thumbnailStage = new Stage();
    thumbnailStage.initOwner(primaryStage);
    thumbnailStage.initStyle(StageStyle.UNDECORATED);
    thumbnailStage.setX(primaryStage.getX()+1100);
    thumbnailStage.setY(primaryStage.getY()+540);
    Scene scene = new Scene(thumbnailRoot, 250, 145);
    thumbnailStage.setScene(scene);
    thumbnailStage.show();
}

Place your root and your thumbnailRoot together in a regular Pane (which is the equivalent of a null layout in Swing).将根目录和 thumbnailRoot 放在一个常规窗格中(相当于 Swing 中的 null 布局)。

To allow the user to move the thumbnailRoot, add mouse event handlers to it for pressing and dragging, and keep private fields that track thumbnailRoot's position and to keep track of the mouse dragging.要允许用户移动 thumbnailRoot,请向其添加鼠标事件处理程序以进行按下和拖动,并保留跟踪 thumbnailRoot 的 position 的私有字段并跟踪鼠标拖动。

Simple example implementation:简单的示例实现:

import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.MenuBar;
import javafx.scene.layout.Pane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;

public class ParentAndThumbnail
extends Application {
    private Bounds thumbnailBoundsOnPress;

    private double pressedX;
    private double pressedY;

    @Override
    public void start(Stage stage) {
        Label positionLabel = new Label("Current position: x y");

        VBox left =
            new VBox(6, new Button("+"), new Button("-"), new Button("C"));
        left.setFillWidth(true);
        left.setPadding(new Insets(6));
        left.getChildren().forEach(
            c -> ((Button) c).setMaxWidth(Double.MAX_VALUE));

        VBox right =
            new VBox(6, new Button("+"), new Button("-"), new Button("C"));
        right.setFillWidth(true);
        right.setPadding(new Insets(6));
        right.getChildren().forEach(
            c -> ((Button) c).setMaxWidth(Double.MAX_VALUE));

        MenuBar menuBar = new MenuBar(
            new Menu("File", null,
                new MenuItem("New"),
                new MenuItem("Open"),
                new MenuItem("Save"),
                new MenuItem("Exit")),
            new Menu("Edit", null,
                new MenuItem("Cut"),
                new MenuItem("Copy"),
                new MenuItem("Paste")));

        ImageView imagePane =
            new ImageView(new Image("parent-stage-background.png"));

        BorderPane root = new BorderPane(
            imagePane, menuBar, left, positionLabel, right);

        BorderPane thumbnailRoot = new BorderPane(
            new ImageView(new Image("thumbnail-background.png")));
        thumbnailRoot.setStyle(
            "-fx-border-width: 4px 30px 4px 30px; " +
            "-fx-border-color: black");

        thumbnailRoot.setOnMousePressed(e -> {
            if (e.getButton() == MouseButton.PRIMARY) {
                thumbnailBoundsOnPress = thumbnailRoot.getBoundsInParent();
                pressedX = e.getScreenX();
                pressedY = e.getScreenY();
            }
        });
        thumbnailRoot.setOnMouseDragged(e -> {
            if (e.getButton() == MouseButton.PRIMARY) {
                thumbnailRoot.setLayoutX(
                    thumbnailBoundsOnPress.getMinX()
                    + e.getScreenX() - pressedX);
                thumbnailRoot.setLayoutY(
                    thumbnailBoundsOnPress.getMinY()
                    + e.getScreenY() - pressedY);
            }
        });

        Pane overlay = new Pane();
        overlay.getChildren().addAll(root, thumbnailRoot);

        stage.setOnShown(e -> {
            thumbnailRoot.setLayoutX(root.getWidth() - 400);
            thumbnailRoot.setLayoutY(root.getHeight() - 200);
        });

        stage.setScene(new Scene(overlay));
        stage.setTitle("Spaception");
        stage.show();
    }

    public static class Main {
        public static void main(String[] args) {
            Application.launch(ParentAndThumbnail.class, args);
        }
    }
}

You can accomplish the same functionality in an.fxml file: just place the background and the thumbnail in a Pane.您可以在 .fxml 文件中完成相同的功能:只需将背景和缩略图放在窗格中。 You can add mouse event handlers there too, if you wish.如果您愿意,您也可以在那里添加鼠标事件处理程序。

Here is the image I used as parent-stage-background.png:这是我用作 parent-stage-background.png 的图像:

在此处输入图像描述

And here is the image I used as thumbnail-background.png:这是我用作 thumbnail-background.png 的图像:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM