我可以从JPanel创建BufferedImage而无需在JFrame中呈现吗?

时间:2012-09-18 15:29:15

标签: java swing jframe jpanel bufferedimage

是否可以从JPanel创建BufferedImage而无需先在JFrame中呈现它?我搜遍了我能想到的任何地方,找不到答案。有人可以帮忙吗?

以下是一些示例代码。如果我不取消注释JFrame代码,我的BufferedImage就是空白。

    test(){
//      JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        Dimension dim = new Dimension(50,50);
        panel.setMinimumSize(dim);
        panel.setMaximumSize(dim);
        panel.setPreferredSize(dim);
        JLabel label = new JLabel("hello");
        panel.add(label);
//      frame.add(panel);
//      frame.pack();
        BufferedImage bi = getScreenShot(panel);

        //...code that saves bi to a jpg
    }

    private BufferedImage getScreenShot(JPanel panel){
        BufferedImage bi = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_ARGB);
        panel.paint(bi.getGraphics());
        return bi;
    }

1 个答案:

答案 0 :(得分:4)

编辑2:基本上安德鲁汤普森的答案是正确的,没有必要使用框架。同时拥有一个是实用的,因为对pack()的调用将使布局管理器工作。我删除了原始答案的第一部分,左边是与记忆相关的部分。请注意,即使没有框架,仍然需要在图形上调用dispose。

关于使用框架时堆空间的用尽:这不应该发生。当你完成它们时,你可能只需要在帧上调用dispose()。如果这没有帮助,我建议在一个单独的问题中提出。来自dispose docs:

  

释放此Window使用的所有本机屏幕资源   子组件及其拥有的所有子组件。也就是资源   对于这些组件将被销毁,他们消耗的任何内存都将被销毁   返回操作系统,它们将被标记为不可显示。 (......)   注意:当Java虚拟机中的最后一个可显示窗口时   (VM)被丢弃,VM可以终止。

编辑:更多想法:

  • 重用相同的JFrame对象也应该有效。添加面板,调用包,创建图像,删除面板,重复
  • 不要忘记在你创建的Graphics对象上调用dispose()
  • 在最坏的情况下,您可以不时从脚本重新启动JVM