Why shouldn't I call setVisible(true) before adding components?

I've seen it written on this site a number of times (such as here, and here) that you mustn't call setVisible(true) before adding components to a JComponent, but I haven't seen an explanation, and information on the internet seems scarce.

Why is this the case, and what happens if you break the rule?


Solution 1:

You're not breaking anything if you call it first, but you will probably then need to call it again if you've added anything. Else Swing won't render the added components. You need to have the JVM call the JFrame's paint(...) method to have the JFrame's components rendered, and setVisible(true) will ask the JVM to do just this. If you've ever add components after calling setVisible(true) and don't see the components, you'll find that they'll "materialize" if you re-size the JFrame. This is because re-sizing it causes the operating system to ask Swing to repaint the GUI, and this will result in paint(...) being called.

Note that if you add a component after creating your GUI, you can call revalidate() and often repaint() on its container to get the new component laid out correctly and then rendered. The repaint() will definitely be necessary if the change in components involves a deletion, or a component being drawn where another component was visualized previously.

A book suggestion that I highly recommend: Filthy Rich Clients buy Guy and Haase. Just buy it! You won't regret the purchase.

Solution 2:

Amplifying on @Hovercraft's helpful analysis, you may also have to re-pack() the enclosing top-level container. This example, which adds elements to a JList after setVisible(), may illustrate the trade-offs.