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.二进制内容分析 ...
随机推荐
- (后台)java 读取excel 文件 Unable to recognize OLE stream 错误
原因:不支出读取 excel 2007 文件(*.xlsx).只支持 excel 2003 (*.xls). 光修改文件后缀不行,需要文件另存(或者导出)为 .xls Excel 1997-2004 ...
- Python数据清洗基本流程
# -*- coding: utf-8 -*-"""Created on Wed Jul 4 18:40:55 2018 @author: zhen"" ...
- 【PAT】B1042 字符统计(20 分)
/* 15分的题很简单,但是自己写的时候在输入数据时没有考虑好下标 另外有忘记了输入字符时考虑是否有\n */ #include<stdio.h> #include<algorith ...
- JDBC lesson 1
https://www.mkyong.com/tutorials/jdbc-tutorials/ 1.jdbc基本概念 Java Database Connectivity (JDBC)是一套提供数据 ...
- 简单Nginx下防跨站、跨目录安全设置,支持PHP 5.3.3以上版本
Nginx下存在跨站和跨目录的问题,跨站和跨目录影响同服务器/VPS上的其他网站. PHP在5.3.3以上已经增加了HOST配置,可以起到防跨站.跨目录的问题. 如果你是PHP 5.3.3以上的版本, ...
- element-ui使用导航栏跳转路由用法
element-ui使用导航栏跳转路由用法 最近初学vue,试着做一个小项目熟悉语法与思想,其中使用elemen-ui的导航栏做路由跳转切换页面.下面记录一下学习过程 element-ui引入vue项 ...
- 让zepto支持slideup(),slidedown()
zepto不支持slideup()和slidedown():使用以下方法可以支持该功能 <div class="slide"> <p> zepto不支持sl ...
- 1.4 Genymotion模拟器安装
如果你符合下述三种情况的话,你可以考虑安装一个Genymotion Android模拟器: 没有真机调试,只能用模拟器 嫌SDK内置的AVD启动速度,运行速度慢 电脑配置还可以,最好4G内存以上 如果 ...
- day12 Python字典
类:dict #字典是无序的 1.前戏 info = { "k1": "v1", # 键值对 "k2": "v2" } ...
- 【总文档】rac增加新节点的方法步骤 How to Add Node/Instance or Remove Node/Instance in 10gR2, 11gR1, 11gR2 and 12c Oracle Clusterware and RAC
[总文档]How to Add Node/Instance or Remove Node/Instance in 10gR2, 11gR1, 11gR2 and 12c Oracle Clusterw ...