Why must I override getPreferredSize() for Canvas to appear on the screen?

Scott Stanchfield

Whenever you use a component in a layout manager, it may be asked for its preferredSize. This is a layout manager's way of respecting the sizing wishes of components that it manages. Some layout managers try to respect it, while others may ignore it.

The preferredSize property is a component's way of saying how big it wants to be to be comfortable. In the case of a Canvas, there is nothing to display, so its preferredSize is (0,0). Because of this, if it is placed in a layout manager that respected preferredSize(), like BorderLayout or FlowLayout, it will take up no space and appear invisible.

You should never "set" the preferredSize of any component from the outside. Swing components allow you to do this, but it is a very bad idea. The preferredSize should always be computed based on what the component displays. A Button, for example, figures out how big the text will be, and adds some room for the border around that text. A Panel asks its layout manager (assuming one has been set) for a preferredSize, so all of its contained components can be taken into account.

You should override the getPreferredSize() method of Canvas to return a size appropriate for what you are displaying. Depending on what is displayed, the preferredSize may need to change. For example, if you're displaying a graph and a new month is added to its x-axis, the preferred width may need to increase. Override getPreferredSize() to return the proper computed preferred size.