[英]Get the current titlebar and border size of my window and manipulate screenshot image
我正在尝试使用Java
和GUI进行操作,并且有一个自定义对话框,该对话框是从jPanel
创建的,该jPanel
富有想象力,称为DLog ,应要求收集用户输入时出现。 这很好用,但是我的对话框当然不是模态的,当对话框打开时,其余的控件对用户可见并可以访问。 一点都不好!
为了克服这一点,我有一个单独jPanel
称为DLogCover与窗口大小,但直到需要它是无形的。 当显示自定义对话框时,会截取我的窗口的屏幕截图,并将其显示为DLogCover上标签中的图像,该标签显示在我的自定义对话框下方,但在所有其他内容上方(在MODAL_LAYER
的jLayeredPanel
-自定义对话框显示在POPUP_LAYER
)。 尽管有两个小问题,我希望您可能会有所帮助,但这完全按计划进行。
首先,屏幕截图当然包括标题栏和窗口的左边框。 我已经考虑了使用任意数字的可能性,这些数字现在对我有用,但是当然在每个OS上这都是不同的,因为我使用的是系统外观,并且这些大小可能不正确。
问题 :有什么方法可以确保我的屏幕截图仅是窗口的内部内容(还是任何方式,无论操作系统如何,总能获得正确的窗口标题栏和边框大小)?
其次,尽管我的屏幕截图可以正常工作,但它只是窗口的图像,并且我希望使其略微褪色或模糊,以使其看起来实际上覆盖了控件。
问题 :是否有任何方法可以处理图像以使外观看起来如此?
这是我用来捕获图像并显示它的代码(在显示自定义对话框之前):
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
非常感谢您可以提供的任何帮助,并且像以前一样,我这样做的原因是因为我正在尝试学习Java
因此我正在进行实验,目前就是这样!
非常感谢您可以提供的任何帮助,当然,我乐于接受有关实现同一目标的替代方法的建议。
我想添加此信息,以便任何其他正在寻找的人都可以找到它。
多亏了安德鲁·汤普森(Andrew Thompson)的代码(非常感谢链接的nIcE cOw),我现在才能获得我的窗口内容的屏幕截图,而无需尝试计算标题栏和边框大小:
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;
}
当我打开我的自定义对话框这就是所谓的,我再能修改图像变暗和模糊了一点,然后在显示它jLabel
指只存在于我的自定义DLogCover(这仅仅是一个jPanel
和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);
然后,我需要防止鼠标和键事件与主窗口上的控件进行交互,尽管这些控件被图像隐藏了,但这些控件目前仍可访问。 我正在尝试使用以下代码执行此操作,但这似乎仅阻止了鼠标事件:
myLabel.addMouseListener(new MouseAdapter() {});
myLabel.addMouseMotionListener(new MouseMotionAdapter() {});
myLabel.addKeyListener(new KeyAdapter() {});
iv尝试使用各种控件代替jLabel
但具有相同的效果:鼠标被锁定,但键未被锁定。 这是一个问题,因为该应用程序中的主要元素之一是jTextPane
,绝对不允许该jTextPane
接受无关的按键输入。
为了简便起见,我现在根据需要打开和关闭可编辑属性,以防止意外在文本窗格中键入内容,但这是一种解决方法,因为有时我可能已分配了键盘加速器,但我不希望它们当自定义对话框打开时被意外激活。
如果有人在打开自定义对话框时有任何其他建议来防止任何键盘事件到达基础控件,那么Id非常希望听到它们。
问候
MVK
我强烈建议您看一下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/Showhowaglasspane可以用于blockmouseandkeyevents.htm
希望能帮助Shane
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.