Hi,

I am trying to get a screenshot of the active window on the screen, for which unfortunately Java does not have an API. It allows me to capture the screenshot of the whole screen but not of the active window.

Now, I did a bit of workaround but it is not working as expected. What I did was first press the Alt+PrntScrn keys using the robot class object. Then I get the contents from the clipboard and save the image to a file.

The code is working fine, however it is not getting me the latest image. It gets the last screenshot taken. So the first time the code is run, the image file size is 0kb, next time the code runs it gets the image that was previously taken.
Here is the code:

robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(KeyEvent.VK_PRINTSCREEN);
robot.keyRelease(KeyEvent.VK_PRINTSCREEN);
robot.keyRelease(KeyEvent.VK_ALT);                
saveToImage((RenderedImage)getClipboard(),targetLocation);


public Image getClipboard() 
    {
        Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
        try {
            if (t != null && t.isDataFlavorSupported(DataFlavor.imageFlavor)) 
            {
                Image text = (Image)t.getTransferData(DataFlavor.imageFlavor);
                return text;
            }
        }
        catch (UnsupportedFlavorException e) 
        {} 
        catch (IOException e) 
        {}
        return null;
    }

I am not sure what is happening, please advice.

Thanks,
Anuj Sharma

Dani AI

Generated

Short explanation and a reliable pattern to fix it

The symptom you saw is a timing/race issue: Robot synthesizes Alt+PrintScreen but the OS may update the clipboard asynchronously, so an immediate read can return the previous clipboard contents. ’s suggestion to wait is correct; Robot provides delay/wait helpers you can (and should) use rather than assuming the clipboard is ready instantly. (docs.oracle.com)

More robust approaches (preferred over a blind sleep)

  • Wait until the clipboard actually offers an image flavor instead of sleeping a fixed time. You can either register a FlavorListener on the system clipboard or poll isDataFlavorAvailable(DataFlavor.imageFlavor) with a short sleep and an overall timeout. That avoids flaky timing and handles cases where the clipboard is briefly locked by the OS. Also catch/handle IllegalStateException since some platforms briefly make the clipboard unavailable. (docs.oracle.com)

Example polling pattern (conceptual)

Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
long deadline = System.currentTimeMillis() + 2000; // 2s timeout
while (!cb.isDataFlavorAvailable(DataFlavor.imageFlavor) &&
       System.currentTimeMillis() < deadline) {
    Thread.sleep(50);
}
if (cb.isDataFlavorAvailable(DataFlavor.imageFlavor)) {
    // get and save image
}

(Use a background thread — don’t block the Swing EDT — and adjust timeout as needed.)

If you specifically need the active window only
Using Alt+PrtSc is a GUI hack and can change focus (menus/toolbars). A cleaner solution is to get the active window bounds via native calls (JNA/JNI) and then use Robot.createScreenCapture(rect) or, on Windows, call PrintWindow / GetForegroundWindow to capture the window directly. The JNA approach is commonly recommended for this use-case. (stackoverflow.com)

Practical notes: avoid long sleeps on the EDT, prefer a short polling loop or FlavorListener, and always use sensible timeouts so the app remains responsive.

Recommended Answers

All 2 Replies

Perhaps it's a task switch thing? You could try a sleep(1000) after taking the screenshot but before accessing the clipboard?

Thanks James. You were right, it is a task switch thing. As you suggested, i put a sleep in between the screenshot and clipboard access and it worked. Now it is getting the right image.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.