移动父级舞台时,在Windows上移动子级舞台

huangapple go评论39阅读模式
英文:

Move a child stage when moving parent stage on Windows

问题

我想知道是否有一种方法可以在Windows上移动JavaFX子舞台以及其父舞台,当我们移动父舞台时。实际上,在MacOS上,这似乎是默认行为。正如您在这个视频中所看到的:https://i.stack.imgur.com/XjOSg.jpg,我可以独立移动缩略图场景,当我移动主窗口时,这个缩略图(它是主窗口的子场景)仍然与父窗口“连接”并跟随它。

然而,在Windows上,正如您在这里所看到的:https://i.stack.imgur.com/Tm7Q9.jpg,结果不同。当移动父舞台时,缩略图粘在其当前位置。我该如何在Windows上复制MacOS的行为?

供参考,这是我的舞台初始化方式:

public void start(Stage primaryStage) {
    //应用程序的主舞台
    Parent root = FXMLLoader.load(getClass().getResource("../spaception.fxml"));
    Scene scene = new Scene(root, 1400, 700);
    primaryStage.setScene(scene);
    primaryStage.show();
    //...

    //子舞台(缩略图)
    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 thumbnailScene = new Scene(thumbnailRoot, 250, 145);
    thumbnailStage.setScene(thumbnailScene);
    thumbnailStage.show();
}
英文:

I wonder if there is a way to move a JavaFX child Stage with its parent, when we move the parent stage on Windows. Indeed, on MacOS this seems to be the default behavior. As you can see in this video: https://i.stack.imgur.com/XjOSg.jpg, 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.

However, on Windows, as you can see here: https://i.stack.imgur.com/Tm7Q9.jpg, the result is not the same. When the parent stage is moved, the thumbnail stick to its current position. How can I reproduce the MacOS behaviour on Windows?

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

答案1

得分: 0

将根和缩略图根一起放在一个常规的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) {
        // ...(省略部分代码)...

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

        // ...(省略部分代码)...

        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文件中实现相同的功能:只需将背景和缩略图放在一个Pane中,如果需要,也可以在那里添加鼠标事件处理程序。

这是我用作parent-stage-background.png的图片:

移动父级舞台时,在Windows上移动子级舞台

这是我用作thumbnail-background.png的图片:

移动父级舞台时,在Windows上移动子级舞台

英文:

Place your root and your thumbnailRoot together in a regular Pane (which is the equivalent of a null layout in Swing).

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.

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. You can add mouse event handlers there too, if you wish.

Here is the image I used as parent-stage-background.png:

移动父级舞台时,在Windows上移动子级舞台

And here is the image I used as thumbnail-background.png:

移动父级舞台时,在Windows上移动子级舞台

huangapple
  • 本文由 发表于 2020年7月23日 06:52:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63044296.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定