JavaFX窗口程序开发(实现窗口大小自由拉伸效果)

wylc123 1年前 ⋅ 442 阅读

一、问题场景

  同样的,隐藏掉窗体的默认标题栏也会导致窗体大小自由拉伸功能的失效。

二、解决思路

  判断鼠标在窗体的位置,改变鼠标样式,给窗体组件添加拖拽事件监听器,根据鼠标移动位置改变窗体大小。

三、代码实现

/**
 * 程序入口
 * @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);
        });
    }
}

效果演示图:

 


全部评论: 0

    我有话说: