如何在 Java Swing 中导出图像而不显示它

How to export image without showing it in Java Swing

我有以下代码的问题(它是简化的测试版本):

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();
    }
 }

我只想将 JPanel 背景 导出为 png 文件而不显示框架。问题是,现在它可以工作了,但是如果我评论行:

frame.setVisible(true);

我得到的只是 png 文件,全黑,大小合适。

如果 setVisible 为 false,我认为组件未正确绘制,我在互联网上查看过,但根据我对 swing 的短暂经验,我发现没有任何效果。也许这里有人可以提供帮助?

解决方案

使用函数 pack() 创建具有大小的组件并使用 dispose() 完成 swing 的循环。

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();
}

在您 pack() 框架或在框架上调用 setVisible( true ) 之前,Swing 组件没有大小,因为尚未调用布局管理器。

因此,请尝试在调用 getImage() 方法之前调用 pack()。

您也可以尝试使用 Screen Image,这是一个可重复使用的 class,它允许您创建桌面、框架或框架上任何组件的图像。它会自动处理设置组件的大小,即使它们在框架上还不可见。