【问题标题】:Get the current titlebar and border size of my window and manipulate screenshot image获取我的窗口的当前标题栏和边框大小并操作截图图像
【发布时间】:2012-07-09 00:21:15
【问题描述】:

我正在尝试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;
}

当我打开我的自定义对话框时会调用它,然后我可以修改图像以使其变暗并稍微模糊,然后将其显示在我的自定义 DLogCover 上存在的 jLabel 中(这只是图像的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() {});

我尝试了各种控件来代替jLabel,但效果相同:鼠标被阻止但按键没有。这是一个问题,因为应用程序中的主要元素之一是jTextPane,绝对不允许它接受无关的键输入。

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

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

问候

MVK

【问题讨论】:

  • 请看看@AndrewThompson 的这个精彩的example :-)。但是如何为图像添加效果超出了我的知识范围,因此无法阐明该主题:(。此线程包含一些simple examples
  • 感谢nIcE cOw,安德鲁斯代码成功获得了我需要的图像(减去边框和标题栏等),但现在又打开了另一个蠕虫罐!我会更新我的问题以反映这一点。非常感谢您的链接。
  • 你很受欢迎,保持微笑:-)

标签: java swing


【解决方案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

希望有所帮助 谢恩

【讨论】:

  • 感谢 Shane,我已经找到了该网站,并且我同意它可以满足我的要求,但是我真的宁愿先以艰难的方式做到这一点,以便我了解所涉及的内容。一旦我达到那个阶段,我会很乐意使用额外的资源让生活更轻松!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-29
  • 2014-02-04
  • 1970-01-01
  • 2015-10-16
  • 2023-03-17
  • 1970-01-01
相关资源
最近更新 更多