此实用程序应用程序通过按JFrame上的按钮获取多个监视器的屏幕截图。该方法的预期逻辑如下:
即使最终的“返回框架可见”步骤已从代码中注释掉,让我在执行后看不到屏幕上的框架,框架在屏幕截图中可见。我不知道为什么。
使用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;
}
答案 0 :(得分:1)
这不是一个明确的答案,但也许它会指出你正确的方向。
我遇到类似的问题,要求JFrame使用OpenGL在3D应用程序上全屏显示。
我假设发生的事情是frame.setVisible()与OS窗口管理器对话,请求隐藏(或显示)窗口。一旦发出请求并确认,方法调用就不再阻塞,invokeAndWait()中的线程现在完成了调用和等待。
您的代码将继续截屏,但不保证操作系统实际上已经处理了最小化Window的请求。在你的情况下,似乎没有。
解决方案(也许?): 看起来Java有一个名为WindowEvent doc here的类。您应该能够在等待状态更新的屏幕截图调用之前创建侦听器和/或循环。请注意该文档具体说:
窗口已停用的事件类型。当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;
}