Java - 将JPanel保存为图像

时间:2014-09-03 18:41:10

标签: java jpanel bufferedimage

我有一个受欢迎的问题。我已经阅读了很多关于它的内容,但我仍然无法解决它。我编写了像MSW Logo(Turtle图形解释器)之类的东西,我想保存我的图像(在扩展JPanel的类上绘制)。问题是保存的图像是空白的(只有白色背景,没有更多,没有形状)。

从StackOverflow上的帖子我注意到,在JPanel上绘图是错误的,我应该使用BufferedImage,但我不知道如何将此提示应用于我的源代码。拜托,帮我起步。非常感谢! :)

我的课程扩展JPanel:

public class TurtlePanel extends JPanel {

    public TurtlePanel() {
        super();
        this.setPreferredSize(new Dimension(481, 481));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
    }

}

创建面板:

public class PanelView {

    private JPanel panel;
    private MainWindowView mainView;


    public PanelView(MainWindowView mainView) {
        this.mainView = mainView;
        createView();
    }

    private void createView() {
        panel = new TurtlePanel();
        panel.setBounds(280, 30, 481, 481);
        panel.setBackground(Color.WHITE);
        panel.setVisible(true);
        mainView.mainWindow.add(panel);
    }

    public JPanel getPanel() {
        return this.panel;
    }

}

我绘制形状的方式(它的工作方式,形状在我的面板上显示):

private void drawCircle(double radius) {
    if(Math.signum(radius) == -1)
        throw new NumberFormatException();

    if(turtleModel.isShown()) {
        Graphics2D g = ((Graphics2D) panelView.getPanel().getGraphics());
        g.setColor(turtleModel.getPenColor());
        g.draw(new Ellipse2D.Double(turtleModel.getPosX() - radius, turtleModel.getPosY() - radius, 2*radius, 2*radius));
    }
}

我试图保存图片的方式:

try {
    BufferedImage image = new BufferedImage(panelView.getPanel().getWidth(), panelView.getPanel().getHeight(), BufferedImage.TYPE_INT_RGB);
    Graphics graphics = image.getGraphics();
    panelView.getPanel().paint(graphics);
    ImageIO.write(image, ext, new File(path));
} 
catch(IOException exc) {
    exc.printStackTrace();
}

再次,谢谢你的帮助!如果您需要其他信息,请告诉我们。干杯!

2 个答案:

答案 0 :(得分:0)

在JPanel上绘图完全没问题。如果你经常重绘,那些重绘会绘制相同的东西,那就是你可能想要在BufferedImage中缓存你的图形。

我不确定你当前的渲染是如何完成的,因为它似乎在一个可能是实例变量的Graphics对象上运行,这很奇怪,因为你不想保存那些Graphics对象。使用非标准(可能已损坏)的方式绘制图形是最有可能给您带来麻烦的。

解决这个问题的简单方法是创建一个更抽象的方法,绘制您希望在传入的Graphics对象上呈现的内容。然后,JPanel的paintComponent方法(使用Graphics对象)和有关保存图像的代码(图像中的Graphics对象)都可以使用相同的方法调用共享。

答案 1 :(得分:0)

调用绘制(图形)不会复制当前面板的内容。 这不是它本应该起作用的方式。

通常,您将swing组件添加到JPanel,并且调用 paintComponents()会调用JPanel中包含的每个组件的 paint()

你不应该直接绘图,而是你可以修改TurtlePanel,使它拥有一个他必须对Graphics对象做的动作的列表,并覆盖它的paint()方法,这样它总是可以从一个全新的内容打印它的全部内容图形对象。

显然,对于专业架构,您可能会想到更好的方法。