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

如何在JavaFX中保持Stage调整大小时的1:1恒定比例?

JavaFX Stage 保持1:1缩放比例的正确实现

原代码的问题分析

  • 交替移除/添加监听器的方式会导致窗口调整过程中反复触发width和height属性变更,引发明显闪烁
  • 依赖鼠标释放后才能稳定显示正确比例,无法实时响应拖动操作
  • 你提到的WindowEvent.WINDOW_RESIZED并非标准JavaFX API中的事件,不存在于官方库中,属于非正规内容误导

解决方案:使用标志位避免循环触发

核心思路是添加一个布尔标志位,标记当前是否正在执行窗口大小调整,避免width和height的监听器互相触发循环,实现实时的1:1比例锁定。

修正后的完整代码

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class Test extends Application {

    private ChangeListener<? super Number> widthListener;
    private ChangeListener<? super Number> heightListener;
    // 标志位:标记是否正在调整窗口大小,避免循环触发监听器
    private boolean isResizing = false;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        double length = 300;
        Circle circle = new Circle();
        circle.setRadius(length / 2);
        circle.setCenterX(length / 2);
        circle.setCenterY(length / 2);
        circle.setFill(Color.BLUEVIOLET);

        Pane pane = new Pane(circle);
        Scene scene = new Scene(pane);

        stage.setTitle("Test");
        stage.setScene(scene);
        stage.setOnCloseRequest(event -> Platform.exit());

        // 宽度变化监听器
        widthListener = (obs, oldWidth, newWidth) -> {
            if (!isResizing) {
                isResizing = true;
                // 同步高度为当前宽度,保持1:1比例
                stage.setHeight(newWidth.doubleValue());
                isResizing = false;
            }
        };
        stage.widthProperty().addListener(widthListener);

        // 高度变化监听器
        heightListener = (obs, oldHeight, newHeight) -> {
            if (!isResizing) {
                isResizing = true;
                // 同步宽度为当前高度,保持1:1比例
                stage.setWidth(newHeight.doubleValue());
                isResizing = false;
            }
        };
        stage.heightProperty().addListener(heightListener);

        // 初始化窗口大小
        stage.setWidth(length);
        stage.setHeight(length);
        stage.show();
    }
}

关键说明

  • isResizing标志位确保当我们主动设置width/height时,不会触发另一个方向的监听器,彻底避免循环触发的问题
  • 拖动窗口时,width或height的变更会立刻同步另一个维度的大小,实现实时的1:1比例锁定,不会出现闪烁
  • 无需移除/重新添加监听器,逻辑更简洁可靠

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 15:33:12