JavaFX 之窗口大小自由拉伸(四)


一、問題場景

  同樣的,隱藏掉窗體的默認標題欄也會導致窗體大小自由拉伸功能的失效。

二、解決思路

  判斷鼠標在窗體的位置,改變鼠標樣式,給窗體組件添加拖拽事件監聽器,根據鼠標移動位置改變窗體大小。

三、代碼實現

/**
 * 程序入口
 * @author Light
 */
public class JavaFXTest extends Application {
    
    @Override
    public void start(Stage stage) {
        
        stage.initStyle(StageStyle.TRANSPARENT);
        
        VBox root = new VBox();
        root.setId("root");
        // 引入樣式
        root.getStylesheets().add(JavaFXTest.class.getResource("/resources/style.css").toString());
        
        //頂部
        VBox top = new VBox();
        top.setId("top");
        top.setPrefSize(300,26);
        // 標題欄
        AnchorPane title = new AnchorPane();
        Label close = new Label();
        close.setPrefWidth(33);
        close.setPrefHeight(26);
        close.setId("winClose");//winClose css樣式Id
        title.getChildren().add(close);
        AnchorPane.setRightAnchor(close, 0.0);
        AnchorPane.setTopAnchor(close, 5.0);
        top.getChildren().add(title);
        
        // 內容
        VBox content = new VBox();
        content.setPrefWidth(300);
        content.setMinHeight(200);
        // 組裝
        root.getChildren().addAll(top, content);
        Scene scene = new Scene(root);        
        stage.setScene(scene);
        // 拖動監聽器
        DragUtil.addDragListener(stage, top);
        // 添加窗體拉伸效果
        DrawUtil.addDrawFunc(stage, root);
        // 顯示
        stage.show();
    }
    
    

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
    
}

 

/**
 * 拉伸工具類
 * @author Light
 */
public class DrawUtil {
    //窗體拉伸屬性
    private static boolean isRight;// 是否處於右邊界調整窗口狀態
    private static boolean isBottomRight;// 是否處於右下角調整窗口狀態
    private static boolean isBottom;// 是否處於下邊界調整窗口狀態
    private final static int RESIZE_WIDTH = 5;// 判定是否為調整窗口狀態的范圍與邊界距離
    private final static double MIN_WIDTH = 300;// 窗口最小寬度
    private final static double MIN_HEIGHT = 250;// 窗口最小高度
    
    public static void addDrawFunc(Stage stage,VBox root) {

root.setOnMouseMoved((MouseEvent event) -> { event.consume(); double x = event.getSceneX(); double y = event.getSceneY(); double width = stage.getWidth(); double height = stage.getHeight(); Cursor cursorType = Cursor.DEFAULT;// 鼠標光標初始為默認類型,若未進入調整窗口狀態,保持默認類型 // 先將所有調整窗口狀態重置 isRight = isBottomRight = isBottom = false; if (y >= height - RESIZE_WIDTH) { if (x <= RESIZE_WIDTH) {// 左下角調整窗口狀態 } else if (x >= width - RESIZE_WIDTH) {// 右下角調整窗口狀態 isBottomRight = true; cursorType = Cursor.SE_RESIZE; } else {// 下邊界調整窗口狀態 isBottom = true; cursorType = Cursor.S_RESIZE; } } else if (x >= width - RESIZE_WIDTH) {// 右邊界調整窗口狀態 isRight = true; cursorType = Cursor.E_RESIZE; } // 最后改變鼠標光標 root.setCursor(cursorType); }); root.setOnMouseDragged((MouseEvent event) -> { double x = event.getSceneX(); double y = event.getSceneY(); // 保存窗口改變后的x、y坐標和寬度、高度,用於預判是否會小於最小寬度、最小高度 double nextX = stage.getX(); double nextY = stage.getY(); double nextWidth = stage.getWidth(); double nextHeight = stage.getHeight(); if (isRight || isBottomRight) {// 所有右邊調整窗口狀態 nextWidth = x; } if (isBottomRight || isBottom) {// 所有下邊調整窗口狀態 nextHeight = y; } if (nextWidth <= MIN_WIDTH) {// 如果窗口改變后的寬度小於最小寬度,則寬度調整到最小寬度 nextWidth = MIN_WIDTH; } if (nextHeight <= MIN_HEIGHT) {// 如果窗口改變后的高度小於最小高度,則高度調整到最小高度 nextHeight = MIN_HEIGHT; } // 最后統一改變窗口的x、y坐標和寬度、高度,可以防止刷新頻繁出現的屏閃情況 stage.setX(nextX); stage.setY(nextY); stage.setWidth(nextWidth); stage.setHeight(nextHeight); }); } }

效果演示圖:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM