JavaFx之不通过全局静态变量进行窗体通信
百度了n多窗体通信,,,总是通过定义全局静态变量进行传值通信。。我个人不喜欢一个controller里写满所有的布局(这样显得臃肿,但是组件传值方便)。有没有另外的办法进行模块化并且可以传值呢。。
肯定是有的。。。
1.定义一个泛型类接收Controller对象与Stage对象
 public class StageAndController<C, S> {
     private C controller;
     private S stage;
     public StageAndController(C controller, S stage) {
         this.controller = controller;
         this.stage = stage;
     }
     public StageAndController(C controller) {
         this.controller = controller;
     }
     public C getController() {
         return controller;
     }
     public void setController(C controller) {
         this.controller = controller;
     }
     public S getStage() {
         return stage;
     }
     public void setStage(S stage) {
         this.stage = stage;
     }
 }
这里之所以返回两个对象,,首先每个controller都对应一个打开的布局窗体,controller用来传值、赋值、初始化操作,stage本身需要调用show()才显示,,所以定义此类
2.封装 打开一个窗体或者动态加载一个Node
 public static StageAndController addMenu(final Pane pane, final String fxmlName, Object controller) {
         URL location = AddOperation.class.getResource("/fxml/" + fxmlName);
         FXMLLoader fxmlLoader = new FXMLLoader();
         fxmlLoader.setLocation(location);
         fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
         try {
             Node node = fxmlLoader.load();//返回Node对象  Node是布局顶级父类,再之上就是Object,所有此处可以加载一个布局添加到父级中
             pane.getChildren().add(node);//Node添加到父级布局
             controller = fxmlLoader.getController();//获取加载布局的Contrller对象
         } catch (IOException e) {
             e.printStackTrace();
         }
         return new StageAndController(controller);//返回controller实例
     }
//pane->需要添加node的父级Pane及Pane子类对象 fxmlName-->自定义的布局文件 Object-->需要实例化的Controller
这里我的用法是动态增加一排菜单栏,使用了到了controller传值作用,用法如下:
StageAndController controller = AddOperation.addMenu(operation, "read_item.fxml", ReadCardController.class);
readCardController = (ReadCardController) controller.getController();
向父级窗体暴露了一个Controller实例对象,就可以进行父窗体向子组件传值,初始化。
-------------------------------------------------------------------------------------------------------
  public static StageAndController newDialog(String fxmlName, String title, Object controller) {
         URL location = OpenDialog.class.getResource("/fxml/" + fxmlName);
         FXMLLoader fxmlLoader = new FXMLLoader();
         fxmlLoader.setLocation(location);
         fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
         Stage stage = new Stage();
         try {
             Pane dialogPane = fxmlLoader.load();
             stage.setScene(new Scene(dialogPane));
             stage.initModality(Modality.APPLICATION_MODAL);
             stage.initStyle(StageStyle.DECORATED);
             stage.setResizable(false);
             if (title != null) {
                 stage.setTitle(title);
             }
             controller = fxmlLoader.getController();
         } catch (IOException e) {
             e.printStackTrace();
         }
         return new StageAndController(controller, stage);
此处同理,加载的是一个窗体布局,同时设置模态化(本身未关闭,父级窗体不可点击)、动态标题,,,,,返回一个Controller与Stage对象,,,用法如下:
 StageAndController stageAndController = OpenDialog.newDialog("connectDevice.fxml", "连接", ConnectDevice.class);
        ConnectDevice controller = (ConnectDevice) stageAndController.getController();
        Stage stage = (Stage) stageAndController.getStage();
        controller.str= str;
        controller.init();
        stage.show();
窗体显示之前父窗体向子窗体传值或者做一些初始化。 这样模块化布局传值也变得简单好维护。
-------------------------------------------------------------------------------------------------------
嫌弃自带窗体风格太丑,,可以往下看。。
自定义Stage窗体布局(State设置透明时):
public static StageAndController customDialog(String fxmlName, Object controller, Pane pane, String css) {
        URL location = OpenDialog.class.getResource("/fxml/" + fxmlName);
        FXMLLoader fxmlLoader = new FXMLLoader();
        fxmlLoader.setLocation(location);
        fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
        Stage stage = new Stage();
        try {
            pane = fxmlLoader.load();
            Background background = new Background(new BackgroundFill(Paint.valueOf("#EFEFEF"), new CornerRadii(15), new Insets(0)));
            pane.setBackground(background);
            pane.setBorder(new Border(new BorderStroke(Color.valueOf("#0096C9"), BorderStrokeStyle.SOLID, new CornerRadii(15), new BorderWidths(2))));
            Scene scene = new Scene(pane);
            if (css != null) {
                scene.getStylesheets().add(OpenDialog.class.getResource("/css/" + css).toExternalForm());
            }
            scene.setFill(Paint.valueOf("#FFFFFF00"));//设置场景透明
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.initStyle(StageStyle.TRANSPARENT);
            stage.setResizable(false);
            stage.setScene(scene);
            controller = fxmlLoader.getController();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new StageAndController(controller, stage);
    }
用法差不多,加了一个自定义加载css样式,可以按需更改,,不过自定义时,,窗体头部拖动就不可用,下面贴出解决方案:
 public class DragListener implements EventHandler<MouseEvent> {
     private double xOffset = 0;
     private double yOffset = 0;
     private final Stage stage;
     public DragListener(Stage stage) {
         this.stage = stage;
     }
     @Override
     public void handle(MouseEvent event) {
         event.consume();
         if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
             xOffset = event.getSceneX();
             yOffset = event.getSceneY();
         } else if (event.getEventType() == MouseEvent.MOUSE_DRAGGED) {
             stage.setX(event.getScreenX() - xOffset);
             if(event.getScreenY() - yOffset < 0) {
                 stage.setY(0);
             }else {
                 stage.setY(event.getScreenY() - yOffset);
             }
         }
     }
     public void enableDrag(Node node) {
         node.setOnMousePressed(this);
         node.setOnMouseDragged(this);
     }
 }
用法如下:
   StageAndController stageAndController = OpenDialog.customDialog("connectDevice_cus.fxml",ConnectDevice.class,new Pane(),null);
         ConnectDevice controller = (ConnectDevice) stageAndController.getController();
         Stage stage = (Stage) stageAndController.getStage();
         new DragListener(stage).enableDrag(controller.title);//自定义窗口时设置拖动监听   此处controller.title是我自定义窗体标题栏的HBox对象
         controller.stage = stage;
         controller.init();
         stage.show();
这样就可以愉快的使用自定义弹窗了。。。。
-------------------------------------------------------------------------------------------------------
不喜勿喷!!!! 欢迎进群学习交流(927465926)
JavaFx之不通过全局静态变量进行窗体通信的更多相关文章
- C++中的局部变量、全局变量、局部静态变量、全局静态变量的区别
		
局部变量(Local variables)与 全局变量: 在子程序或代码块中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量. 全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序 ...
 - wpf绑定全局静态变量(mvvm)
		
原文 wpf绑定全局静态变量(mvvm) 在实际的开发中,有一些集合或者属性可能是全局的,比如当你做一个oa的时候,可能需要展示所有的人员,这时这个所有的人员列表显然可以作为全局参数,比如这里有一个全 ...
 - C++ 局部静态变量,全局变量,全局静态变量,局部变量的区别和联系
		
C++变量根据定义位置的不同,具有不同的作用域,作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名作用域和文件作用域. 从作用域看: 全局变量具有全局作用域.全局变量只需在一个源文件 ...
 - 关于C#静态变量初始化问题
		
关于这个静态变量,平时自己没有太认真的去认识.最近调项目的bug,让我重新认识了静态变量的特点. 其实,我们一直都在说:静态变量只在类第一次初始化的时候进行初始化,以后都不初始化. 很简单的一句话,但 ...
 - 静态变量static和extern外引用
		
静态变量--加static关键字的变量,特点: (1)在全局数据区中分配内存,每次对其值得修改都会保留结果,直至程序结束. (2)若静态变量没显示初始化,那会被自动初始化为0,并且只能初始化一遍. 1 ...
 - Python的学习(二十一)----Python的静态变量
		
前段时间在论坛里面有人提问说, class foo(): member1 member2 ... self.member1 foo.member2 其中的两个成员member1, member2有什么 ...
 - Springmvc在项目启动时查询数据库并初始化静态变量
		
private static List<ResourceEntity> resourceList = null; //初始化的全局静态变量 @Autowired private Resou ...
 - C和C++的静态函数和静态变量
		
1.C程序的静态变量和函数 引用自:https://blog.csdn.net/thanklife/article/details/78476737 作者:零点零一 C程序一直由下列部分组成 ...
 - 学了这么多年C语言,你真的知道全局变量,局部变量,静态变量,本地函数,外部函数是如何区分标识的吗?
		
动态库内容分析 文章目录 动态库内容分析 1. 动态库编译 1.1 第一个C文件:basic.c 1.2第二个C文件:demo.c 1.3第三个C文件:main.c 2.动态库编译 3.二进制内容分析 ...
 
随机推荐
- bootstrap-select插件     多选框
			
HeBeiTianQi.jsp页面 1 <!--bootstrap-select .css引用--> 2 <link rel="stylesheet" href= ...
 - Linux 下查看系统当前登录用户信息
			
当你新登录一个主机,过着管理一个主机,这时候你就需要这些命令来进行查看了: 1. w : Show who is logged on and what they are doing. w [optio ...
 - Hadoop2.7.6_07_HA高可用
			
1. Hadoop的HA机制 前言:正式引入HA机制是从hadoop2.0开始,之前的版本中没有HA机制 1.1. HA的运作机制 (1)hadoop-HA集群运作机制介绍 所谓HA,即高可用(7*2 ...
 - cocos2d-x 3.0 安装及创建项目
			
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/LanerGaming/article/details/24146921 好久没实用过cocos2d- ...
 - socket.io+angular.js+express.js做个聊天应用(三)
			
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/www19940501a/article/details/27590611 接着前面博客文章socke ...
 - JS操作DOM节点大全
			
1.Javascript删除节点 在Javascript中,只提供了一种删除节点的方法:removeChild(). removeChild() 方法用来删除父节点的一个子节点. 语法:parent. ...
 - 转载 javascript中(function($){...})(jQuery)写法是什么意思
			
javascript中(function($){...})(jQuery)写法是什么意思 这里实际上是匿名函数function(arg){...}这就定义了一个匿名函数,参数为arg 而调用函数 ...
 - HTTPS协议,SSL协议及完整交互过程
			
文章转自 https://blog.csdn.net/dfsaggsd/article/details/50910999 SSL 1. 安全套接字(Secure Socket Layer ...
 - PAT A1076 Forwards on Weibo (30 分)——图的bfs
			
Weibo is known as the Chinese version of Twitter. One user on Weibo may have many followers, and may ...
 - PAT A1106 Lowest Price in Supply Chain (25 分)——树的bfs遍历
			
A supply chain is a network of retailers(零售商), distributors(经销商), and suppliers(供应商)-- everyone invo ...