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

标签 java swing

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

为了克服这个问题,我有一个单独的 jPanel称为 DLogCover,它与窗口大小一致,但在需要之前是不可见的。当显示自定义对话框时,我的窗口的屏幕截图被截取并显示为 DLogCover 上标签中的图像,该图像显示在我的自定义对话框下方,但高于其他所有内容(在 MODAL_LAYERjLayeredPanel 上 - 自定义对话框出现在 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

非常感谢您提供的任何帮助,和以前一样,我这样做的原因是因为我正在努力学习 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 上(只是图像的 jPaneljLabel):
//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绝对不允许它接受无关的键输入。

为简单起见,目前我正在根据需要打开和关闭可编辑属性,以防止意外键入文本 Pane ,但这在很大程度上是一种解决方法,因为在某些时候我可能分配了键盘加速器并且我不想要它们打开自定义对话框时意外激活。

如果有人有任何进一步的建议来防止在自定义对话框打开时任何键盘事件到达底层控件,我非常希望听到它们。

问候

MVK

最佳答案

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

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

如果您仍然一头雾水,您可以获取内容 Pane 的大小并从主框架的高度中减去它。这应该(通常)给你你想要的结果。

你需要做类似的事情

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

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

就个人而言,我只想研究 JXLayer。

谢恩

更新:

好吧,艰难的路。所以你已经捕获了屏幕。正如我上面建议的那样,您将需要修剪框架的边框。

使用 JHLabs-Filters,可以对图像进行如下模糊处理
GaussianFilter gf = new GaussianFilter(10);
imgBG = gf.filter(imgBG, null);

要完成鼠标事件处理程序,您将需要使用“玻璃 Pane ”。这只是一个您可以放置​​在框架顶部的组件,将鼠标监听器(和键监听器)附加到它,它们应该为您“使用”事件。

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

这可能会对您在这方面有所帮助http://www.java2s.com/Code/Java/Swing-JFC/Showhowaglasspanecanbeusedtoblockmouseandkeyevents.htm

希望有帮助
谢恩

关于java - 获取我的窗口的当前标题栏和边框大小并操作截图图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11397817/

相关文章:

java - JPanel 作为 TableCellEditor 消失

java - 使用新数据刷新 JEditorPane

java - 渲染等距网格

java - 无法使用 IBM Rational Application Developer 将 WAR 文件部署到 Websphere

java - 获取游戏中对象的位置

适用于桌面和移动设备的 Java 单一代码库

java - 如何在 JTextPane 中嵌入可调整大小的 JPanel?

Java : detect triple-click without firing double-click

Java matcher.matches() 在应该为真时返回 false

java - 使用java访问cleverbot