2

I've created a simple program with the Robot class which generates a screen capture of your computer. It creates the screen capture when you click on a JButton.

I've tried to make the JFrame disappear when the screen capture is being made. Unfortunately, the JButton won't display... Can you tell me what is wrong with my code?

package Threads;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;

public class ScreenCapture extends JFrame implements ActionListener{

private JButton b;

public ScreenCapture() throws Exception{
    this.setTitle("Etfeld");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    this.setVisible(true);
    this.pack();
    this.setResizable(false);
    this.setLocation(1366/2-100,678/2);

    ImageIcon jamil=new ImageIcon("Logo.png");
    Image logo=jamil.getImage();
    this.setIconImage(logo);

    JPanel jp=new JPanel();
    b=new JButton("Capture!");
    b.addActionListener(this);
    this.add(jp);
    jp.add(b);

}

@Override
public void actionPerformed(ActionEvent ae) {
    Object obj=ae.getSource();
    if(obj instanceof JButton){
        try {
            Robot robot = new Robot();
            this.setVisible(false);
            BufferedImage im=robot.createScreenCapture(new Rectangle(0,0,1366,768));

                    Toolkit.getDefaultToolkit().beep();
                    this.setVisible(true);
                    File outputfile = new File("saved.png");
                    ImageIO.write(im, "png", outputfile);
                } catch (Exception v) {v.printStackTrace();}
    }

}

public static void main(String []args) throws Exception{
    ScreenCapture sc=new ScreenCapture();
}
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Donagi
  • 23
  • 2

2 Answers2

4

The frame has been made visible before the button is added. Ensure that this statement appears after the component has been added. Invoke pack prior to making the frame visible to ensure that the frame is large enough to make the button visible

pack();
setVisible(true);
Reimeus
  • 158,255
  • 15
  • 216
  • 276
  • Not to forget, `pack()` comes second-to-last :) – An SO User Feb 28 '14 at 18:07
  • 1
    @LittleChild unless you want to make a `setLocationRelativeTo(null);` call ;) – Obicere Feb 28 '14 at 18:18
  • `setLocation(fancyCoordinates)` already used. Your argument is as invalid as my cat trying to catch an `Exception` xD *for the lack of a better comparison* – An SO User Feb 28 '14 at 18:20
  • 1
    @LittleChild *"`setLocation(fancyCoordinates)` already used. Your argument is as invalid.."* Not to `setLocationRelativeTo(..)` it isn't. It positions a container accounting for the *current size*. If code calls `setLocationRelativeTo` on a 0x0 container, it will put the location (of the top left point) right at that location. Better to either of course, is `setLocationByPlatform(..)` which also does not change depending on container size but **must** be called before the container is set visible. See [this answer](http://stackoverflow.com/a/7143398/418556) for demo. – Andrew Thompson Mar 01 '14 at 06:15
3

You need to rearrange the calls to your methods. You should call pack() just before making the frame visible; after you have added all your UI components.
Then, use setVisible(true) to make the JFrame visible.

An SO User
  • 24,612
  • 35
  • 133
  • 221