没有JFrame的打印屏幕

时间:2014-10-11 21:53:04

标签: java swing jframe screen desktop

我想在我称之为源的JFrame后面做一个打印屏幕。但是JFrame(源代码)本身并没有将它打印在另一个JFrame中,我称之为命运......就像链接中的图片一样:https://drive.google.com/file/d/0B4iWj2t4ATQ5ZllwVEE0M1BxUnc/view?usp=sharing

我尝试使用setVisible(false)并在setVisible(true)之后,但我不希望它关闭并再次打开。我是怎么做到的?

这是我的实际代码:

package tests;

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;

public class Offscreen {

    private static BufferedImage img;

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

        // print screen
        Robot r = new Robot();
        // hide source
        source.setVisible(false);
        long l = System.currentTimeMillis();
        while (System.currentTimeMillis() - l < 200) { // take the time to hide
        }
        // take the picture
        img = r.createScreenCapture(source.getBounds());
        // show the source again
        source.setVisible(true);
        // print on destiny
        destiny.repaint();
    }
}

1 个答案:

答案 0 :(得分:2)

“假设”你只想捕捉活动框架后面的区域(正如你所说,没有框架),那么就像..

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的时间有一些问题,看起来操作的一部分是以某种方式进行线程化的,这意味着除非你在不可见和可见之间改变帧的时间“ “是的,你真的会重新夺回这个框架......很烦人......

要尝试修复此问题,并减少尝试捕获屏幕的次数,我使用了javax.swing.Timer(以减少捕获尝试)和SwingWorker来控制实际的快照过程,从事件调度线程中取出它,确保(在某种程度上)窗口不可见。

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