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 ...