You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX width/height属性仅触发一次的问题咨询

解决JavaFX窗口Resize事件仅触发一次的问题

嘿,我之前也踩过这个坑!你的代码里的核心问题是监听器类型用错了——你现在使用的是InvalidationListener而非ChangeListener,这就是为什么resize事件只触发一次的原因。

我给你详细拆解下:
当你写:

stage.widthProperty().addListener(observable -> { System.out.println("Width changed"); });

这个lambda对应的是InvalidationListener接口,它只会在属性从有效状态变为无效状态时触发一次。而且如果你不去主动读取这个属性的值(比如调用stage.getWidth()),它就不会再次触发——因为属性会一直保持"无效"状态,不会重复发送通知。

而我们实际需要的是ChangeListener,它会在属性实际值发生变化时每次都触发,不管有没有读取属性值。

正确的写法

你需要把监听器改成ChangeListener的形式,接收旧值和新值参数:

Stage stage = new Stage();
stage.setScene(someScene);
stage.setTitle("Some Title");
stage.initModality(Modality.APPLICATION_MODAL);

// 建议先添加监听器再调用show,逻辑上更连贯,顺序不影响功能
stage.widthProperty().addListener((observable, oldValue, newValue) -> {
    System.out.println("Width changed from " + oldValue + " to " + newValue);
});
stage.heightProperty().addListener((observable, oldValue, newValue) -> {
    System.out.println("Height changed from " + oldValue + " to " + newValue);
});

stage.show();

额外小建议:监听Scene尺寸可能更贴合需求

如果你关注的是窗口内可布局的客户区尺寸(不包含标题栏、边框这些系统窗口装饰),建议监听Scene的尺寸属性而非Stage的:

someScene.widthProperty().addListener((observable, oldValue, newValue) -> {
    System.out.println("Scene width changed: " + newValue);
});
someScene.heightProperty().addListener((observable, oldValue, newValue) -> {
    System.out.println("Scene height changed: " + newValue);
});

这样你拿到的是实际可用的布局区域尺寸,更适合用来触发布局重计算。

内容的提问来源于stack exchange,提问作者James Robinson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 20:39:08