user2195984
user2195984

Reputation: 33

Save JPanel into .jpg/.png image

I making a Java Applet that save on an image what user paint in a JPanel. When i save on the output image i have only the background of the JPanel, lines has drawed by user disappear. Any tips to fix it? In this code line has drawed by the program, but the bug remains.

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;

public class MarkPen extends Applet implements ActionListener, AdjustmentListener, MouseListener, MouseMotionListener {

     private int x = 0;
     private int y = 0;
     private int prevx  = 0;
     private int prevy  = 0;

     private JPanel drawPanel = new JPanel();
     private JButton saveButton = new JButton("SaveImage");

     public void init()
     {

        setLayout(new BorderLayout());

        drawPanel.setBackground(Color.red);
        drawPanel.addMouseMotionListener(this);
        drawPanel.addMouseListener(this);
        drawPanel.add(new Comp());
        drawPanel.setDoubleBuffered(true);
        add(drawPanel, "Center");

        saveButton.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent e)
                {
                 BufferedImage image = new BufferedImage(drawPanel.getWidth(), drawPanel.getHeight(), BufferedImage.TYPE_INT_RGB);
                 Graphics2D graphics2D = image.createGraphics(); 

                 drawPanel.paint(graphics2D);
                 try{
                     ImageIO.write(image,"jpeg", new File("C:/.../Example.jpeg"));
                     }
                 catch(Exception ex){
                      ex.printStackTrace();
                     }
                 }
        });

        add(saveButton, "South");

     }

    public void setGraphicalDefaults(MouseEvent e){}

    public class Comp extends JComponent{
        public void paintComponent(Graphics g) {
            g  = drawPanel.getGraphics();
            g.setColor(Color.black);
            g.drawLine(0,0,100,100);
        }
     }

     public void mouseDragged(MouseEvent e){}
     public void mousePressed(MouseEvent e){}
     public void actionPerformed(ActionEvent e){}   
     public void mouseReleased(MouseEvent e){}
     public void mouseEntered(MouseEvent e){}
     public void mouseExited(MouseEvent e){}
     public void mouseMoved(MouseEvent e){}
     public void mouseClicked(MouseEvent e){}
     public void adjustmentValueChanged(AdjustmentEvent arg0){}

}

Thanks to yours help i solved it, i post the working code below.

WORKING CODE:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JApplet;
import javax.swing.SwingUtilities;

public class MarkPen extends JApplet {

    private static final long serialVersionUID = 1L;

    public static class DrawPanel extends JPanel {

        private static final long serialVersionUID = 1L;
        private List<Point> points = new ArrayList<Point>();

        public DrawPanel() {
            setBackground(Color.WHITE);

            addMouseMotionListener(new MouseAdapter() {

                @Override
                public void mouseDragged(MouseEvent e) {
                    points.add(e.getPoint());
                    repaint();
                }
            });

            addMouseListener(new MouseAdapter(){

                @Override
                public void mousePressed(MouseEvent e){
                    Point p = null;
                    points.add(p);
             }
            });

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(300, 300);
        }

        @Override
        protected void paintComponent(java.awt.Graphics g) {
            super.paintComponent(g);
            Point p1 = null;
            Point p2 = null;
            g.setColor(Color.black);
            for (Point p : points) {
                p2 = p1;
                p1 = p;
                if (p1 != null && p2 != null) {
                    g.drawLine(p1.x, p1.y, p2.x, p2.y);
                }
            }
        }
    }

    protected void initUI() {
        setLayout(new BorderLayout());

        JButton saveButton = new JButton("SaveImage");
        JButton clearButton = new JButton("Clear");
        final DrawPanel drawPanel = new DrawPanel();
        JPanel buttonsPanel = new JPanel();

        buttonsPanel.setLayout(new BorderLayout());
        setSize(1000, 305);
        add(drawPanel, "Center");

        saveButton.addActionListener(new ActionListener(){
             public void actionPerformed(ActionEvent e)
                {
                 BufferedImage image = new BufferedImage(drawPanel.getWidth(), drawPanel.getHeight(), BufferedImage.TYPE_INT_RGB);
                 Graphics2D graphics2D = image.createGraphics(); 

                 drawPanel.paint(graphics2D);
                 try{
                     ImageIO.write(image,"png", new File("C:/.../Desktop/Example.png"));
                     }
                 catch(Exception ex){
                      ex.printStackTrace();
                     }
                 }
        });

       clearButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                drawPanel.points.clear();
                repaint();
            }
        });

        buttonsPanel.add(clearButton, BorderLayout.WEST);
        buttonsPanel.add(saveButton, BorderLayout.EAST);
        add(buttonsPanel, BorderLayout.SOUTH);

        validate();
    }

    @Override
    public void init() {
        super.init();
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    initUI();
                }
            });
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Upvotes: 1

Views: 4704

Answers (2)

camickr
camickr

Reputation: 324078

it's first time i use BufferedImage and i have problem to understand how it works

See Custom Painting Approaches. The DrawOnImage example is the one that uses a BufferedImage, although it doesn't hurt to understand the other example as well.

Upvotes: 1

mKorbel
mKorbel

Reputation: 109815

  • your issue is by usage of drawPanel.getGraphics();,

  • this methods can creates temparary object for Save JPanel into Image, not for displaying an Image in JPanel

  • override getPreferredSize in public class Comp extends JComponent{

  • drawImage inside paintComponent

  • use super.paintComponent in the case that you want to replace current painting

for example

class Comp extends JComponent {

    private static final long serialVersionUID = 1L;

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(300, 300);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(bi, 0, 0, this);
    }
}

Upvotes: 1

Related Questions