1

I want to create an app which captures the screen (1280x720 res) and then displays it. The code for this is in a while loop so it's ongoing. Here's what I have:

import javax.swing.*;

import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;

public class SV1 {

    public static void main(String[] args) throws Exception {
        JFrame theGUI = new JFrame();
        theGUI.setTitle("TestApp");
        theGUI.setSize(1280, 720);
        theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        theGUI.setVisible(true);

        Robot robot = new Robot();

        while (true) {
            BufferedImage screenShot = robot.createScreenCapture(new Rectangle(1280,720));

            JLabel picLabel = new JLabel(new ImageIcon( screenShot ));
            theGUI.add(picLabel);
        }
    }
}

I figured this out from this answer but it isn't ideal for what I want. First of all, for some reason I'm not sure of, it causes java to run out of memory "Java heap space". And secondly it doesn't work properly as the image shown isn't updated.

I've read about using Graphics (java.awt.Graphics) to draw the image. Can anyone show me an example of this? Or perhaps point me in the right direction if there's a better way?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Joey Morani
  • 25,431
  • 32
  • 84
  • 131
  • `while (true) {..` Don't block the EDT, and don't try to update the GUI on anything other than the EDT. This calls for a Swing `Timer` to trigger the screen grabs. Also, the frame is too small for the label. It should simply call `pack()` after the label is added with first screenshot - then it will be exactly as big as needed to display it. If the screen-shots are 'the entire screen', put the label in a scroll pane. – Andrew Thompson Aug 22 '12 at 00:48

1 Answers1

3

it causes java to run out of memory "Java heap space"

You are looping forever and continuosly adding new JLabels to your JFrame. You could try instead of recreating each time the JLabel, to simply set a new ImageIcon:

JLabel picLabel = new JLabel();
theGUI.add(picLabel);
while (true) 
{
    BufferedImage screenShot = robot.createScreenCapture(new Rectangle(1280,720));
    picLabel.setIcon(new ImageIcon(screenShot));   

}

If you want to paint using Graphics(in this case it's probably a better idea), you can extend a JLabel and override paintComponent method, drawing the image inside it:

public class ScreenShotPanel extends JLabel
{

    @override
    public void paintComponent(Graphics g) {
        BufferedImage screenShot = robot.createScreenCapture(new Rectangle(1280,720));
        g.drawImage(screenShot,0,0,this);
    }
}
Heisenbug
  • 38,762
  • 28
  • 132
  • 190