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

如何让JavaFX识别当前屏幕是4K还是1080P?

嘿,这个问题我之前折腾过好一阵,咱们来理清楚到底是怎么回事~

首先,你拿到的两个DPI值都没错,只是它们代表的含义完全不同:

  • Screen.getPrimary().getDpi() 是JavaFX提供的逻辑DPI,也就是系统的基准DPI(通常Windows默认是96,Mac是72),它不受系统缩放设置的影响,是JavaFX用来计算界面元素大小的参考值。
  • Toolkit.getDefaultToolkit().getScreenResolution() 是AWT的API,返回的是物理DPI,是根据屏幕的实际像素数和物理尺寸计算出来的(比如15寸1080P屏幕的DPI大概是141,27寸4K屏幕大概是163)。

但其实,你要检测1080P/4K来调整程序尺寸和位置,依赖DPI并不是最优方案——因为同样是1080P,不同尺寸的屏幕DPI差异很大,反过来,相同DPI的屏幕也可能是不同的分辨率等级。

更靠谱的方案:直接获取屏幕物理像素尺寸

JavaFX的Screen类提供了足够的信息,结合缩放因子就能准确拿到屏幕的物理像素:

  1. 先获取主屏幕的逻辑尺寸和缩放因子
  2. 用逻辑尺寸乘以缩放因子,得到实际的物理像素宽高
  3. 根据物理像素判断是1080P(1920×1080)、4K(3840×2160)还是其他等级

给你个完整的示例代码,直接就能跑:

import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.stage.Screen;
import javafx.stage.Stage;

public class ScreenAdjustDemo extends Application {
    @Override
    public void start(Stage primaryStage) {
        Screen primaryScreen = Screen.getPrimary();
        
        // 1. 获取逻辑屏幕尺寸(系统缩放后的,比如Windows开150%缩放,1920×1080会变成1280×720)
        Rectangle2D logicalBounds = primaryScreen.getBounds();
        // 如果要避开任务栏等系统UI,用getVisualBounds()代替getBounds()
        // Rectangle2D usableBounds = primaryScreen.getVisualBounds();
        
        // 2. 获取系统缩放因子
        double scaleX = primaryScreen.getOutputScaleX();
        double scaleY = primaryScreen.getOutputScaleY();
        
        // 3. 计算物理像素尺寸
        double physicalWidth = logicalBounds.getWidth() * scaleX;
        double physicalHeight = logicalBounds.getHeight() * scaleY;
        
        // 判断分辨率等级
        String resLevel;
        if (physicalWidth >= 3840 && physicalHeight >= 2160) {
            resLevel = "4K";
        } else if (physicalWidth >= 1920 && physicalHeight >= 1080) {
            resLevel = "1080P";
        } else {
            resLevel = "其他分辨率";
        }
        System.out.println("当前屏幕分辨率等级:" + resLevel);
        
        // 4. 调整程序窗口的尺寸和位置(基于逻辑尺寸,JavaFX会自动适配缩放)
        primaryStage.setWidth(logicalBounds.getWidth() * 0.7); // 占屏幕宽度的70%
        primaryStage.setHeight(logicalBounds.getHeight() * 0.7); // 占屏幕高度的70%
        // 窗口居中
        primaryStage.setX((logicalBounds.getWidth() - primaryStage.getWidth()) / 2);
        primaryStage.setY((logicalBounds.getHeight() - primaryStage.getHeight()) / 2);
        
        primaryStage.setTitle("分辨率适配Demo");
        primaryStage.show();
    }

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

额外注意点:

  • 如果程序需要支持多屏幕,记得遍历Screen.getScreens()来获取所有屏幕的信息,而不是只取主屏幕
  • 如果要让窗口不覆盖任务栏、Dock等系统UI,用getVisualBounds()代替getBounds()来计算可用区域

这样就能准确根据屏幕的实际分辨率等级来调整你的程序啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:23:03