javaFX 在Controller中获取Stage

如果你想以Controller架构写javaFX的话, 有一个需求是按ESC键退出程序, 那么你需要在Controller中获取到Stage从而关闭程序

思路:
1. 根据id取到布局中的根元素, (使用fx:id获取 )
2. 通过根元素取得Stage

代码:

fxml:

<VBox fx:id="rootLayout" prefHeight="300.0" prefWidth="450.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<children>
        <TextArea fx:id="detail" onKeyPressed="#translateStart" prefHeight="100.0" prefWidth="450.0" text="" wrapText="true">
            <font>
                <Font name="consolas" size="13.0" />
            </font>
        </TextArea>
    </children>
<!--这里是你的其他控件-->
</VBox>

controller:

public class Controller implements EventHandler<KeyEvent> {
    @FXML
    private TextArea detail;
    @FXML
    private VBox rootLayout;

    //这里是监听键盘按下的事件方法
    @FXML
    public void translateStart(KeyEvent event) {
        handle(event);
    }

    //这里是判断如果按下ESC就直接退出
    @Override
    public void handle(KeyEvent event) {
        if (event.getCode() == KeyCode.ESCAPE) {
            //这里是取到Stage的具体代码
            Stage stage = (Stage) rootLayout.getScene().getWindow();
            stage.close();
        }
    }
}

其他不相关的代码我就不写了, 大家随意看看就好

参考博文: JavaFx在同一个Scence/Window加载新的fxml,以及在Controller中获取Stage

### JavaFX 中两个控制器之间传递参数的方法 在 JavaFX 应用程序中,多个场景或窗口通常由不同的控制器管理。为了使这些控制器能够相互通信并共享数据,在它们之间传递参数是一个常见的需求。 #### 方法一:通过主应用程序类传递 一种常见的方式是在启动应用时设置公共属性或方法用于存储和获取要传递的数据。假设有一个 `MainApp` 类作为整个应用程序的入口点: ```java public class MainApp extends Application { private StringProperty sharedData = new SimpleStringProperty(); public void setSharedData(String value){ this.sharedData.set(value); } public String getSharedData(){ return this.sharedData.get(); } } ``` 当需要从第一个控制器向第二个控制器发送信息时,可以通过调用此方法来保存所需的信息[^1]。 接着,在目标控制器初始化阶段读取该值: ```java @FXML private void initialize() { ((MainApp) AppContext.getInstance()).getSharedData(); // 假设存在静态工厂方法返回当前运行的应用实例 } ``` 这种方法适用于简单的应用场景,但对于更复杂的情况可能不够灵活。 #### 方法二:事件驱动模型 另一种更为推荐的做法是采用观察者模式或者发布/订阅机制。这允许一个对象(比如源控制器)通知其他感兴趣的对象发生了某些变化而无需知道谁会接收消息。可以借助于 `EventBus` 或类似的框架实现这一点。 对于较小规模的应用来说,直接使用 Java 的内置接口如 `ChangeListener<T>` 和 `InvalidationListener` 来监听特定属性的变化也是一种不错的选择。 例如,在源控制器中定义一个公开可访问的属性,并注册监听器以便及时更新视图或其他逻辑处理: ```java // Source Controller private final ObjectProperty<String> messageToPass = new SimpleObjectProperty<>(); public void setMessageForNextScreen(String msg){ this.messageToPass.setValue(msg); } messageToPass.addListener((observable, oldValue, newValue)->{ System.out.println("Message changed to "+newValue); }); ``` 而在目的控制器里,则可以在适当的时候查询这个属性的内容: ```java // Target Controller @FXML private Label displayLabel; @Override public void initialize(URL location, ResourceBundle resources) { // Assuming we have a way to access the source controller here. SourceController srcCtrlr = ... ; if (srcCtrlr != null && srcCtrlr.getMessageToPass()!=null){ displayLabel.setText(srcCtrlr.getMessageToPass().getValue()); } } ``` 这种方式使得组件间的耦合度更低,同时也更容易维护和发展大型项目[^2]。 #### 方法三:利用 FXML 加载器 如果两个控制器关联紧密且其中一个总是先被加载,那么可以直接让前者负责创建后者并将必要的参数传入其构造函数内。这是因为在加载 FXML 文件的同时还可以指定自定义的控制器实例。 ```java FXMLLoader loader = new FXMLLoader(getClass().getResource("/path/to/target.fxml")); TargetController targetCtrl = new TargetController(paramValue); loader.setController(targetCtrl); Parent root = loader.load(); Scene scene = new Scene(root); Stage stage = new Stage(); stage.setScene(scene); stage.show(); ``` 这里的关键在于手动构建了新的控制器实例而不是依赖默认行为自动创建它。这样就可以很容易地将任何类型的变量注入进去[^3]。 以上就是几种常用的 JavaFX 控制器间通信的技术方案。具体选择哪一种取决于实际项目的架构和个人偏好等因素。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值