我想在我称之为源的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();
}
}
答案 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
来控制实际的快照过程,从事件调度线程中取出它,确保(在某种程度上)窗口不可见。
我还添加了一些额外的延迟,以确保框架在屏幕外的时间足够长,以防止它被快照捕获...