显示器选择与边界计算
基本信息
| 属性 | 值 |
|---|---|
| 核心方法 | ClientProxy#getAppropriateScreenBounds(Rectangle, int) |
| 监视器索引基数 | 1 起(findScreenDimensionsByID 用 screens[monitorID - 1]) |
| 自动选择哨兵 | Reference.AUTOMATIC_MONITOR_SELECTION = 0 |
| 取显示器信息的方式 | java.awt.GraphicsEnvironment#getScreenDevices(),不是 LWJGL |
分支优先级
方法是一条 if / else-if 链,先到先得:
| 顺序 | 条件 | 结果 |
|---|---|---|
| 1 | advanced 且 onlyRemoveDecorations |
直接用 currentCoordinates,不 resize 也不移动 |
| 2 | advanced 且 customFullscreenDimensions 且 H > 256 且 W > 256 |
自定义矩形 |
| 3 | desiredMonitor < 0 或 == 0 |
按窗口中心点落在哪块屏来选 |
| 4 | 其余(指定了 ≥ 1 的屏号) | 按屏号取;取不到则退回分支 3 |
分支 1 因 onlyRemoveDecorations 恒为 false 而是死代码,
详见 配置项 的"第 10 个配置项从未写入"。
自动模式:按窗口中心点判断
findCurrentScreenDimensionsAndPosition(x, y) 遍历 getScreenDevices(),
返回第一个 bounds.contains(x, y) 的显示器。传入的 (x, y) 是当前窗口矩形中心:
Point centerCoordinates = new Point(
(int) (currentCoordinates.getMinX() + currentCoordinates.getWidth() / 2),
(int) (currentCoordinates.getMinY() + currentCoordinates.getHeight() / 2));
全部 GraphicsDevice 都不含该点时(Java 报告不出匹配屏),退回 LWJGL 的
Display.getDesktopDisplayMode() 宽高,并假定原点为 (0, 0)。
自定义尺寸:X/Y 是相对偏移
分支 2 生效需要同时满足四项:advanced 总开关开、自定义总开关开、
W > 256 且 H > 256。只有宽高都过 256 才生效,缺一不可。
选中屏号(desiredMonitor > 0)时,X/Y 会被解释为相对该屏原点的偏移:
screenBounds.setLocation(actualScreenBounds.x + screenBounds.x,
actualScreenBounds.y + screenBounds.y);
desiredMonitor == 0(自动)时则直接用配置里的 X/Y 绝对值。
语言文件的描述与此一致:X 为"主显示器最左像素列"或"所选显示器最左像素列"。
屏号取不到时的降级
findScreenDimensionsByID 有三重保护,任一命中返回 null:
monitorID < 1→null(所以屏号 0 和负数都进不了这条路径);screens == null || screens.length == 0→null;screens.length < monitorID→null(越界)。
null 会让分支 4 退到分支 3 的自动选择——即"指定了但没接上,就当成自动"。
与分支 2 的交互盲点
desiredMonitor > 0 才会走"取实际屏原点做偏移"这一步,但取原点的
findScreenDimensionsByID(desiredMonitor) 可能返回 null;
源码对这里的 null 做了判断(if (actualScreenBounds != null)),
只是不施加偏移——窗口会落在绝对 X/Y 上,语义与注释里的"相对偏移"不符。