I'm developing an application, in which all UI components are defined via an XML file. I read the xml and depeding on it the UI is composed. After the user made some changes a new XML is provided and the UI is refreshed accordingly. Now I get some really annoying rendering issues, especially with several scroll areas, where either parts of the UI are cut of (and only get visible, when I resize the window) or the scrollbar is alread scrolled to some point, but it should just show the top of the content.
I assume this is an Event Dispatch Thread issue and found some really useful info about it here: http://www.javapractices.com/topic/TopicAction.do?Id=153
You can read there:"This thread (the EDT) becomes active after a component becomes realized : either pack, show, or setVisible(true) has been called"
Parsing the XML is not done in the EDT and also instantiating the components and adding them to their parent panels. Only after all components are created they are finally added to the MainPane via the EDT.
However is seems in some cases creating components and adding them to panels, already starts the EDT. So things get messed up.
Does someone have detailed knowledge which methods call pack, show, or setVisible(true) and therefore start the EDT?
Thanks a lot
I had the same issues with scroll panes, try setting the following property on them:
scrollpane.getViewport().setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
As in the comments, all Swing components must be created on the EDT or your going to get weird stuff happening.
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'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
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.
I have an application that includes a JTabbedPane and two tabs with some components. My problem is when I click on another tab, it's components do not appear immediately; but when the mouse courser moves over each component (JCheckBox, JButton and so on) of the tab, the components will appear but not correctly (see below image).
alt text http://hivaonline.persiangig.com/1.gif
alt text http://hivaonline.persiangig.com/2.gif
This is my CODE . . .
Are you mixing some awt and swing stuff?
This could probably make such unpredictable effects.
Can you see an exception on the console? Exceptions in Event Dispatching Thread can cause such behavior.
As others have observed, your code is incomplete. As a guide, consider this article on the benefits of a Short, Self Contained, Correct (Compilable), Example. Several such examples are discussed in How to Use Tabbed Panes. You might compare them with what you're doing.
thanks a milion for your response, the problem was calling repaint() of a component that called when i changing it position, the location of marker must be change every time the map move by user or page event occurred, so i think calling repaint() caused a loop and other component not paint correctly.