1

I am developing a scribble type app in java swing. It is in a rudimentary stage and is shown here.

Scribble Board

I have implemented the undo feature which undoes the last drawn stroke upto. The undo feature can be done upto a maximum defined undo levels.

The undo feature works by copying the contents of the drawing canvas after each stroke in an Image array. This array acts like a First-In-Last-Out Stack. When undo is clicked the stack is poped and the obtained image is drawn on screen.

Now the problem I am facing is, the current method of implementation of undo takes up too much memory. At undo levels of 20, almost 70-80 MB of memory is used up, and at levels of 30, heap overflow occurs.

Is there a better way of implementing the undo feature ? Thanks.

EDIT : I found some useful information here which may be helpful.

Extreme Coders
  • 3,441
  • 2
  • 39
  • 55
  • 2
    Sounds like you're saving the entire image after every stroke. Is this correct? In my opinion, it'd be better to save each individual stroke and then draw the image according to all the individual strokes. – adchilds Dec 20 '12 at 07:30
  • @adchilds Yes, I am saving the entire image after each stroke. – Extreme Coders Dec 20 '12 at 07:31
  • @adchilds means you are suggesting saving only the changes from the previous that is like a patch – Extreme Coders Dec 20 '12 at 07:32
  • Instead of saving the entire canvas every time (images use lots of memory!), add each individual stroke to your stack and then draw each stroke individually, which should create the entire image in itself. – adchilds Dec 20 '12 at 07:34
  • Why don't you save the canvas contents to a file and just hold a reference to that file in the Stack? That way it will only eat up your hard drive space which is not as limited. – david Dec 20 '12 at 07:40
  • 1
    @david Well serialization is definitely an option, but I was concerned about run time performance – Extreme Coders Dec 20 '12 at 07:41
  • @2012-EndoftheWorld I think you should try serialization. It is very straightforward and I don't think the performance should be much of an issue. Well, you will only find out by trying. :) – david Dec 20 '12 at 07:51
  • Check [this](http://stackoverflow.com/questions/3901430/fast-undo-redo-for-bitmap-editor-when-memory-is-limited?rq=1) post on how to implement efficient undo/redo when memory is constrained. –  Dec 30 '12 at 14:13

1 Answers1

2

You need to represent the steps in your drawing differently. In the current approach you are using, you save the Canvas each time anew as an uncompressed picture - and that is memory-greedy.

Try to refactor your code so that only the strokes being drawn on the Canvas are saved into the stack. This will put a little bit more overhead when rendering the picture (you would need to redraw the entire canvas each time a change occurs), but Java is designed to deal with that.

Having saved only shapes, the memory requirements should decrease significantly. Use the Shape class to represent the strokes on the canvas.

Jakub Zaverka
  • 8,816
  • 3
  • 32
  • 48
  • If i save the shapes, that means a vector style of drawing – Extreme Coders Dec 20 '12 at 07:34
  • @2012-EndoftheWorld If this is bitmap drawing, you still can achieve this. Instead of using Shape class for vector drawing, you can track the parameters of a stroke (path, opacity, size, etc...) and save this instead. When repainting the canvas using undo, you can recreate the wholepicture by following the tracked strokes from memory. – Jakub Zaverka Dec 20 '12 at 07:38