java - JFrame 不会及时消失以进行屏幕截图

标签 java swing

此实用程序应用程序通过按 JFrame 上的按钮来获取多个监视器的屏幕截图。该方法的预期逻辑如下:

  • 创建新的矩形来表示所有监视器边界的联合
  • 使用 InvokeAndWait 隐藏到 JFrame,并确保在进一步处理之前将其隐藏
  • 使用 Robot 类截取屏幕截图
  • 再次将框架设置为可见并返回图像

即使最后的“将框架返回可见”步骤在代码中被注释掉,执行后我在屏幕上看不到任何框架,但该框架在屏幕截图中是可见的。我不知道为什么。

使用 print 语句,我确定在截取屏幕截图之前确实会触发使 JFrame 不可见的方法。我还尝试在截图之前使用 if 语句检查 JFrame 是否可见,并且 if 语句从未被触发。

有什么办法可以解决这个问题吗?

public Image capture(ArrayList<Monitor> monitors) {

    Rectangle bounds = new Rectangle();
    monitors.stream().forEach(a -> Rectangle.union(bounds, a.getBounds(), bounds) );

    Image image = null;

    try {

        EventQueue.invokeAndWait(() ->  {
            frame.setVisible(false);
            System.out.println("Set frame invisible");
        });

    } catch (Exception ex) {
        ex.printStackTrace();
    }

    try {

        image = new Image(new Robot().createScreenCapture(bounds));

    } catch (Exception ex) {
        ex.printStackTrace();           
    }

    //frame.setVisible(true);
    return image;
}

最佳答案

这不是一个明确的答案,但也许它会为您指明正确的方向。

我遇到了类似的问题,需要 JFrame 在使用 OpenGL 的 3D 应用程序上全屏显示。

我假设正在发生的是,frame.setVisible() 与操作系统窗口管理器对话,请求隐藏(或显示)窗口。一旦发出并确认请求,方法调用就不再阻塞,invokeAndWait() 中的线程现在已完成调用和等待。

您的代码将继续进行屏幕截图,但不能保证操作系统实际处理了最小化窗口的请求。就您而言,似乎并非如此。

解决方案(也许?): 看起来 Java 有一个名为 WindowEvent 文档 here 的类。您应该能够在等待状态更新的屏幕截图调用之前创建监听器和/或循环。请注意该文档特别指出:

The window-deactivated event type. This event is delivered when the Window is no longer the active Window. Only a Frame or a Dialog can be the active Window. The native windowing system may denote the active Window or its children with special decorations, such as a highlighted title bar. The active Window is always either the focused Window, or the first Frame or Dialog that is an owner of the focused Window.

我怀疑等待 WINDOW_DEACTIVATED 和/或 WINDOW_LOST_FOCUS 可能是窗口是否已被操作系统窗口管理器最小化的实际指示器。​​

再说一遍,我的这篇文章是基于我几个月前从事的一个几乎不相关的项目,但希望其中一些能有所帮助。

更新

OP实现了如下解决方案:

public Image capture(ArrayList<Monitor> monitors) 
{

    Rectangle bounds = new Rectangle();
    monitors.stream().forEach(a -> Rectangle.union(bounds, a.getBounds(), bounds) );

    Image image = null;

    try 
    {

        EventQueue.invokeAndWait(() -> frame.setExtendedState(Frame.ICONIFIED));

        while (frame.getExtendedState() != Frame.ICONIFIED) { }
        image = new Image(new Robot().createScreenCapture(bounds));

    } 
    catch (Exception ex) 
    {
        ex.printStackTrace();           
    }

    EventQueue.invokeLater(() -> frame.setExtendedState(Frame.NORMAL));

    return image;
}

关于java - JFrame 不会及时消失以进行屏幕截图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28593362/

相关文章:

java - Spring Framework 4.3.0 - 我什么时候需要@Autowired?

java - Netbeans 7.2 启动时报告错误

java - JTable:如何获取表的更新列和行?

java - 如何在 OS X 上的 Swing 中启用 LCD 子像素抗锯齿?

java - 更改 JLabel 的文本 - 初学者

java - 如何在不使用 HTML 的情况下向 JLabel 添加换行符

java - Apache POI : API to identify tables in the excel sheet and read them

java - 如何暂停 main()

java - Struts2 触发表在完成时加载

java - 在 java 中首次运行时设置变量