JavaFx之场景交互(二十一)
JavaFx之场景交互(二十一)
有parent、son两个父子窗口,父窗口可以操作子窗口,父子可以相互调用对方的对象,下面我给出两种方案,我推荐使用第二种
一、构造传参
参数比较多的话代码不优雅、而且不太方便维护。
父
package top.oneit.jdownload.test;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
/**
* @author lingkang
*/
public class MyParent extends Application {
private MySonA sonA;
private Button button;
@Override
public void start(Stage primaryStage) throws Exception {
button = new Button("open子窗口A");
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (sonA==null){
sonA = new MySonA(primaryStage,button);
sonA.show();// 显示子窗口
}else{
sonA.show();
}
// 调用子接口对象
System.out.println(sonA.getButton().getText());
}
});
Button closeSon = new Button("关闭子窗口");
closeSon.setLayoutY(40);
closeSon.setOnAction(event -> {
sonA.close();
});
AnchorPane anchorPane = new AnchorPane(button, closeSon);
anchorPane.setPrefWidth(400);
anchorPane.setPrefHeight(300);
primaryStage.setScene(new Scene(anchorPane));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
子
package top.oneit.jdownload.test;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
/**
* @author lingkang
*/
public class MySonA extends Stage {
private Stage parent;
private Button button;
public MySonA(Stage parent,Button parentButton) {
this.parent = parent;
Label label = new Label("我是儿子A");
button = new Button("关闭父窗口");
button.setOnAction(event -> {
System.out.println(parent.getTitle());
parent.close();
});
button.setLayoutY(40);
Button open = new Button("打开父窗口");
open.setLayoutY(80);
open.setOnAction(event -> {
parentButton.setText("子调用父的对象");// 父子传参,构造方法
parent.show();
});
Button exit = new Button("exit");
exit.setLayoutY(120);
exit.setOnAction(event -> {
System.exit(0);
});
AnchorPane pane = new AnchorPane(label, button, open, exit);
pane.setPrefWidth(300);
pane.setPrefHeight(200);
setScene(new Scene(pane));
}
public Button getButton() {
return button;
}
public void setButton(Button button) {
this.button = button;
}
}
效果:

二、继承公共类
灵活,注意,创建多个同样的窗口带来的问题,还有获取对应stage为空的问题!提前判空
启动入口
import javafx.application.Application;
import javafx.stage.Stage;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* @author lingkang
* @date 2021/11/18
*/
public class MyApp extends Application {
public static ConcurrentMap<String, Stage> stages = new ConcurrentHashMap<>();
@Override
public void start(Stage primaryStage) throws Exception {
new MyParent();//显示父窗口
}
public static void main(String[] args) {
launch(args);
}
}
公共类
import javafx.event.EventHandler;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
/**
* @author lingkang
* @date 2021/11/18
*/
public class MyStageCommon extends Stage {
private String thisClassName=getClass().getName();//将当前类名单独初始化
public MyStageCommon() {
super();
// 创建窗口时加入
MyApp.stages.put(thisClassName, this);
// x 掉窗口时将它移除
setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
MyApp.stages.remove(thisClassName);
}
});
}
@Override
public void close() {
super.close();
MyApp.stages.remove(thisClassName);
}
/**
* 获取对象,,注意返回空值
*/
public <T> T getStage(Class<T> clazz) {
if (!MyApp.stages.containsKey(clazz.getName()))
return null;
return (T) MyApp.stages.get(clazz.getName());
}
}
父
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
/**
* @author lingkang
*/
public class MyParent extends MyStageCommon {
public Button button;
public MyParent() {
setTitle("父窗口!");
button = new Button("open子窗口A");
button.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
if (getStage(MySonA.class) == null) {
new MySonA().show();// 显示子窗口
} else {
getStage(MySonA.class).show();
}
// 调用子接口对象
System.out.println(getStage(MySonA.class).button.getText());
}
});
Button closeSon = new Button("关闭子窗口");
closeSon.setLayoutY(40);
closeSon.setOnAction(event -> {
if (getStage(MySonA.class) != null)
getStage(MySonA.class).close();
});
AnchorPane anchorPane = new AnchorPane(button, closeSon);
anchorPane.setPrefWidth(400);
anchorPane.setPrefHeight(300);
setScene(new Scene(anchorPane));
show();
}
}
子
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import java.util.Date;
/**
* @author lingkang
*/
public class MySonA extends MyStageCommon {
public Button button;
public MySonA() {
setTitle("子窗口A");
MyParent parent = getStage(MyParent.class);
Label label = new Label("我是儿子A");
button = new Button("关闭父窗口");
button.setOnAction(event -> {
System.out.println(parent.getTitle());
parent.close();
});
button.setLayoutY(40);
Button open = new Button("打开父窗口");
open.setLayoutY(80);
open.setOnAction(event -> {
if (parent.button != null)
parent.button.setText("子调用父的对象" + new Date());// 父子传参
parent.show();
});
Button exit = new Button("exit");
exit.setLayoutY(120);
exit.setOnAction(event -> {
System.exit(0);
});
AnchorPane pane = new AnchorPane(label, button, open, exit);
pane.setPrefWidth(300);
pane.setPrefHeight(200);
setScene(new Scene(pane));
}
}
效果:

JavaFx之场景交互(二十一)的更多相关文章
- WCF技术剖析之二十一:WCF基本异常处理模式[中篇]
原文:WCF技术剖析之二十一:WCF基本异常处理模式[中篇] 通过WCF基本的异常处理模式[上篇], 我们知道了:在默认的情况下,服务端在执行某个服务操作时抛出的异常(在这里指非FaultExcept ...
- 中介者模式 调停者 Mediator 行为型 设计模式(二十一)
中介者模式(Mediator) 调度.调停 意图 用一个中介对象(中介者)来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散 而且可以独立地改变它们之间的交互. ...
- WCF技术剖析之二十一:WCF基本异常处理模式[下篇]
原文:WCF技术剖析之二十一:WCF基本异常处理模式[下篇] 从FaultContractAttribute的定义我们可以看出,该特性可以在同一个目标对象上面多次应用(AllowMultiple = ...
- WCF技术剖析之二十一: WCF基本的异常处理模式[上篇]
原文:WCF技术剖析之二十一: WCF基本的异常处理模式[上篇] 由于WCF采用.NET托管语言(C#和NET)作为其主要的编程语言,注定以了基于WCF的编程方式不可能很复杂.同时,WCF设计的一个目 ...
- iOS 11开发教程(二十一)iOS11应用视图美化按钮之实现按钮的响应(1)
iOS 11开发教程(二十一)iOS11应用视图美化按钮之实现按钮的响应(1) 按钮主要是实现用户交互的,即实现响应.按钮实现响应的方式可以根据添加按钮的不同分为两种:一种是编辑界面添加按钮实现的响应 ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(二十一):在小程序中使用 WebSocket (.NET Core)
本文将介绍如何在 .NET Core 环境下,借助 SignalR 在小程序内使用 WebSocket.关于 WebSocket 和 SignalR 的基础理论知识不在这里展开,已经有足够的参考资料, ...
- 学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用
目录 学习笔记:CentOS7学习之二十一: 条件测试语句和if流程控制语句的使用 21.1 read命令键盘读取变量的值 21.1.1 read常用见用法及参数 21.2 流程控制语句if 21.2 ...
- Django笔记二十一之使用原生SQL查询数据库
本文首发于公众号:Hunter后端 原文链接:Django笔记二十一之使用原生SQL查询数据库 Django 提供了两种方式来执行原生 SQL 代码. 一种是使用 raw() 函数,一种是 使用 co ...
- 无废话ExtJs 入门教程二十一[继承:Extend]
无废话ExtJs 入门教程二十一[继承:Extend] extjs技术交流,欢迎加群(201926085) 在开发中,我们在使用视图组件时,经常要设置宽度,高度,标题等属性.而这些属性可以通过“继承” ...
- Bootstrap <基础二十一>徽章(Badges)
Bootstrap 徽章(Badges).徽章与标签相似,主要的区别在于徽章的边角更加圆滑. 徽章(Badges)主要用于突出显示新的或未读的项.如需使用徽章,只需要把 <span class= ...
随机推荐
- 异常:no transaction is in progress
转载请注明出处: 在使用 @Scheduled 注解创建了一个定时任务,并通过定时任务不断向mysql写入数据,写入数据的方式是通过 jpa 的方式,在代码运行的过程中出现错误:no transac ...
- md5sum 文件一致性校验
1. 背景 在网络传输.设备之间转存.复制大文件等时,可能会出现传输前后数据不一致的情况.这种情况在网络这种相对更不稳定的环境中,容易出现.那么校验文件的完整性,也是势在必行的. md5sum命令用于 ...
- Python面向对象——面向对象介绍、实现面向对象编程、定义类、再调用类产生对象、总结__init__方法、查找顺序
文章目录 面向对象介绍 实现面向对象编程 一:先定义类 二:再调用类产生对象 总结__init__方法 查找顺序 面向对象介绍 ''' 面向过程: 核心是"过程"二字 过程的终极奥 ...
- mooc第五单元《管理组织》单元测试
第五单元<管理组织>单元测试 返回 本次得分为:30.00/50.00, 本次测试的提交时间为:2020-08-30, 如果你认为本次测试成绩不理想,你可以选择 再做一次 . 1 ...
- Sentinel源码改造,实现Nacos双向通信!
Sentinel Dashboard(控制台)默认情况下,只能将配置规则保存到内存中,这样就会导致 Sentinel Dashboard 重启后配置规则丢失的情况,因此我们需要将规则保存到某种数据源中 ...
- js数据结构--字典
<!DOCTYPE html> <html> <head> <title></title> </head> <body&g ...
- 18.2 使用NPCAP库抓取数据包
NPCAP 库是一种用于在Windows平台上进行网络数据包捕获和分析的库.它是WinPcap库的一个分支,由Nmap开发团队开发,并在Nmap软件中使用.与WinPcap一样,NPCAP库提供了一些 ...
- 后缀数组 (SA) 学习笔记
写得很草率的一篇东西. 后缀排序 #include<bits/stdc++.h> #define il inline using namespace std; il int read() ...
- CF1523D Love-Hate 题解
抽象化题意: 一共有 \(m\) 个元素,给定 \(n\) 个集合,每个集合的元素不超过 \(15\) 个,求出一个元素个数最多的集合 \(S\) 是至少 \(\lceil \dfrac{n}{2} ...
- 彻底掌握Python中 * 号
Python中的 *号是一个特殊的符号,在其他编程语言中,它最广为人知的用途就是作为乘法运算的符号.而在Python中,它的用途远不止如此. 本文总结了Python中*号的所有用途,以供参考. 1. ...