Perhaps, the layout manager is just attempting to honor your preferred size.
I would:
A) remove the preferred just to see what happens ( not a very good idea anyway )
or
B) not use canvas in first place but JComponent. After all Canvas is AWT component, and I not pretty sure how they work as today anyway. JComponent is a light weight component and since you're using a JComponent as container they would... mmhhh work better together?
Gee.. I'm giving voodoo programming suggestions now. Better get to work.
C) What have always worked for me. Make an small proof of concept, by adding step by step the stuff in my code. Start with empty canvas, then add the preffered size, then etc. etc. Chances are, the bug is on the paint method :P
Good luck.
:)