Granny's Programming Pearls
"inside of every large program is a small program struggling to get out"
JavaRanch.com/granny.jsp
Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

possible bug with FlowLayout and setVisible() ?  RSS feed

 
dave Lande
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Build a GUI . Use ContentPane(). Add a JTextField to the GUI. Make it invisible with setVisible(false). Later try to make it visible with
setVisible(true). It does not appear. Resizing the frame makes it visible.
Coding repaint() does not make the JTextField appear..

Do the same thing, (exact same code) but this time use a different Layout Manager - say GridLayout. The JTextField appears when setVisible(true) is
executed.

Is there a known bug with FlowLayout and setVisible() which prevents a paint event from happening?
 
Rob Spoor
Sheriff
Posts: 21090
85
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try doLayout() as well as repaint().
The layout manager does not place the components if they are invisible, so the previously invisible component probably is placed somewhere where you can't see it. doLayout() is a request to the layout manager to layout the components again - something that is automatically done when resizing.
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First, the API states that application code should generally call validate() rather than doLayout() directly. When working with Swing you should use revalidate(), it will validate the first validateRoot found in the container heirarchy and is generally a more preferred behavior.

Second, understanding why one layout manager requires a revalidate() call and another doesn't requires a deeper look at layout managers. Understand that they automatically update when their size, location or internal layout changes. FlowLayout uses layoutContainer(Contanier) rather than having components added directly to it. When layoutContainer() is invoked it essentially iterates through the Container's components. If the component is visible, it assigns it a size equal to it's preferred size and then checks to see if that, combined with insets and the horizontal gap, will fit in the Container's width. Once it reaches the end of a row it moves all the components to their proper locations. If it is not visible it is ignored. The component has no size set and is never moved. When you change the visibility of the component there is no effect because the component hasn't been put anywhere to be painted. A GridLayout couldn't care less whether or not a component is visible. If it's there, it's getting it's own rectangle equal to all the other component's rectangles. When you change visibility it shows up because it was placed and sized while it was not visible. A change in visibility does not trigger layout to be performed and thus you are required to trigger it yourself. This is the intended behavior as far as I'm aware.

So, add revalidate() after setVisible(true) and your problems should go away.

EDIT: Edited to give a better answer after a brief look at the source and API.
[ October 28, 2005: Message edited by: Ken Blair ]
 
dave Lande
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks... both of you.

Dave
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!