百度了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之不通过全局静态变量进行窗体通信的更多相关文章

  1. C++中的局部变量、全局变量、局部静态变量、全局静态变量的区别

    局部变量(Local variables)与 全局变量: 在子程序或代码块中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量. 全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序 ...

  2. wpf绑定全局静态变量(mvvm)

    原文 wpf绑定全局静态变量(mvvm) 在实际的开发中,有一些集合或者属性可能是全局的,比如当你做一个oa的时候,可能需要展示所有的人员,这时这个所有的人员列表显然可以作为全局参数,比如这里有一个全 ...

  3. C++ 局部静态变量,全局变量,全局静态变量,局部变量的区别和联系

    C++变量根据定义位置的不同,具有不同的作用域,作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名作用域和文件作用域. 从作用域看: 全局变量具有全局作用域.全局变量只需在一个源文件 ...

  4. 关于C#静态变量初始化问题

    关于这个静态变量,平时自己没有太认真的去认识.最近调项目的bug,让我重新认识了静态变量的特点. 其实,我们一直都在说:静态变量只在类第一次初始化的时候进行初始化,以后都不初始化. 很简单的一句话,但 ...

  5. 静态变量static和extern外引用

    静态变量--加static关键字的变量,特点: (1)在全局数据区中分配内存,每次对其值得修改都会保留结果,直至程序结束. (2)若静态变量没显示初始化,那会被自动初始化为0,并且只能初始化一遍. 1 ...

  6. Python的学习(二十一)----Python的静态变量

    前段时间在论坛里面有人提问说, class foo(): member1 member2 ... self.member1 foo.member2 其中的两个成员member1, member2有什么 ...

  7. Springmvc在项目启动时查询数据库并初始化静态变量

    private static List<ResourceEntity> resourceList = null; //初始化的全局静态变量 @Autowired private Resou ...

  8. C和C++的静态函数和静态变量

       1.C程序的静态变量和函数 引用自:https://blog.csdn.net/thanklife/article/details/78476737 作者:零点零一   C程序一直由下列部分组成 ...

  9. 学了这么多年C语言,你真的知道全局变量,局部变量,静态变量,本地函数,外部函数是如何区分标识的吗?

    动态库内容分析 文章目录 动态库内容分析 1. 动态库编译 1.1 第一个C文件:basic.c 1.2第二个C文件:demo.c 1.3第三个C文件:main.c 2.动态库编译 3.二进制内容分析 ...

随机推荐

  1. Angular 2基础(一) 环境搭建

    Angular2是一款开源JavaScript库,由Google维护,用来创建页面应用程序.正式发布于2016年9月,基于ES6开发. 一.准备工作 使用Angular2开发,需要预先做一些配置上的配 ...

  2. TraceView工具的使用

    一.TraceView工具如何使用 TraceView有4种启动/关闭分析方式: (1) 第一种使用方法演示 1. 选择跟踪范围 在想要根据的代码片段之间使用以下两句代码 Debug.startMet ...

  3. JavaScript变量提升的理解

    变量提升 先说三句总结性的话: let 的「创建」过程被提升了,但是初始化没有提升. var 的「创建」和「初始化」都被提升了. function 的「创建」「初始化」和「赋值」都被提升了. 所以,我 ...

  4. mysql初次启动相关配置

    一.启动mysql服务 使用mysql之前,首先要启动mysql服务器端.使用命令mysqld.在命令行终端先进入mysql安装的目录直到bin目录,如图: 运行这个命令,可能会报错,提示找不到dat ...

  5. 让bootstrap-table支持高度百分比

    更改BootstrapTable.prototype.resetView 方法,以支持高度百分比定义,适应不同高度屏幕 BootstrapTable.prototype.resetView = fun ...

  6. CRM JS

    注意事项:Xrm.Page中的方法使用的是实体.字段.关系的逻辑名称.窗体调试:contentIFrame.Xrm.Page.getControl("compositeControlPara ...

  7. Windows 10更新后频繁死机、假死(SSD)

    问题详情: 新版的Windows改变了更新策略,无法设置为不更新系统.在系统更新后,之前的部分设定也会神奇丢失,包括之前设定的解决的这个卡顿问题.于是重新爬文章找解决方案,在这里做个备份. 本文章内容 ...

  8. ccf-20160903--炉石传说

    本题思路如下图: 题目和代码如下: 问题描述 试题编号: 201609-3 试题名称: 炉石传说 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 <炉石传说:魔兽英雄传& ...

  9. Java学习笔记--JDK动态代理

    1.JDK动态代理     JDK1.3之后,Java提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和 ...

  10. 什么是Java序列化?如何实现序列化?

    一.什么是序列化: 序列化理解成“打碎”是可以的,不过在书本上的名词就是将对象转换成二进制. 二.在java中如何实现序列化: 首先我们要把准备要序列化类,实现 Serializabel接口 例如:我 ...