不带JFrame的打印屏幕 [英] Print screen without JFrame

查看:86
本文介绍了不带JFrame的打印屏幕的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想拍一张JFrame背后的画面,而不需要JFrame本身.我尝试的方法是关闭窗口,等待一会儿使其完全关闭,然后取出打印屏幕,然后再次打开它.当前的方法不能满足我的需要,因为我需要更频繁地执行此操作,并且等待关闭窗口的时间过多.另外,我不想为此关闭窗口.

I want to take a print screen of what is behind the JFrame, without the JFrame itself. The way I tried was to close the window, wait for a while so it fully closes, then take the print screen and then open it again. The current method is not good for what I need since I need to do it more frequently and waiting for the window to close is too much time. Also, I don't want to close the window for that.

这是我当前的代码:

public class Offscreen {

    private static BufferedImage img;

    public static void main(String[] main)
                throws AWTException, InterruptedException {
        JFrame frame = new JFrame() {
            @Override
            public void paint(Graphics g) {
                if (img != null)
                    // draw print screen
                    g.drawImage(img, 0, 0, null);
            }
        };
        frame.setSize(500, 500);
        frame.setLocation(700, 0);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        frame.setVisible(false);

        Thread.sleep(200);

        // take the picture
        Robot r = new Robot();
        img = r.createScreenCapture(frame.getBounds());

        // show the source again
        frame.setVisible(true);
        // print on destiny
        frame.repaint();
    }
}

推荐答案

假设"您只想捕获活动框架后面的区域(就像您说的那样,不包含框架),然后类似..

"Assuming" you only want to capture the area behind the active frame (and as you say, without the frame), then something like..

import java.awt.AWTException;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class PrintScreen01 {

    public static void main(String[] args) {
        new PrintScreen01();
    }

    private Timer timer;

    public PrintScreen01() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                final PrintPane printPane = new PrintPane();

                final JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(printPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.addComponentListener(new ComponentAdapter() {

                    @Override
                    public void componentMoved(ComponentEvent e) {
                        timer.restart();
                    }

                    @Override
                    public void componentResized(ComponentEvent e) {
                        timer.restart();
                    }

                });
                timer = new Timer(250, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (frame.isVisible()) {
                            takeSnapShot(frame, printPane);
                        }
                    }
                });
                timer.setRepeats(false);
                frame.setVisible(true);
//                takeSnapShot(frame, printPane);
            }
        });
    }

    public void takeSnapShot(JFrame frame, PrintPane pane) {

        Rectangle bounds = new Rectangle(pane.getLocationOnScreen(), pane.getSize());
        frame.setVisible(false);
        new SnapShotWorker(frame, pane, bounds).execute();

    }

    public class SnapShotWorker extends SwingWorker<BufferedImage, BufferedImage> {

        private JFrame frame;
        private PrintPane pane;
        private Rectangle captureBounds;

        public SnapShotWorker(JFrame frame, PrintPane pane, Rectangle bounds) {
            this.frame = frame;
            this.pane = pane;
            captureBounds = bounds;
        }

        @Override
        protected BufferedImage doInBackground() throws Exception {

            Thread.sleep(125);

            BufferedImage snapShot = null;
            try {
                Robot bot = new Robot();
                snapShot = bot.createScreenCapture(captureBounds);
            } catch (AWTException ex) {
                ex.printStackTrace();
            }
            Thread.sleep(125);
            return snapShot;
        }

        @Override
        protected void done() {
            try {
                BufferedImage snapShot = get();
                pane.setSnapShot(snapShot);
                frame.setVisible(true);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            } catch (ExecutionException ex) {
                ex.printStackTrace();
            }
        }



    }

    public class PrintPane extends JPanel {

        private BufferedImage background;

        public PrintPane() {
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        public void setSnapShot(BufferedImage img) {
            background = img;
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (background != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
                g2d.drawImage(background, 0, 0, this);
                g2d.dispose();
            }
        }

    }

}

可以帮助...

现在,我在Robot的计时方面遇到了一些问题,似乎该操作的一部分已通过某种方式进行了螺纹加工,这意味着除非您获得了在不可见和可见正好"之间切换帧的计时,否则,您实际上会重新捕获框架...烦人的...

Now, I had some issues with the timing of Robot, it would seem that part of the operation is threaded in some way, meaning that unless you got the timing of the frame changing between invisible and visible "just" right, you would actually recapture the frame...annoying...

为解决此问题并减少尝试捕获屏幕的次数,我使用了javax.swing.Timer(以减少捕获尝试)和SwingWorker来控制实际的快照过程,将其从屏幕中删除事件调度线程,通过确保(在某种程度上)该窗口不可见.

To try and fix this, and reduce the amount of times I tried capturing the screen, I employed a javax.swing.Timer (to reduce the capture attempts) and a SwingWorker to control the actual snapshot process, taking it out of the Event Dispatching Thread, there by ensuring (to some degree) that the window will be invisible.

我还添加了一些额外的延迟,以确保帧离开屏幕足够长的时间,以防止被快照捕获...

I also added some additional lag to ensure that the frame was off the screen long enough to prevent it been capture by the snapshot...

这篇关于不带JFrame的打印屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆