0

在通过按下部署到 a 中的按钮执行的操作(即方法)中JFrame,我想隐藏 java 应用程序,然后获取屏幕截图。最后,一旦截取屏幕截图,我需要使其JFrame可见。

方法如下:

  public void myButtonPressedAction(){
       //Hiding the JFrame
       this.setVisible(false);
       //Now I use Robot to get a screenshot using another method
       //not reported for simplicity
       myMethodToGetScreenshot();
       //Making the JFrame visible
       this.setVisible(true);
  }

发生的情况是,一旦可见性设置为 false,应用程序开始变得不可见,我立即得到屏幕截图:不幸的是,屏幕截图还捕获了JFrame淡出时(即,它将变得不可见,isVisible方法返回true,但是JFrame不是完全不可见的)。

一种可能的解决方案是插入一个计时器,以在对 的调用setVisible(false)和对的调用之间设置延迟myMethodToGetScreenshot()。但是,假设系统很忙,延迟可能会被低估;相反,较大的延迟会使我的应用程序变慢!

我怎样才能获得JFrame完全淡出的确切时间,即它真的不可见?

编辑

这在构造函数中初始化:

String myPath= ...;//here I have a String that represent a path to a folder.
JPEGImageWriteParam JPEG_PARAMS_BEST_QUALITY = new JPEGImageWriteParam(null);
JPEG_PARAMS_BEST_QUALITY.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
JPEG_PARAMS_BEST_QUALITY.setCompressionQuality(1f);

这是代码 myMethodToGetScreenshot()

public void  myMethodToGetScreenshot(){
  BufferedImage capture = new Robot().createScreenCapture(screenArea);
  ImageWriter writer = writerService.getWriter();
  writer.setOutput(new FileImageOutputStream(new File(myPath+"screenshot.jpg")));
  writer.write(null, new IIOImage(capture, null, null), JPEG_PARAMS_BEST_QUALITY);
}

这是我得到的截图。你可以看到 JFrame 淡出...

在此处输入图像描述

4

4 回答 4

3

然后放一些延迟时间。您可以使用Swing 计时器

这是一个小演示:

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class ScreenshotDemo {
    JFrame frame = new JFrame();
    JButton button = new JButton("Catch the screenshot");
    Timer timer;
    Robot robot;
    JLabel label = new JLabel();

    public ScreenshotDemo() {
        try {
            robot = new Robot();
        } catch (AWTException e1) {
            e1.printStackTrace();
        }

        // Keeps frame disposed for 3 seconds
        timer = new Timer(3000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Rectangle size = new Rectangle(Toolkit.getDefaultToolkit()
                        .getScreenSize());
                Image image = robot.createScreenCapture(size);
                label.setIcon(new ImageIcon(image));
                frame.setVisible(true);
            }
        });
        timer.setRepeats(false);

        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                frame.setVisible(false);
                timer.start();
            }
        });

        frame.add(button, BorderLayout.NORTH);
        frame.add(label, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        // frame.pack();
        frame.setSize(1024, 768);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ScreenshotDemo();
            }
        });
    }

}

基本上,您将隐藏您的框架一段时间(在此演示中为 3 秒)。当框架被隐藏时,您将拍摄快照。

于 2013-06-19T09:52:10.490 回答
2

而不是setvisible你可以使用setExtendedState

//Minimize the JFrame
this.setExtendedState(JFrame.ICONIFIED);
//Now I use Robot to get a screenshot using another method
//not reported for simplicity
myMethodToGetScreenshot();
//Restore the JFrame
this.setExtendedState(JFrame.NORMAL);
于 2013-06-19T09:48:28.013 回答
1

您必须在隐藏框架之后和截取屏幕截图之前添加一个合理的延迟。最简单的方法是插入对robot.delay()before的调用robot.createScreenCapture()

于 2013-06-19T10:10:08.813 回答
0

我会给ComponentListener一个尝试(假设此代码转到 JFrame 扩展类的成员):

    final Container contentPane = getContentPane();
    ComponentAdapter componentAdapter = new ComponentAdapter() {

        @Override
        public void componentHidden(ComponentEvent arg0) {
            myMethodToGetScreenshot();
            contentPane.removeComponentListener(this);
        }
    };
    contentPane.addComponentListener(componentAdapter);
于 2013-06-19T10:09:11.977 回答