createScreenCapture() 必须传入 Rectangle,所谓“全屏”需动态计算屏幕区域:单屏用 getMaximumWindowBounds()(适配DPI),多屏需遍历 GraphicsDevice 合并 getBounds(),并注意跨平台差异与线程安全。

createScreenCapture() 要求传入 Rectangle,不能直接“全屏”
Robot.createScreenCapture() 本身不提供无参重载或“全屏”快捷方法。它只接受一个 Rectangle 参数,表示要截取的屏幕区域坐标和尺寸。所谓“全屏”,本质是构造一个覆盖当前主屏幕(或所有屏幕)的 Rectangle。
常见错误是直接写 new Rectangle(0, 0, 1920, 1080) —— 这在多显示器、缩放(如 Windows 125% DPI)、高分屏(如 macOS Retina)下必然截错或截不全。
- 用
GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds()获取**逻辑屏幕边界**(已考虑 DPI 缩放),适合单屏主流场景 - 若需多屏拼接截图,必须遍历
GraphicsDevice,对每个设备调用getBounds()并手动合并矩形(注意:跨屏坐标系是连续的,但需按实际布局偏移) - 避免硬编码分辨率;
Toolkit.getDefaultToolkit().getScreenSize()返回的是未缩放的像素尺寸,在高 DPI 系统上会严重失真
多屏环境下容易只截到主屏,漏掉扩展屏
默认调用 getMaximumWindowBounds() 或 getScreenSize() 都只反映主显示器信息。如果你的程序运行在副屏上,或者用户把窗口拖到了扩展屏,而你仍用主屏尺寸截图,结果就是——画面空白或只有一角。
正确做法是明确区分“当前活跃屏幕”还是“全部物理屏幕”:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 要截当前鼠标所在屏:先用
MouseInfo.getPointerInfo().getLocation()拿坐标,再遍历GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()找到包含该坐标的GraphicsDevice,再取其getBounds() - 要截所有屏幕拼成一张大图:收集所有
GraphicsDevice的getBounds(),算出最小左上角和最大右下角,构造总Rectangle,再创建目标BufferedImage,逐设备createScreenCapture()后用Graphics2D.drawImage()合并 - 注意:Linux X11 下多屏可能共用一个
GraphicsDevice,此时getBounds()已是总区域,重复遍历会出错
截图后保存为 PNG 时中文路径或特殊字符会报 java.io.FileNotFoundException
这不是 createScreenCapture() 的问题,但几乎每个第一次用的人会卡在这儿:ImageIO.write() 底层依赖文件系统路径解析,而 FileOutputStream 在 Windows 上对含中文、空格、括号的路径处理脆弱。
- 不要直接拼接字符串路径,改用
Paths.get("截图_2024.png")构造Path,再传给Files.newOutputStream() - 更稳妥:用
ImageIO.write(bufferedImage, "png", new FileOutputStream(path.toFile()))仍是错的;应改用ImageIO.write(bufferedImage, "png", Files.newOutputStream(path)) - 如果路径来自用户输入(比如 JFileChooser),务必用
path.toAbsolutePath().normalize()清理 . 和 .. - 别忽略异常:
IOException可能因磁盘满、权限不足、父目录不存在引起,Files.createDirectories(path.getParent())要前置
性能与线程安全:Robot 实例不能共享,且截图会阻塞调用线程
Robot 不是线程安全类,多个线程共用同一个实例可能引发 IllegalThreadStateException 或截出花屏。同时,createScreenCapture() 是同步操作,耗时取决于屏幕分辨率和 GPU 驱动,1080p 通常 20–50ms,4K 可能超 100ms。
- 每次截图都应新建
Robot实例(轻量,无显著开销),或至少确保单线程独占使用 - 不要在 JavaFX 主线程或 Swing EDT 中直接调用;应丢进
Executors.newSingleThreadExecutor()异步执行,完成后用Platform.runLater()或SwingUtilities.invokeLater()更新 UI - 频繁截图(如录屏)需加帧率控制:用
System.nanoTime()计算间隔,避免无节制调用压垮 GUI 线程
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










