如何修复GraphicsEnvironment.getRefreshRate()返回错误刷新率的问题
Java获取Linux显示器刷新率错误问题排查与修复
问题现象
在配备单台165Hz显示器的Manjaro台式机上,通过Java GraphicsEnvironment类获取主显示器刷新率时返回50,而非正确的165;但在搭载60Hz显示器的Linux Mint笔记本上结果正常。
测试代码
import java.awt.GraphicsEnvironment; class FileName { public static void main(String[] args) { int hrz = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDisplayMode().getRefreshRate(); System.out.println(hrz); } }
运行输出
[shringe@dashingkoso Refresh-Rate]$ javac FileName.java [shringe@dashingkoso Refresh-Rate]$ java FileName 50 [shringe@dashingkoso Refresh-Rate]$
系统显示模式确认(xrandr -q输出)
DP-0 connected primary 2560x1440+0+0 (normal left inverted right x axis y axis) 597mm x 336mm 2560x1440 59.95 + 165.00* 160.00 155.00 143.97 120.00 1920x1080 119.88 100.00 60.00 59.94 50.00 1440x900 59.89 1440x576 50.00 1280x1024 75.02 60.02 1152x864 75.00 1024x768 75.03 70.07 60.00 800x600 75.00 72.19 60.32 56.25 640x480 75.00 72.81 59.94
原因分析
- Java AWT的
getRefreshRate()方法在Linux环境下依赖X11的旧接口实现,这类接口对高刷新率显示器的支持存在缺陷,可能错误读取非当前激活模式的参数(比如误取了1080p分辨率下的50Hz值)。 - Manjaro搭配的桌面环境(如KDE/GNOME)与显卡驱动的组合,可能导致AWT无法正确同步显示器的实际运行模式,尤其是当显示器支持多档刷新率选项时。
修复方法
1. 解析xrandr命令输出
直接调用系统xrandr -q命令,解析带*标记的当前激活模式刷新率,绕过AWT的局限性:
import java.io.BufferedReader; import java.io.InputStreamReader; class RefreshRateFix { public static void main(String[] args) { try { Process process = Runtime.getRuntime().exec("xrandr -q"); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = reader.readLine()) != null) { if (line.contains("primary") && line.contains("*")) { String[] parts = line.split("\\s+"); for (String part : parts) { if (part.contains("*")) { String rateStr = part.replace("*", ""); int rate = (int) Math.round(Double.parseDouble(rateStr)); System.out.println(rate); break; } } break; } } reader.close(); } catch (Exception e) { e.printStackTrace(); } } }
2. 使用JavaFX的Screen API
JavaFX的Screen类对Linux显示器的兼容性更好,能正确读取当前刷新率:
import javafx.stage.Screen; class FXRefreshRate { public static void main(String[] args) { double rate = Screen.getPrimary().getRefreshRate(); System.out.println((int) Math.round(rate)); } }
注意:运行JavaFX代码需确保环境包含JavaFX库,或采用模块化编译运行方式。
3. 升级JDK版本
部分旧版本JDK的AWT实现存在该bug,升级至最新的OpenJDK或Oracle JDK版本,可能已修复Linux下高刷新率识别问题。
内容的提问来源于stack exchange,提问作者Shringe_
相关产品推荐
相关产品推荐

