有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在Windows上移动父阶段时移动子阶段

我想知道,当我们在Windows上移动父阶段时,是否有办法将JavaFX子阶段与其父阶段一起移动。事实上,在MacOS上,这似乎是默认行为。正如你在这段视频中看到的:https://imgur.com/a/r3qIklu,我可以独立移动缩略图场景,当我移动主窗口时,缩略图(顺便说一句,它是主窗口的子场景)仍然“附加”到父窗口并跟随它

然而,在Windows上,正如您在这里看到的:https://imgur.com/a/SPEkYJ2,结果是不一样的。移动父阶段时,缩略图将保持在其当前位置。如何在Windows上重现MacOS的行为

以下是我的阶段的初始化方式,仅供参考:

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();
}

共 (1) 个答案

  1. # 1 楼答案

    将root和thumbnailRoot放在一个常规的Pane中(这相当于Swing中的空布局)

    要允许用户移动thumbnailRoot,请向其添加鼠标事件处理程序以进行按下和拖动,并保留跟踪thumbnailRoot位置和鼠标拖动的专用字段

    简单示例实现:

    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);
            }
        }
    }
    

    您可以在一个应用程序中完成相同的功能。fxml文件:只需将背景和缩略图放在窗格中即可。如果愿意,也可以在那里添加鼠标事件处理程序

    这是我用作舞台背景的图片。巴布亚新几内亚:

    enter image description here

    这是我用作缩略图背景的图像。巴布亚新几内亚:

    enter image description here