简体   繁体   中英

How to export image without showing it in Java Swing

I have probelm with code below (it's simplified test version):

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

public class Example {
    JFrame frame;
    JPanel background;
    JPanel top;
    JPanel center;
    JPanel bottom;

    public Example() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(1016, 639);
        frame.setResizable(false);

        background = new JPanel();
        background.setLayout(new BoxLayout(background, BoxLayout.Y_AXIS));
        background.setPreferredSize(new Dimension(1000, 600));

        top = new JPanel();
        top.setPreferredSize(new Dimension(1000, 200));
        top.setBackground(Color.BLACK);

        center = new JPanel();
        center.setPreferredSize(new Dimension(1000, 200));
        center.setBackground(Color.WHITE);

        bottom = new JPanel();
        bottom.setPreferredSize(new Dimension(1000, 200));
        bottom.setBackground(Color.BLUE);

        background.add(top);
        background.add(center);
        background.add(bottom);

        frame.add(background);

        frame.setVisible(true);
    }


   public void getImage() {
        BufferedImage img = new BufferedImage(1000, 600, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = img.createGraphics();
        background.paint(g2d);
        g2d.dispose();
        try {
            ImageIO.write(img, "png", new File("frame_2.png"));
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String... args) {
        Example ex = new Example();
        ex.getImage();
    }
 }

All I want to do is to export JPanel background as png file without showing the frame. Problem is, that now it works, but if I comment line:

frame.setVisible(true);

all I get is png file all black, with the right size.

I thing components are not properly painted if setVisible is false, I looked on the internet, but with my short experience with swing I found nothing that works. Maybe someone here could help?

SOLUTION

Use functions pack() to create components with sizes and dispose() to finish swing's loop.

public void getImage() {
    frame.pack();
    BufferedImage img = new BufferedImage(1000, 600, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2d = img.createGraphics();
    background.paint(g2d);
    g2d.dispose();
    try {
        ImageIO.write(img, "png", new File("frame_2.png"));
    } catch(Exception e) {
        e.printStackTrace();
    }
    frame.dispose();
}

Swing components don't have a size until you pack() the frame or invoke setVisible( true ) on the frame, since the layout manager hasn't been invoked.

So try invoking pack() before you invoke the getImage() method.

You can also try using Screen Image which is a reusable class that allows you to create an image of the desktop, frame or any component on the frame. It will automatically handle setting the size of the components even if they are not yet visible on the frame.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM