Swing: Get JFrame Image

How to get java.awt.Image JFrame?

I want to get a screenshot of a JFrame (for later use in my application). This is currently being done using a robot to take a screenshot of the coordinates and sizes of the involved JFrame .

However, I believe there is a better way: Swing components, by default, display themselves as images in a double buffer before drawing themselves on the screen.

Is there any way to get these images from a component?

+57
java image swing screenshot jframe
May 02 '11 at 5:55
source share
1 answer

ComponentImageCapture.java

 import java.awt.BorderLayout; import java.awt.Component; import java.awt.Image; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.InputEvent; import javax.swing.*; import javax.swing.border.TitledBorder; import javax.imageio.ImageIO; import java.io.File; /** Create a screenshot of a component. @author Andrew Thompson */ class ComponentImageCapture { static final String HELP = "Type Ctrl-0 to get a screenshot of the current GUI.\n" + "The screenshot will be saved to the current " + "directory as 'screenshot.png'."; public static BufferedImage getScreenShot( Component component) { BufferedImage image = new BufferedImage( component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB ); // call the Component paint method, using // the Graphics object of the image. component.paint( image.getGraphics() ); // alternately use .printAll(..) return image; } public static void main(String[] args) { Runnable r = new Runnable() { public void run() { final JFrame f = new JFrame("Test Screenshot"); JMenuItem screenshot = new JMenuItem("Screenshot"); screenshot.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_0, InputEvent.CTRL_DOWN_MASK )); screenshot.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent ae) { BufferedImage img = getScreenShot( f.getContentPane() ); JOptionPane.showMessageDialog( null, new JLabel( new ImageIcon( img.getScaledInstance( img.getWidth(null)/2, img.getHeight(null)/2, Image.SCALE_SMOOTH ) ))); try { // write the image as a PNG ImageIO.write( img, "png", new File("screenshot.png")); } catch(Exception e) { e.printStackTrace(); } } } ); JMenu menu = new JMenu("Other"); menu.add(screenshot); JMenuBar mb = new JMenuBar(); mb.add(menu); f.setJMenuBar(mb); JPanel p = new JPanel( new BorderLayout(5,5) ); p.setBorder( new TitledBorder("Main GUI") ); p.add( new JScrollPane(new JTree()), BorderLayout.WEST ); p.add( new JScrollPane( new JTextArea(HELP,10,30) ), BorderLayout.CENTER ); f.setContentPane( p ); f.pack(); f.setLocationRelativeTo(null); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } }; SwingUtilities.invokeLater(r); } } 

Screenshot

GUI with captured image

see also

The above code assumes that the component was implemented on the screen before rendering.

Rob Camick shows how to draw an unrealized component in the Screen Image class.

Another thread that may be relevant is Render JLabel without a 1st display , in particular, Darryl Burke's β€œsingle-line fix”.

LabelRenderTest.java

Below is an updated version of the code shown on the second channel.

 import java.awt.*; import java.awt.image.BufferedImage; import javax.swing.*; public class LabelRenderTest { public static void main(String[] args) { SwingUtilities.invokeLater( new Runnable() { public void run() { String title = "<html><body style='width: 200px; padding: 5px;'>" + "<h1>Do UC Me?</h1>" + "Here is a long string that will wrap. " + "The effect we want is a multi-line label."; JFrame f = new JFrame("Label Render Test"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); BufferedImage image = new BufferedImage( 400, 300, BufferedImage.TYPE_INT_RGB); Graphics2D imageGraphics = image.createGraphics(); GradientPaint gp = new GradientPaint( 20f, 20f, Color.red, 380f, 280f, Color.orange); imageGraphics.setPaint(gp); imageGraphics.fillRect(0, 0, 400, 300); JLabel textLabel = new JLabel(title); textLabel.setSize(textLabel.getPreferredSize()); Dimension d = textLabel.getPreferredSize(); BufferedImage bi = new BufferedImage( d.width, d.height, BufferedImage.TYPE_INT_ARGB); Graphics g = bi.createGraphics(); g.setColor(new Color(255, 255, 255, 128)); g.fillRoundRect( 0, 0, bi.getWidth(f), bi.getHeight(f), 15, 10); g.setColor(Color.black); textLabel.paint(g); Graphics g2 = image.getGraphics(); g2.drawImage(bi, 20, 20, f); ImageIcon ii = new ImageIcon(image); JLabel imageLabel = new JLabel(ii); f.getContentPane().add(imageLabel); f.pack(); f.setLocationByPlatform(true); f.setVisible(true); } }); } } 

Screenshot

Label rendered on image

+69
May 2 '11 at 6:15 a.m.
source share



All Articles