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

org.eclipse.swt.widgets.Monitor获取第二台显示器数据值异常求助

问题

我想要获取所有显示器的尺寸和缩放比例,编写了如下ApplicationMonitorsManager代码:

package root.viewer.rcp.util;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.ui.PlatformUI;

public class ApplicationMonitorsManager
{
  public Monitor[] monitors;
  //public Display display = new Display();
  
  public ApplicationMonitorsManager()
  {
    
  }
  
  public Monitor[] getMonitors()
  {
    //Display display = Display.getCurrent();
    Display display = PlatformUI.createDisplay();
    monitors = display.getMonitors();
    return monitors;
  }
}

主显示器返回的数据正确:

clientHeight    2070    
clientWidth 3840    
clientX 0   
clientY 0   
handle  200823  
height  2160    
width   3840    
x   0   
y   0   
zoom    225 

第二台显示器与主显示器分辨率相同,但缩放比例为125%,获取到的数据却异常:

clientHeight    3798    
clientWidth 6912    
clientX 6912    
clientY 0   
handle  200517  
height  3888    
width   6912    
x   6912    
y   0   
zoom    225 

尝试使用Display display = Display.getCurrent()或Display display = PlatformUI.createDisplay()均无效果,使用Display display = new Display()时应用会崩溃,抛出SWTException: Invalid thread access异常。


问题分析与解决

核心问题原因

  • 错误创建Display实例:PlatformUI.createDisplay()会生成新的Display实例,而非复用RCP应用已绑定UI线程的Display。新实例无法正确识别系统多显示器的DPI缩放配置,导致第二台显示器的尺寸被错误套用主显示器的缩放比例计算,出现异常数值。
  • 线程访问限制:SWT规定所有UI操作必须在UI线程执行,new Display()在非UI线程调用会直接触发Invalid thread access异常;Display.getCurrent()在非UI线程调用会返回null,同样无法正常获取显示器数据。

正确实现方案

  1. 复用已有Display实例:在RCP应用中,通过PlatformUI.getWorkbench().getDisplay()获取应用主Display,该实例已绑定UI线程,能正确读取所有显示器的DPI缩放配置。
  2. 确保UI线程执行:如果需要在非UI线程获取显示器数据,必须通过Display.syncExec()或asyncExec()将操作切换到UI线程执行。

修改后的代码示例:

package root.viewer.rcp.util;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.ui.PlatformUI;

public class ApplicationMonitorsManager
{
  public Monitor[] getMonitors()
  {
    // 获取RCP应用已有的UI线程Display
    Display display = PlatformUI.getWorkbench().getDisplay();
    if (display == null || display.isDisposed()) {
        throw new IllegalStateException("无法获取有效的UI Display实例");
    }
    return display.getMonitors();
  }
}

额外说明

  • Monitor.getZoom()返回的是缩放比例的千分比(比如225代表225%,125代表125%),转换为百分比时除以10即可。
  • 获取显示器区域时,要区分getBounds()(包含任务栏的整个屏幕区域)和getClientArea()(可用工作区域),按需选择对应方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:20:06