1

I am trying to serialize a Canvas instance (using the Serializable interface) on which I have painted some pixels like the following code suggests:

Canvas board = new Canvas();
Graphics g = board.getGraphics();
g.setColor(Color.BLACK);
g.drawString("txt", 10, 20);
g.dispose();

Then when I serialize board it doesn't save the pixels I've painted. I'm guessing this is because by using getGraphics() I am not saving those pixels to any instance, so I thought that perhaps I should instead paint from within the Canvas's paint() method. Would serializing the Canvas then save the modified pixels too? If not, what are my options to save/serialize a Canvas with the pixels I've modified? I am guessing I would have to serialize the Graphics object instead of the Canvas? I am new to Java graphics, any help will be greatly appreciated.

To be more clear, what I'm trying to do is have the pixels I've put on a Canvas instance saved to a file using serialization. Then later I need to reload this Canvas instance from the serialized file I saved earlier, so that when I use it on the screen I see the exact same pixels I modified just before I serialized the Canvas. I know how to serialize objects and all that. I am just unclear where all the pixels are stored.

Update1:

The way the user draws something on the screen is by left-clicking on the Canvas area. Then MouseListener calls the following method, passing along the Point object specifying the mouse xy:

private void drawAt(Point p)
{
    Graphics g = board.getGraphics();
    g.setColor(brushColor);
    g.setFont(brushFont);
    g.drawString(brushText, p.x, p.y);
    g.dispose();
}
programmar
  • 670
  • 2
  • 8
  • 18

1 Answers1

2

Don't serialize Canvas or any other GUI components as you'd be serializing the "View" portion of your program, a risky thing to do (high risk for serialization exceptions due to attempting to serialize and unserialize unserializable sub components) and an inefficient thing to do -- serializing large amounts of data which are built automatically by the JVM and thus don't need serialization.

Instead you will want to serialize the "Model" portion of your data, that portion which holds the logical data of your program. So if your GUI is drawn using data held by an ArrayList, or a collection of ArrayLists, or whatever data it takes, then serialize that data. Then be sure to create your GUI so that can be built using the serialized data.

Or if you need to store an image, then store an image, probably best as a loss-less png file.

Also, I suggest that you draw into a BufferedImage, that you then display that BufferedImage within the paintComponent method override of a JPanel, and that you then save and restore the image. For more on how to draw and save, please have a look at these links. The first two contain my code, the third is that of MadProgrammer's:

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • The program is basically like mspaint or photoshop, it lets the user paint whatever they want on the `Canvas`, so I'm not so sure if I can serialize the model in this case unless I track every x and y coordinate of the mouse they used to paint, the color, the brush size, etc. That's why i was thinking it would be easier to just save the pixels rather than all the random steps a user may take to draw something. – programmar Dec 06 '15 at 00:40
  • @programmar: I will state this again most emphatically, because it is the truth: you do not want to serialize the Canvas, regardless of anything, you do not want to serialize it. Much will depend on how you do your drawings, something we don't know about as yet, but you still could extract png image from the drawn image and save that, or if you wish to have a drawing with undo functionality, then you may wish to save collections of images or points. – Hovercraft Full Of Eels Dec 06 '15 at 00:44
  • @programmar: Out of curiosity -- why do you use the AWT GUI class, Canvas? Why not a Swing component such as a JPanel or a JavaFX component? – Hovercraft Full Of Eels Dec 06 '15 at 00:45
  • I mainly use `Canvas` just because our professor has limited us on what we can use. I could also choose to use `JPanel` if that would make things better. what classes would I have to look into to extract the drawn image as a png like you suggested? – programmar Dec 06 '15 at 00:51
  • @programmar: update your question please and show us how you draw. Hopefully you're not calling `getGraphics()` on a component. – Hovercraft Full Of Eels Dec 06 '15 at 00:52
  • @programmar: you're not drawing in a safe way. To show what I mean, run your program, draw on it, minimize the program and then restore it. Do you lose your drawings? – Hovercraft Full Of Eels Dec 06 '15 at 01:18
  • I do see what you mean, if I minimize my program it erases everything I drew. That is because I should be drawing from `paint()` or `paintComponent()` methods right? The biggest problem is that our professor requires us to serialize this image we make, so would it be possible to serialize the JPanel or BufferedImage instances so the image can be reloaded from the serialized file later? – programmar Dec 06 '15 at 03:16