Javafx 2 如何拖动JavaFX的未装饰窗口(阶段)

Javafx 2 如何拖动JavaFX的未装饰窗口(阶段),javafx-2,javafx,javafx-8,Javafx 2,Javafx,Javafx 8,我有一扇没有装饰的窗户: public static void initStartPage(final Stage primaryStage) { final Stage startPage = new Stage(); startPage.initStyle(StageStyle.UNDECORATED); //startPage.initOwner(primaryStage); //startPage.toFront();

我有一扇没有装饰的窗户:

public static void initStartPage(final Stage primaryStage) {

        final Stage startPage = new Stage();
        startPage.initStyle(StageStyle.UNDECORATED);
        //startPage.initOwner(primaryStage);
        //startPage.toFront();
        Scene scene = new Scene(agentsPanel(), 900, 500);
        startPage.setScene(scene);
        startPage.show();

    }
我想知道我如何才能使它成为一个可拖动的未装饰窗户? 我想在用户用鼠标右键选择窗口时更改其位置,然后在按住鼠标按钮的同时移动鼠标

p.S.我测试了这个解决方案,但它不起作用:

private static FlowPane flow;
    private static BorderPane bpi;

    public static void initStartPage(final Stage primaryStage) {

        final Stage startPage = new Stage();
        startPage.initStyle(StageStyle.UNDECORATED);
        startPage.initOwner(primaryStage);
        //startPage.toFront();
        Scene scene = new Scene(agentsPanel(primaryStage), 900, 500);
        startPage.setScene(scene);
        startPage.show();

    }

    private static double xOffset = 0;
    private static double yOffset = 0;

    public static BorderPane agentsPanel(final Stage primaryStage) {

        BorderPane bp = new BorderPane();
        bp.setPrefSize(900, 500);
        bp.setMaxSize(900, 500);

        HBox thb = new HBox(10); // Set spacing between each child into the HBox
        thb.setPadding(new Insets(15, 15, 15, 15));


        HBox bhb = new HBox(10); // Set spacing between each child into the HBox
        bhb.setPadding(new Insets(15, 15, 15, 15));

        bp.setTop(thb);
        bp.setBottom(bhb);
        bp.setCenter(navigationPanel());


        bp.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                xOffset = event.getSceneX();
                yOffset = event.getSceneY();
            }
        });
        bp.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                primaryStage.setX(event.getScreenX() - xOffset);
                primaryStage.setY(event.getScreenY() - yOffset);
            }
        });

        return bp;

    }
私有静态流窗格流;
私有静态边界窗格bpi;
公共静态无效初始起始页(最终阶段初级阶段){
最终阶段开始页=新阶段();
起始页。初始样式(舞台样式。未装饰);
起始页初始所有者(初级阶段);
//起始页toFront();
场景=新场景(代理面板(primaryStage),900500);
起始页。设置场景(场景);
startPage.show();
}
专用静态双xOffset=0;
专用静态双yOffset=0;
公共静态边框窗格代理面板(最终阶段primaryStage){
BorderPane bp=新的BorderPane();
bp.setPrefSize(900500);
bp.setMaxSize(900500);
HBox thb=新HBox(10);//设置HBox中每个子项之间的间距
thb.设置填充(新插图(15,15,15,15));
HBox bhb=新HBox(10);//设置HBox中每个子项之间的间距
bhb.设置填充(新插图(15,15,15,15));
英国石油公司setTop(泰铢);
bp.setBottom(bhb);
setCenter(navigationPanel());
setOnMousePressed(新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
xOffset=event.getSceneX();
yOffset=event.getSceneY();
}
});
setOnMouseDrawed(新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
setX(event.getScreenX()-xOffset);
setY(event.getScreenY()-yOffset);
}
});
返回bp;
}

只需将setOnMousePressed方法更改为:

bp.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                xOffset = primaryStage.getX() - event.getScreenX();
                yOffset = primaryStage.getY() - event.getScreenY();
            }
        });
bp.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                primaryStage.setX(event.getScreenX() + xOffset);
                primaryStage.setY(event.getScreenY() + yOffset);
            }
        });
bp.setOnMousePressed(新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
xOffset=primaryStage.getX()-event.getScreenX();
yOffset=primaryStage.getY()-event.getScreenY();
}
});
您的SetonMouse被拖到以下位置:

bp.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                xOffset = primaryStage.getX() - event.getScreenX();
                yOffset = primaryStage.getY() - event.getScreenY();
            }
        });
bp.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                primaryStage.setX(event.getScreenX() + xOffset);
                primaryStage.setY(event.getScreenY() + yOffset);
            }
        });
bp.setonMouseDrawed(新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
setX(event.getScreenX()+xOffset);
setY(event.getScreenY()+yOffset);
}
});

您可以使用它,它既适用于一个阶段,也适用于警报(基本上是另一个阶段,但适用于pup po消息)。该节点是该阶段的主节点

//Make a Stage Draggable
public void DraggableStage(Node node, Stage stage, Alert alert ) {
    double[] xOffset = {0}, yOffset = {0};
    node.setOnMousePressed(event -> {
        if (stage != null && alert == null){
            xOffset[0] = stage.getX() - event.getScreenX();
            yOffset[0] = stage.getY() - event.getScreenY();
        } else if(stage == null && alert != null){
            xOffset[0] = alert.getX() - event.getScreenX();
            yOffset[0] = alert.getY() - event.getScreenY();
        }
    });

    node.setOnMouseDragged(event -> {
        if (stage != null && alert == null){
            stage.setX(event.getScreenX() + xOffset[0]);
            stage.setY(event.getScreenY() + yOffset[0]);
        } else if(stage == null && alert != null){
            alert.setX(event.getScreenX() + xOffset[0]);
            alert.setY(event.getScreenY() + yOffset[0]);
        }
    });
}

@eeliyaresponse运行良好。但是,如果使用下面的代码,代码会更短,因为我们不需要声明变量

每当
setonmousedraild
被激发时,我们需要一次又一次地
setonmousedraild
,但我认为这并没有造成问题

bp.setOnMousePressed(pressEvent -> {
    bp.setOnMouseDragged(dragEvent -> {
        primaryStage.setX(dragEvent.getScreenX() - pressEvent.getSceneX());
        primaryStage.setY(dragEvent.getScreenY() - pressEvent.getSceneY());
    });
});

希望它有助于

可能的重复,也可能重复我更新的帖子。我测试了这段代码,但它不起作用。至于内容:为了代码卫生:最好不要传递不必要的参数-相反,每个阶段/警报都有专门的方法为什么要浪费时间和重复代码?这是个人选择的问题,如果你愿意,你可以使用“分而治之”,但在这种情况下,我的内容与我在过去两个小时内输入的所有其他内容一样重要。请编辑它们以遵循命名约定。。使其他人更容易阅读和理解您正在将偏移量应用到主面板以拖动舞台(javafx中的窗口),因此。。。。对我来说,命名约定是可以的,不管怎样,可以是开发者想要的。。否:约定的存在是有原因的(使代码更易于阅读和理解,一目了然)。不,在java星球上,一个以大写字母开头的方法总是违反惯例的——如果你还没有看到这一点,你可能想了解一下它们(见我的第一条评论)的工作原理和外观!