此实用程序应用程序通过按 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/