JavaFX之自定義標題欄(springboot)

自定義標題欄(或者窗口)先看javaFX 默認的效果
在這裏插入圖片描述
當我們想做全背景的窗口時,javaFX自帶的窗口欄,就很格格不入了

一:創建css文件

login.css

.dev-fx-body {
    -fx-background-image: url("../images/login.jpg");
    -fx-background-position: center;
    -fx-background-repeat: no-repeat;/*不平鋪*/
    -fx-background-size: cover;/*鋪滿*/

    -fx-pref-width: 1104;
    -fx-pref-height: 670;
}

二:修改FXML

login.xml
添加 styleClass=“dev-fx-body”

<AnchorPane prefHeight="400.0" prefWidth="600.0"
            xmlns="http://javafx.com/javafx/8"
            xmlns:fx="http://javafx.com/fxml/1"
            styleClass="dev-fx-body"
            fx:controller="com.xiyang.boot.controller.LoginController">
   <children>
      <Button fx:id="button" layoutX="259.0" layoutY="170.0" mnemonicParsing="false" text="Button" />
   </children>
</AnchorPane>

啓動項目可以看到窗口欄,讓人很不舒服。接下來我們進一步改造
在這裏插入圖片描述

三:修改Main類

根據springboot-javafx-support我們只需要重寫beforeInitialView方法即可,

    @Override
    public void beforeInitialView(Stage stage, ConfigurableApplicationContext ctx) {
        stage.initStyle(StageStyle.TRANSPARENT); /* 透明標題欄 */
        stage.setResizable(false); /* 設置窗口不可改變 */
        stage.setAlwaysOnTop(true); /* 窗口始終懸浮 */
    }

或者在application.properties中配置

javafx.title=自定義標題欄
javafx.stage.style=TRANSPARENT
javafx.stage.resizable=true

效果
在這裏插入圖片描述
標題欄被隱藏了,但是你會發現窗口無法拖到了,無法手動關閉了
所以還需進一步改進

四:創鍵窗口欄

創建一個公共的窗口欄模板window.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Tooltip?>
<?import javafx.scene.layout.*?>
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.xiyang.boot.controller.WindowController" fx:id="window" styleClass="dev-fx-window" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
    <children>
        <AnchorPane prefHeight="30">
            <children>
                <Button fx:id="minWindow" mnemonicParsing="false" styleClass="dev-fx-window-min" text="" AnchorPane.bottomAnchor="0.0" AnchorPane.rightAnchor="55.0" AnchorPane.topAnchor="0.0" >
                    <tooltip>
                        <Tooltip text="最小化" />
                    </tooltip>
                </Button>
                <Button fx:id="closeWindow" mnemonicParsing="false" styleClass="dev-fx-window-close" text="X" AnchorPane.bottomAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                    <tooltip>
                        <Tooltip text="關閉" />
                    </tooltip>
                </Button>
            </children>
        </AnchorPane>
    </children>
</VBox>

在login.fxml中引入

<AnchorPane prefHeight="400.0" prefWidth="600.0"
            xmlns="http://javafx.com/javafx/8"
            xmlns:fx="http://javafx.com/fxml/1"
            styleClass="dev-fx-body"
            fx:controller="com.xiyang.boot.controller.LoginController">
   <fx:include source="window.fxml"/>
</AnchorPane>

再創建window.css

.dev-fx-window {
    -fx-background-color: #00000000;
    -fx-pref-width: 100%;
    -fx-pref-height: 30;
}

.dev-fx-window-min {
    -fx-background-color: #00000000;
    -fx-font-size: 18;
    -fx-font-family: "Fira Code";
    -fx-pref-width: 55;
    -fx-border-radius: 0;
    -fx-border-width: 0;
}

.dev-fx-window-min:hover {
    -fx-background-color: #4cc5e8;
    -fx-text-fill: white; /* 字體顏色 */
}

.dev-fx-window-close {
    -fx-background-color: #00000000;
    -fx-font-size: 18;
   -fx-font-family: "Fira Code";
    -fx-pref-width: 55;
    -fx-border-radius: 0;
    -fx-border-width: 0;
}

.dev-fx-window-close:hover {
    -fx-background-color: #e81123;
    -fx-text-fill: white; /* 字體顏色 */
}

在loginView的註解上配置css文件地址

@FXMLView(value = "/fxml/login.fxml",css ={"/css/login.css","/css/window.css"})
public class LoginView extends AbstractFxmlView {
}

最後創建WindowController控制器

@FXMLController /* 標記這個類爲javaFX控制器類 */
public class WindowController implements Initializable {

    private Stage primaryStage;

    /* 自定義窗口 */
    public VBox window;
    public Button minWindow;
    public Button closeWindow;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        primaryStage = JavafxSpringboot3Application.getStage(); //primaryStage爲start方法頭中的Stage
        minWindow.setOnAction(event -> primaryStage.setIconified(true)); /* 最小化 */
        closeWindow.setOnAction((event)->System.exit(0)); /* 關閉程序 */
    }
}

啓動效果,當你鼠標懸停時才顯示
在這裏插入圖片描述
但是窗口還是不能拖動,
我們需要給窗口欄增加一個鼠標按下窗口後拖動事件

public class DragWindowHandler implements EventHandler<MouseEvent> {
    private Stage primaryStage; //primaryStage爲start方法頭中的Stage
    private double oldStageX;
    private double oldStageY;
    private double oldScreenX;
    private double oldScreenY;

    public DragWindowHandler(Stage primaryStage) { //構造器
        this.primaryStage = primaryStage;
    }

    @Override
    public void handle(MouseEvent e) {
        if (e.getEventType() == MouseEvent.MOUSE_PRESSED) {    //鼠標按下的事件
            this.oldStageX = this.primaryStage.getX();
            this.oldStageY = this.primaryStage.getY();
            this.oldScreenX = e.getScreenX();
            this.oldScreenY = e.getScreenY();

        } else if (e.getEventType() == MouseEvent.MOUSE_DRAGGED) {  //鼠標拖動的事件
            this.primaryStage.setX(e.getScreenX() - this.oldScreenX + this.oldStageX);
            this.primaryStage.setY(e.getScreenY() - this.oldScreenY + this.oldStageY);
        }
    }

}

改造WindowController控制器

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        primaryStage = JavafxSpringboot3Application.getStage(); //primaryStage爲start方法頭中的Stage
        DragWindowHandler handler = new DragWindowHandler(primaryStage);
        window.setOnMousePressed(handler);/* 鼠標按下 */![在這裏插入圖片描述](https://img-blog.csdnimg.cn/20191210115159766.gif)
        window.setOnMouseDragged(handler);/* 鼠標拖動 */
        minWindow.setOnAction(event -> primaryStage.setIconified(true)); /* 最小化 */
        closeWindow.setOnAction((event)->System.exit(0)); /* 關閉程序 */
    }

效果
在這裏插入圖片描述

五:demo地址

自定義窗口

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章