JavaFx中Controller获取Stage并自定义窗口移动与缩放逻辑

栏目: Java · 发布时间: 5年前

内容简介:由于去掉了平台自带了标题栏,窗口就无法移动和缩放了,需要我们自己来实现。首先确定在Controller中获取到你的跟布局对象,如下:然后可以在

JavaFx中Controller获取Stage并自定义窗口移动与缩放逻辑

由于去掉了平台自带了标题栏,窗口就无法移动和缩放了,需要我们自己来实现。

去除窗口标题栏

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
        primaryStage.setTitle("main");
        // 主要是这一句
        primaryStage.initStyle(StageStyle.TRANSPARENT);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }


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

在Controller中获取Stage

首先确定在Controller中获取到你的跟布局对象,如下:

public class Controller implements Initializable {
    public BorderPane root;
    private Stage stage;
}
<BorderPane fx:id="root" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" stylesheets="@../css/main.css" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="line.main.Controller">
      <!--其他布局元素-->
</BorderPane>

然后可以在 public void initialize(URL url, ResourceBundle resourceBundle) 方法内获取Stage

public class Controller implements Initializable {
    public BorderPane root;
    private Stage stage;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
       var stage = getStage();
    }

    private Stage getStage() {
        if (stage == null) {
            stage = (Stage) root.getScene().getWindow();
        }
        return stage;
    }

}

自定义窗体移动与缩放逻辑

  1. 记录鼠标坐标

    root.setOnMousePressed(event -> {
                event.consume();
                xOffset = event.getSceneX();
                yOffset = event.getSceneY();
            });
  2. 自定义移动控制区域

    dragArea.setOnMouseDragged(event -> {
                event.consume();
                var stage = getStage();
                stage.setX(event.getScreenX() - xOffset);
                stage.setY(event.getScreenY() - yOffset);
            });
  3. 判断鼠标坐标位置,并处理光标变换

    root.setOnMouseMoved(this::mouseMoveHandle);
    
     private void mouseMoveHandle(MouseEvent event) {
            event.consume();
            double x = event.getSceneX();
            double y = event.getSceneY();
            var stage = getStage();
            double width = stage.getWidth();
            double height = stage.getHeight();
            Cursor cursorType = Cursor.DEFAULT;
            bit = 0;
            if (y >= height - RESIZE_WIDTH) {
                if (x <= RESIZE_WIDTH) {
                    bit |= 1 << 3;
                } else if (x >= width - RESIZE_WIDTH) {
                    bit |= 1;
                    bit |= 1 << 2;
                    cursorType = Cursor.SE_RESIZE;
                } else {
                    bit |= 1;
                    cursorType = Cursor.S_RESIZE;
                }
            } else if (x >= width - RESIZE_WIDTH) {
                bit |= 1 << 2;
                cursorType = Cursor.E_RESIZE;
            }
            root.setCursor(cursorType);
        }
  4. 处理窗口缩放

    root.setOnMouseDragged(this::mouseDraggedHandle);
    
    private void mouseDraggedHandle(MouseEvent event) {
        event.consume();
        var primaryStage = getStage();
        double x = event.getSceneX();
        double y = event.getSceneY();
        double nextX = primaryStage.getX();
        double nextY = primaryStage.getY();
        double nextWidth = primaryStage.getWidth();
        double nextHeight = primaryStage.getHeight();
        if ((bit & 1 << 2) != 0) {
            nextWidth = x;
        }
        if ((bit & 1) != 0) {
            nextHeight = y;
        }
        if (nextWidth <= MIN_WIDTH) {
            nextWidth = MIN_WIDTH;
        }
        if (nextHeight <= MIN_HEIGHT) {
            nextHeight = MIN_HEIGHT;
        }
        primaryStage.setX(nextX);
        primaryStage.setY(nextY);
        primaryStage.setWidth(nextWidth);
        primaryStage.setHeight(nextHeight);
    }

完整代码

package line.main;

import javafx.fxml.Initializable;
import javafx.scene.Cursor;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable {
    public BorderPane root;
    public Pane dragArea;
    private Stage stage;
    private double xOffset = 0;
    private double yOffset = 0;
    private int bit = 0;//left,right,top,bottom
    private static final double RESIZE_WIDTH = 5.00;
    private static final double MIN_WIDTH = 600.00;
    private static final double MIN_HEIGHT = 400.00;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        dragArea.setOnMouseDragged(event -> {
            event.consume();
            var stage = getStage();
            stage.setX(event.getScreenX() - xOffset);
            stage.setY(event.getScreenY() - yOffset);
        });
        root.setOnMousePressed(event -> {
            event.consume();
            xOffset = event.getSceneX();
            yOffset = event.getSceneY();
        });
        root.setOnMouseMoved(this::mouseMoveHandle);
        root.setOnMouseDragged(this::mouseDraggedHandle);
    }

    private Stage getStage() {
        if (stage == null) {
            stage = (Stage) root.getScene().getWindow();
        }
        return stage;
    }

    private void mouseMoveHandle(MouseEvent event) {
        event.consume();
        double x = event.getSceneX();
        double y = event.getSceneY();
        var stage = getStage();
        double width = stage.getWidth();
        double height = stage.getHeight();
        Cursor cursorType = Cursor.DEFAULT;
        bit = 0;
        if (y >= height - RESIZE_WIDTH) {
            if (x <= RESIZE_WIDTH) {
                bit |= 1 << 3;
            } else if (x >= width - RESIZE_WIDTH) {
                bit |= 1;
                bit |= 1 << 2;
                cursorType = Cursor.SE_RESIZE;
            } else {
                bit |= 1;
                cursorType = Cursor.S_RESIZE;
            }
        } else if (x >= width - RESIZE_WIDTH) {
            bit |= 1 << 2;
            cursorType = Cursor.E_RESIZE;
        }
        root.setCursor(cursorType);
    }

    private void mouseDraggedHandle(MouseEvent event) {
        event.consume();
        var primaryStage = getStage();
        double x = event.getSceneX();
        double y = event.getSceneY();
        double nextX = primaryStage.getX();
        double nextY = primaryStage.getY();
        double nextWidth = primaryStage.getWidth();
        double nextHeight = primaryStage.getHeight();
        if ((bit & 1 << 2) != 0) {
            nextWidth = x;
        }
        if ((bit & 1) != 0) {
            nextHeight = y;
        }
        if (nextWidth <= MIN_WIDTH) {
            nextWidth = MIN_WIDTH;
        }
        if (nextHeight <= MIN_HEIGHT) {
            nextHeight = MIN_HEIGHT;
        }
        primaryStage.setX(nextX);
        primaryStage.setY(nextY);
        primaryStage.setWidth(nextWidth);
        primaryStage.setHeight(nextHeight);
    }
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

人本界面

人本界面

(美)拉斯基(Jef Raskin) / 史元春 / 机械工业出版社 / 2004-1-1 / 28.0

如果我们想克服目前人机界面上的固有缺陷,就很有必要理解本书的教义;若无此愿望,读读也无妨。交互设计的许多重要方面此书并没有包括在内,因为许多文献中都已经有详尽的阐述。本书的意图是补充现有的界面设计的方法或预测未来。  本书概述了人机界面设计领域的研究成果,详细论证了界面设计思想应以认知学为基础,并考虑人类的心智特点,在指出当前界面设计中弊端的同时,提出了新产品开发的思路。本书集计算机科学、人体工程......一起来看看 《人本界面》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

随机密码生成器
随机密码生成器

多种字符组合密码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试