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?
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.
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.
Related
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?
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.
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.
I create a little program that load a frame in which I added some panels.
When I click on some button it should show some panels and hide other.
I'm experiencing some difficult to do it, even because I don't really figure out the diference between setVisible(true), repaint() and validate() (that some friends of mine suggested to me).
I hope you can make me to understand!
Thank you.
Carefully read the API for JComponent. The usages are:
setVisible - it will hide or show your component altogether. If you set it as false, you won't see it at all.
repaint() - is called when the actual pixels need to be redrawn, this is done automatically. It's used, for example, when you move a window on top of your GUI and then move it away. The part that was covered needs to be redrawn.
validate() - you should call this when the layout of your GUI has changed and you need the manager to replace and redraw your GUI.
It's a bit more complicated than that, so again, carefully read the API.
setVisible(true): sets the component so that it's visible.
repaint(): calls the paint method on the component.
revalidate(): updates the component based on the root component
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?
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.
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.
just working on some code to do with java graphics, very simple example from a lecture I had today. Anyway, the internet seems to say that update will not be called by a System trigger such as resizing a frame etc. In this example, update is called by such a trigger (hence update and paint are called when I only expect paint to be called). He seemed to put it down to Operating Systems and different results on each.
Can anyone clarify this for me?
Working on windows 7
Thanks in advance
Ben
Here's a great article that really says it all:
http://java.sun.com/products/jfc/tsc/articles/painting/
1) Painting in AWT
To understand how AWT's painting API works, helps to know what
triggers a paint operation in a windowing environment. In AWT, there
are two kinds of painting operations: system-triggered painting, and
application-triggered painting.
2) System-triggered Painting
In a system-triggered painting operation, the system requests a
component to render its contents, usually for one of the following
reasons:
The component is first made visible on the screen.
The component is resized.
The component has damage that needs to be repaired. (For example, something that previously obscured the component has moved, and a
previously obscured portion of the component has become exposed).
3) App-triggered Painting
In an application-triggered painting operation, the component decides
it needs to update its contents because its internal state has
changed. (For example,. a button detects that a mouse button has been
pressed and determines that it needs to paint a "depressed" button
visual).
4) The Paint Method
Regardless of how a paint request is triggered, the AWT uses a
"callback" mechanism for painting, and this mechanism is the same for
both heavyweight and lightweight components. This means that a program
should place the component's rendering code inside a particular
overridden method, and the toolkit will invoke this method when it's
time to paint.
Does anyone know the rational for Java Frames and JFrames being set to invisible by default?
i.e. you have to call myFrameObject.setVisible(true) or you end up with an invisible application interface.
This has been bugging me since you don’t see this in other languages like C# or Objective-C. I was wondering if it was intended to be a time-saver or if the Java architects were just having a bad day.
Knowing this will help me understand the ultimate answer to life, the universe, and everything.
I always assumed it was so you could populate the window before displaying it. Otherwise you could see a bunch of controls shuffle around as they were added. Probably not a noticeable problem with todays machines + JITs, but in the early days of Java with slower machines and bytecode interpreters in the JVMs it might have made a difference.
It also mimics the way top-level windows work in X11: you create the window, and then later you "map" it (make it visible).
Remember, Swing components are not real components from the OS point of view. Every Swing component needs to be "realized". This is done by invoking the pack() or setVisible() methods. Only at this time will the Swing component be mapped to a peer component of the OS.
And remember when you add components to a visible GUI the components will not appear anyway because you need to invoke the layout manager to layout all the components. So even if the frame was visible automatically, in this case you would still need to invoke frame.validate() to make sure the components are layed out properly.
I think it is a better design to add all the components and then make it visibile once you have finished adding everything to the frame. This way you only layout the components once, not after every component is added. Maybe with other languages that use absolute sizes and positioning this is not a big deal because they don't have the concept of layout managers.