0

I'm trying to make a drawing program using a JFrame with a Canvas in it, and there are a couple of other issues with it, but the main one I'm trying to solve right now is how to save the canvas as an image file. I've tried a bunch of different methods I found online but they all just save a transparent screen or something. Please help me, this is a school project and my teacher is the most unhelpful person ever. I don't know what I'm doing. Sorry if my code makes you cringe.

//Java Program to create a canvas and paint the canvas
import java.awt.*;
import javax.swing.*;
//apparently this lets me use the mouse to draw
import java.awt.event.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
//didn't need BreezySwing

//to save canvas
import java.io.File;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.awt.Graphics;
import java.awt.Graphics2D;

//use JFrame instead of GBFrame, GBFrame won't let me use a canvas
class paint3 extends JFrame implements MouseListener, MouseMotionListener{

// create menubar and canvas
JMenuBar menuBar = new JMenuBar();
Canvas c;

// create color variable, set it to black
Color color = Color.black;
// create size variable, set it to 5
int size = 5;

////CONSTRUCTOR FOR FRAME////
public paint3()
{
    ////MENU STUFF////

    setJMenuBar(menuBar); // Add the menu bar to the window
    
    // create menus/menuitems
    JMenu colorMenu = new JMenu("Color"); //create color menu
    
    //implement methods to change the color of the brush when corresponding menu item is selected
    JMenuItem black = new JMenuItem(new AbstractAction("Black") {
        public void actionPerformed(ActionEvent e) {
            color = Color.black;
        }
    }); 
    JMenuItem darkGray = new JMenuItem(new AbstractAction("Dark Gray") {
        public void actionPerformed(ActionEvent e) {
            color = Color.darkGray;
        }
    });
    JMenuItem gray = new JMenuItem(new AbstractAction("Gray") {
        public void actionPerformed(ActionEvent e) {
            color = Color.gray;
        }
    });
    JMenuItem lightGray = new JMenuItem(new AbstractAction("Light Gray") {
        public void actionPerformed(ActionEvent e) {
            color = Color.lightGray;
        }
    });
    JMenuItem red = new JMenuItem(new AbstractAction("Red") {
        public void actionPerformed(ActionEvent e) {
            color = Color.red;
        }
    });
    JMenuItem orange = new JMenuItem(new AbstractAction("Orange") {
        public void actionPerformed(ActionEvent e) {
            color = Color.orange;
        }
    });
    JMenuItem yellow = new JMenuItem(new AbstractAction("Yellow") {
        public void actionPerformed(ActionEvent e) {
            color = Color.yellow;
        }
    });
    JMenuItem green = new JMenuItem(new AbstractAction("Green") {
        public void actionPerformed(ActionEvent e) {
            color = Color.green;
        }
    });
    JMenuItem cyan = new JMenuItem(new AbstractAction("Cyan") {
        public void actionPerformed(ActionEvent e) {
            color = Color.cyan;
        }
    });
    JMenuItem blue = new JMenuItem(new AbstractAction("Blue") {
        public void actionPerformed(ActionEvent e) {
            color = Color.blue;
        }
    });
    JMenuItem magenta = new JMenuItem(new AbstractAction("Magenta") {
        public void actionPerformed(ActionEvent e) {
            color = Color.magenta;
        }
    });
    JMenuItem pink = new JMenuItem(new AbstractAction("Pink") {
        public void actionPerformed(ActionEvent e) {
            color = Color.pink;
        }
    });
    JMenuItem white = new JMenuItem(new AbstractAction("White") {
        public void actionPerformed(ActionEvent e) {
            color = Color.white;
        }
    });
        
        
    JMenu sizeMenu = new JMenu("Size"); // Create Size menu
    
    //implement methods to change the size of the brush when corresponding menu item is selected
    JMenuItem five = new JMenuItem(new AbstractAction("5") {
        public void actionPerformed(ActionEvent e) {
            size = 5;
        }
    });  
    JMenuItem ten = new JMenuItem(new AbstractAction("10") {
        public void actionPerformed(ActionEvent e) {
            size = 10;
        }
    }); 
    JMenuItem fifteen = new JMenuItem(new AbstractAction("15") {
        public void actionPerformed(ActionEvent e) {
            size = 15;
        }
    });
    JMenuItem twenty = new JMenuItem(new AbstractAction("20") {
        public void actionPerformed(ActionEvent e) {
            size = 20;
        }
    });
    JMenuItem twentyfive = new JMenuItem(new AbstractAction("25") {
        public void actionPerformed(ActionEvent e) {
            size = 25;
        }
    });
    JMenuItem thirty = new JMenuItem(new AbstractAction("30") {
        public void actionPerformed(ActionEvent e) {
            size = 30;
        }
    }); 
            
    //JMenu clearButton = new JMenu(new AbstractAction("Clear") {
        //public void actionPerformed(ActionEvent e) {
            //c.clearRect(0,0,800,600);
        //}
    //});
    
    JMenu fileMenu = new JMenu("File"); //create file menu
    
    JMenuItem save = new JMenuItem(new AbstractAction("Save") {
        public void actionPerformed(ActionEvent e) {
            saveCanvas(c);
        }
    });  
    
    
    // add menus/menuitems to frame
    menuBar.add(colorMenu); // Add the color menu
    colorMenu.add(black); //add color menu items to frame
    colorMenu.add(darkGray);
    colorMenu.add(gray);
    colorMenu.add(lightGray);
    colorMenu.add(red);
    colorMenu.add(orange);
    colorMenu.add(yellow);
    colorMenu.add(green);
    colorMenu.add(cyan);
    colorMenu.add(blue);
    colorMenu.add(magenta);
    colorMenu.add(pink);
    colorMenu.add(white);
    
    menuBar.add(sizeMenu); // Add the size menu
    sizeMenu.add(five); // Add size menu items to frame
    sizeMenu.add(ten);
    sizeMenu.add(fifteen);
    sizeMenu.add(twenty);
    sizeMenu.add(twentyfive);
    sizeMenu.add(thirty);
    
    menuBar.add(fileMenu); // Add the file menu
    fileMenu.add(save); //Add file menu items to frame
    
    //terminates program when window is closed
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    ////////
    
    //create an empty canvas
    c = new Canvas() {
        
        //paint the canvas
        public void paint(Graphics g)
        {
        }
        
    };
    
    //set background color of canvas
    c.setBackground(Color.white);
    
    //add mouse listener to canvas
    c.addMouseListener(this);
    c.addMouseMotionListener(this);
    
    //add canvas to frame
    add(c);
    setSize(800,600);
    setResizable(false);
    show(); 
        
}
////////////

//mouse listener and mouse motion listener methods
public void mouseClicked(MouseEvent e)
{
    Graphics g = c.getGraphics();
    
    g.setColor(color);
    
    //get x and y pos
    int x, y;
    x = e.getX();
    y = e.getY();
    
    //draw an oval at the point were mouse is moved
    g.fillOval(x, y, size, size);
}

public void mouseMoved(MouseEvent e)
{
}

public void mouseDragged(MouseEvent e)
{
    Graphics g = c.getGraphics();
    
    g.setColor(color);
    
    //get x and y pos
    int x, y;
    x = e.getX();
    y = e.getY();
    
    //draw an oval at the point were mouse is moved
    g.fillOval(x, y, size, size);
}

public void mouseExited(MouseEvent e)
{
}

public void mouseEntered(MouseEvent e)
{
}

public void mouseReleased(MouseEvent e)
{
}   

public void mousePressed(MouseEvent e)
{
}

//method to save canvas, but it just saves a black screen
public static void saveCanvas(Canvas c) {
    BufferedImage image = new BufferedImage(c.getWidth(), c.getHeight(),BufferedImage.TYPE_INT_RGB);
    
    Graphics2D graphics = image.createGraphics();
    
    c.paint(graphics);
    //save file
    File file = new File("drawing.png");
    
    try {
        ImageIO.write(image, "png", file);
    } catch (Exception e) {
    }

}

//Main method
public static void main(String args[]) 
{
    Frame frm = new paint3();
    //need to capitalize canvas
    Canvas c = new Canvas();
    frm.setSize(800,600);
    //frm.pack();
    frm.setVisible(true);

}

}

camickr
  • 321,443
  • 19
  • 166
  • 288
Sarah
  • 1
  • 1
  • 1
    Nothing will be saved because you are doing painting incorrectly. You have no painting code in the paint() method. Don't use getGraphics() to do the painting. Any painting done will be temporary and will be lost whenever Swing determines the component needs to be repainted. Painting is done by overriding the `paintComponent()` method of a JPanel. Read the section from the Swing tutorial on [Custom Painting](https://docs.oracle.com/javase/tutorial/uiswing/painting/index.html) for a working example to get you started. – camickr Sep 04 '20 at 23:36
  • You can also check out [Custom Painting Approaches](https://tips4java.wordpress.com/2009/05/08/custom-painting-approaches/) for more information and working examples that will allow you to paint multiple ovals. – camickr Sep 04 '20 at 23:42
  • `Graphics g = c.getGraphics();` is NOT how you should be doing custom painting – MadProgrammer Sep 04 '20 at 23:46
  • 1
    As a "general" recommendation, I would recommend drawing to a `BufferedImage` instead, you can then paint this to a component (like a `JPanel`) and write it to a file – MadProgrammer Sep 04 '20 at 23:55
  • [This may be insightful as well](https://tips4java.wordpress.com/2008/10/13/screen-image/) (another **camickr** contribution). – DevilsHnd - 退職した Sep 05 '20 at 00:20
  • @MadProgrammer *"I would recommend drawing to a `BufferedImage` instead.."* Here is an example of painting to [an image](https://stackoverflow.com/a/10628553/418556). – Andrew Thompson Sep 05 '20 at 04:29

0 Answers0