获取窗口的当前标题栏和边框大小并操作屏幕截图图像

时间:2012-07-09 15:05:30

标签: java swing

我正在尝试Java和GUI操作,我有一个自定义对话框,创建自jPanel富有想象力的 DLog ,根据请求收集用户输入。这工作正常,但当然我的对话框不是模态的,这使得对话框打开时其余控件可供用户访问。一点都不好!

为了解决这个问题,我有一个单独的jPanel名为 DLogCover ,它与窗口大小不同,但在需要之前是不可见的。当显示自定义对话框时,我的窗口的屏幕截图被显示为 DLogCover 上的标签中的图像,该标签显示在我的自定义对话框下方,但高于其他所有内容(在{{1}上) } MODAL_LAYER - 自定义对话框显示在jLayeredPanel上。这完全符合计划,尽管我希望你可以帮助解决两个问题。

首先,屏幕截图当然包括窗口的标题栏和左边框。我使用任意数字考虑到这一点,这对我来说当然很有用,但当然每个操作系统都会有所不同,因为我使用的是系统外观和感觉,这些尺寸可能不正确。

问题:有没有办法确保我的屏幕截图只是我窗口的内部内容(或任何方式总是得到标题栏和窗口边框的正确尺寸,不管OS)?

其次,虽然我的截图工作得很好但它只是一个窗口的图像,我想让它略微褪色或模糊,以使其看起来实际上有一些覆盖控件。

问题:有没有办法操纵图像来呈现这种外观?

以下是我用来捕获图像并显示它的代码(在显示自定义对话框之前):

POPUP_LAYER

非常感谢你能给予的任何帮助,和以前一样,我这样做的原因是因为我正在努力学习DLOGCover.setVisible(true); Point pos = this.getLocationOnScreen(); Dimension dim = this.getSize(); //Arbitrary sizes! These need to be discovered and set correctly! int xLoc = pos.x +1 ; int yLoc = pos.y + 11; try { Robot robot = new Robot(); Rectangle captureSize = new Rectangle(xLoc, yLoc, dim.width, dim.height); BufferedImage bImage = robot.createScreenCapture(captureSize); Image imgwork = (Image)bImage; ImageIcon labelimg = new ImageIcon(imgwork); imageLabel.setIcon(labelimg); } catch(AWTException e) { System.err.println("Ouch!"); } //... show the custom dialog 所以我正在尝试,目前正是这个!

非常感谢你能给予的任何帮助,当然我愿意接受有关实现同样事情的替代方法的建议。

一些答案​​

我想添加此信息,以便任何其他来看的人都可以找到它。

感谢Andrew Thompson的代码(非常感谢nIcE cOw的链接)我现在可以获得我的窗口内容的屏幕截图,无需尝试编制标题栏和边框大小:

Java

当我打开自定义对话框时调用它,然后我可以将图像修改为变暗并将其模糊一点,然后将其显示在我的自定义 DLogCover public static BufferedImage getScreenShot(Component component) { BufferedImage image = new BufferedImage( component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB ); // call the Component's paint method, using // the Graphics object of the image. component.paint( image.getGraphics() ); return image; } 中>(图片只是jLabeljPanel):

jLabel

然后我需要阻止鼠标和键事件与主窗口上的控件交互,这些控件目前仍然可以访问,即使它们被图像隐藏了。我试图使用以下代码执行此操作,但这似乎只阻止鼠标事件:

//get the screenshot
BufferedImage bufferedImage = getScreenShot( this.getContentPane() );

//blur and darken the image slightly
Kernel myKernel = new Kernel(3, 3,new float[] {1f/9f, 1f/9f, 1f/9f,1f/9f, 1f/9f, 1f/9f,1f/9f, 1f/9f, 1f/9f});
BufferedImageOp myOp1 = new ConvolveOp(myKernel);
bufferedImage = myOp1.filter(bufferedImage, null);
RescaleOp myOp2 = new RescaleOp(.6f, 0, null);
bufferedImage = myOp2.filter(bufferedImage, null);

//prepare the image to be shown in a `jLabel`
Image Conv1 = (Image)bufferedImage;
ImageIcon Conv2 = new ImageIcon(Conv1);
myLabel.setIcon(Conv2);

Iv尝试了各种控件代替myLabel.addMouseListener(new MouseAdapter() {}); myLabel.addMouseMotionListener(new MouseMotionAdapter() {}); myLabel.addKeyListener(new KeyAdapter() {}); ,但效果相同:鼠标被阻止但键不是。这是一个问题,因为应用程序中的一个主要元素是jLabel,绝对不允许接受无关的键输入。

为了简单起见,我正在根据需要打开和关闭可编辑属性,以防止意外键入文本窗格,但这是一个非常多的解决方法,因为在某些时候我可能会分配键盘加速器而且我不会t希望在自定义对话框打开时意外激活它们。

如果有任何进一步的建议可以防止任何键盘事件在自定义对话框打开时触及基础控件,我非常想听听它们。

问候

MVK

1 个答案:

答案 0 :(得分:1)

我强烈建议你看看JXLayer项目。它完全符合您的要求。

另外,请查看http://www.jhlabs.com/ip/filters/index.html处的JHLabs-Filters。

如果你仍然弯腰,你可以抓住内容窗格的大小,然后从主框架的高度中减去它。这应该(通常)给你你想要的结果。

您需要执行类似

的操作
Point pos = ((JComponent)frame.getContentPane()).getLocationOnScreen();
Point fPos = frame.getLocation();

这将允许您计算框架内的内容窗格的偏移量,您可以从中进行调整。

就个人而言,我只是看看JXLayer。

沙恩

<强>更新

好的,艰难的。所以你有一个屏幕截图。你会想要按照我上面的建议修剪框架的边框。

使用JHLabs-Filters,您可以按如下方式模糊图像

GaussianFilter gf = new GaussianFilter(10);
imgBG = gf.filter(imgBG, null);

要完成鼠标事件处理程序,您将需要使用“玻璃窗格”。这只是一个可以放在框架顶部的组件,将一个鼠标监听器(和一个关键监听器)连接到它上面,它们应该为你“消耗”这些事件。

查找JFrame.getGlassPane()。基本上,您需要添加用于绘制背景的组件(并将对话框置于其上)(不要忘记使其可见)。

这可能会帮助您解决此问题http://www.java2s.com/Code/Java/Swing-JFC/Showhowaglasspanecanbeusedtoblockmouseandkeyevents.htm

希望有所帮助 沙恩