JavaFX 制作无装饰可移动的窗口并使窗口位于屏幕中央

JavaFX 制作无装饰可移动的窗口并使窗口位于屏幕中央

  • 去掉窗口修饰,有两种方式
primaryStage.initStyle(StageStyle.TRANSPARENT);//去掉窗口修饰同时让弹出窗口透明
primaryStage.initStyle(StageStyle.UNDECORATED);
  • 窗口移动处理主要是注意偏移量就可以了 
root.setOnMousePressed(new EventHandler<MouseEvent>() {
    /*
     * 鼠标按下时,记下相对于 root左上角(0,0) 的 x, y坐标, 也就是x偏移量 = x - 0, y偏移量 = y - 0
     */
    @Override
    public void handle(MouseEvent event) {
        xOffset = event.getSceneX();
        yOffset = event.getSceneY();
    }
});
root.setOnMouseDragged(new EventHandler<MouseEvent>() {
    /*
     * 根据偏移量设置primaryStage新的位置
     */
    @Override
    public void handle(MouseEvent event) {
        primaryStage.setX(event.getScreenX() - xOffset);
        primaryStage.setY(event.getScreenY() - yOffset);
    }
});
  • 窗口居中,本来Stage也有一个centerOnScreen()来使居中窗口,但实际它的效果是居中偏上的,可以看下这个方法的相关源码(在javafx.stage.Window里面),找到原因
private static final float CENTER_ON_SCREEN_X_FRACTION = 1.0f / 2;
private static final float CENTER_ON_SCREEN_Y_FRACTION = 1.0f / 3;//注意这里,它并不是除以2

public void centerOnScreen() {
    xExplicit = false;
    yExplicit = false;
    if (impl_peer != null) {
        Rectangle2D bounds = getWindowScreen().getVisualBounds();
        double centerX = bounds.getMinX() + (bounds.getWidth() - getWidth()) * CENTER_ON_SCREEN_X_FRACTION;
        double centerY = bounds.getMinY() + (bounds.getHeight() - getHeight()) * CENTER_ON_SCREEN_Y_FRACTION;

        x.set(centerX);
        y.set(centerY);
        peerBoundsConfigurator.setLocation(centerX, centerY, CENTER_ON_SCREEN_X_FRACTION,
                CENTER_ON_SCREEN_Y_FRACTION);
        applyBounds();
    }
}
  •  所以还是要手动设置Stage的位置,注意在show()方法后面。
Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
primaryStage.setX((screenBounds.getWidth() - width) / 2); 
primaryStage.setY((screenBounds.getHeight() - height) / 2);
  •  完整代码

    Demo.java

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class Demo extends Application {

    // 定义偏移量,用于处理窗口移动
    private double xOffset = 0;
    private double yOffset = 0;

    @Override
    public void start(Stage primaryStage) {
        try {
            // 去掉窗口修饰,有两种方式
            // primaryStage.initStyle(StageStyle.TRANSPARENT);//同时让弹出窗口透明
            primaryStage.initStyle(StageStyle.UNDECORATED);

            BorderPane root = new BorderPane();

            root.setOnMousePressed(new EventHandler<MouseEvent>() {
                /*
                 * 鼠标按下时,记下相对于 root左上角(0,0) 的 x, y坐标, 也就是x偏移量 = x - 0, y偏移量 = y - 0
                 */
                @Override
                public void handle(MouseEvent event) {
                    xOffset = event.getSceneX();
                    yOffset = event.getSceneY();
                }
            });
            root.setOnMouseDragged(new EventHandler<MouseEvent>() {
                /*
                 * 根据偏移量设置primaryStage新的位置
                 */
                @Override
                public void handle(MouseEvent event) {
                    primaryStage.setX(event.getScreenX() - xOffset);
                    primaryStage.setY(event.getScreenY() - yOffset);
                }
            });

            Scene scene = new Scene(root, 400, 400);
            scene.getStylesheets().add(getClass().getResource("demo.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();

            Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds();
            primaryStage.setX((screenBounds.getWidth() - 400) / 2);
            primaryStage.setY((screenBounds.getHeight() - 400) / 2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

    demo.css 
    这个文件里面没内容。

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值