有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 { public MyStageCommon() { super(); // 创建窗口时加入 MyApp.stages.put(getClass().getName(), this); // x 掉窗口时将它移除 setOnCloseRequest(new EventHandler<WindowEvent>() { @Override public void handle(WindowEvent event) { MyApp.stages.remove(getClass().getName()); } }); } @Override public void close() { super.close(); MyApp.stages.remove(getClass().getName()); } /** * 获取对象,,注意返回空值 */ public <T> T getStage(Class<T> clazz) { Stage stage = MyApp.stages.get(clazz.getName()); if (stage == null) 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)); } }
效果: