Reputation: 122
I'm newbie in jave, my first project is draw, and save a image from JPanel, my draw is done, but I cant save it after I draw in JPanel :(, So can you help me to fix it when I open the image after draw, It doesn't contain anything :( here my codes:
package image;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class paint extends JFrame{
private Point points[] = new Point[10000];
private Point pointends[] = new Point[10000];
private int pointCount = 0;
private JButton save_btn;
public paint()
{
panel paint2 = new panel();
add(paint2,BorderLayout.CENTER);
}
private class panel extends JPanel
{
private paint my_paint;
public panel()
{
setBackground(Color.WHITE);
save_btn = new JButton();
save_btn.setText("123");
this.add(save_btn);
ButtonHandler handler1 = new ButtonHandler();
save_btn.addActionListener(handler1);
MouseHandler handler = new MouseHandler();
this.addMouseMotionListener(handler);
this.addMouseListener(handler);
}
private class ButtonHandler implements ActionListener
{
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
savefile();
}
}
@Override
protected void paintComponent(Graphics g)
{
// TODO Auto-generated method stub
super.paintComponent(g);
for(int i = 0;i <pointCount;i++)
{
g.setColor(Color.RED);
g.drawLine(points[i].x, points[i].y, pointends[i].x, pointends[i].y);
}
}
private class MouseHandler extends MouseAdapter
{
@Override
public void mouseDragged(MouseEvent e)
{
// TODO Auto-generated method stub
pointends[ pointCount-1] = e.getPoint();
repaint();
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
super.mousePressed(e);
if(pointCount < points.length)
{
points[ pointCount ] = e.getPoint();
pointends[ pointCount ] = e.getPoint();
pointCount++;
repaint();
}
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
super.mouseReleased(e);
/*pointends[pointCount]=e.getPoint();
repaint();
pointCount++;
*/
}
}
}
public void savefile()
{
BufferedImage image2 = new BufferedImage(panel.WIDTH, panel.HEIGHT, BufferedImage.TYPE_INT_RGB);
JFileChooser jFile = new JFileChooser();
jFile.showSaveDialog(null);
Path pth = jFile.getSelectedFile().toPath();
JOptionPane.showMessageDialog(null, pth.toString());
Graphics2D graphics2D = image2.createGraphics();
try {
ImageIO.write(image2, "", new File(pth.toString()));
} catch (IOException ox) {
// TODO: handle exception
ox.printStackTrace();
}
}
}
Upvotes: 6
Views: 32302
Reputation: 594
private void saveImage(){
BufferedImage imagebuf=null;
try {
imagebuf = new Robot().createScreenCapture(panel.bounds());
} catch (AWTException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Graphics2D graphics2D = imagebuf.createGraphics();
panel.paint(graphics2D);
try {
ImageIO.write(imagebuf,"jpeg", new File("save1.jpeg"));
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("error");
}
}
Upvotes: 6
Reputation: 15408
There is a nice approach:
BufferedImage image = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
component.paint(g);
try {
ImageIO.write(image, "png", new File(filename));
} catch (IOException ex) {
Logger.getLogger(CustomApp.class.getName()).log(Level.SEVERE, null, ex);
}
All what it does: It creates an image with visible component's size and ARGB
type for transparency support. Then it get the graphics and pass that to the component we want to have snapshot of. It paints that component's child component including anything drawn on it.
Update: You can use component.print(Graphics g) too:
Dimension componentSize = component.getPreferredSize();
component.setSize(componentSize); // need to make sure that both sizes are equal
BufferedImage image = new BufferedImage(comonent.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = image.createGraphics();
g.fillRect(0, 0, image.getWidth(), image.getHeight());
component.print(g);
But this function will draw only the rendered graphics of the component but not the child components. I have tested it.
Edit:
paint extends JFrame
class can have a nice name, e.g., PaintFrame extends JFrame
. Class name should not have a name of a function, paint is a verb
, it is a function.panel extends JPanel
: why should we go down choosing a class name with first letter of lower case? We can give our component name to reflect what we are doing with it: like, we are drawing so what about MyCanvas extends JPanel
panel
your first statement private paint my_paint;
: what is it doing here unnecessarily ?saveFile()
function belongs to the JFrame
and you have created your panel
(on which you are drawing) local to the frame constructor. How should the saveFile()
function have access to it? Declare your painting Panel in the JFrame class context as public
or private
. I have written in a meaningful way to read the sizes of the component using getWidth()
and getHeight()
But you are writing:
BufferedImage image2 = new BufferedImage(panel.WIDTH, panel.HEIGHT, ...);
And again i have completely written the code how to save the image as a png
using ImageIO.write(image, "png", "myFile.png")
function. Please read the answers carefully.
Following resources might be helpful:
Upvotes: 6
Reputation: 3390
Create BufferedImage to store your painting. When you paint, paint on BufferedImage.
When you need to display paint on JPanel, draw BufferedImage on JPanel.
This way, you can load / save painting to file.
Something like this:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class Paint extends JPanel{
private BufferedImage paintImage = new BufferedImage(500, 400, BufferedImage.TYPE_3BYTE_BGR);
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(paintImage, 0, 0, null);
}
// draw painting
public void updatePaint(){
Graphics g = paintImage.createGraphics();
// draw on paintImage using Graphics
g.dispose();
// repaint panel with new modified paint
repaint();
}
public void save() throws IOException{
ImageIO.write(paintImage, "PNG", new File("filename.png"));
}
public void load() throws IOException {
paintImage = ImageIO.read(new File("filename.png"));
// update panel with new paint image
repaint();
}
}
Upvotes: 14