Summary
In Swing there is the possibility of validating and invalidating JComponent
s.
invalidate()
marks a component-hierarchy as invalid and either it is then validated programmatically or implicitelyvalidate()
validates a component hierarchy, i.e. basically checks layout and ensures it is uptodaterevalidate()
does both and thus constitutes an explicitvalidate()
call
This information is aligned with what is said here:
Difference between validate(), revalidate() and invalidate() in Swing GUI
Scenario
It is however unclear when exactly to use these functions.
In my scenario I implemented a JPanel
extension, where another thread would fire events and these use SwingUtilities.invokeLater
to queue changes to the panel. These changes constitute of updates to two JLabel
s.
These update functions look something like this:
SwingUtilities.invokeLater( () -> { iconLabel.setIcon( myIcon ) ); textLabel.setText( "Bla" ); } );
Initially I assumed, changing the icon was going to be a possible problem, so I used either invalidate()
or revalidate()
in the function, in order to notify Swing, that I want to ensure this layout is updated and the hierarchy checked.
However component invalidation had other UI related side effects and so these lines were removed. The panel however keeps updating just fine.
Question
Thus, I want to know, what are the exact conditions, when validate()
/ invalidate()
/ revalidate()
need to be called?
Is it necessary at all to call these functions when operating on the EDT, which I obviously do in the example above, since SwingUtilities.invokeLater
is used? When are these functions allowed to be omitted?
I have checked a multitude of questions on SO, however I cannot find clear rules on usage.
- It is stated here, that these methods are thread-safe and do not need to be invoked on the EDT, even though this refers to
JavaFX
: https://docs.oracle.com/javase/tutorial/uiswing/layout/howLayoutWorks.html - The documentation on
JComponent
states, that invoking e.g.revalidate()
is not necessary at all (anymore?) to issue updates: https://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html
Advertisement
Answer
My simple way of looking at this is that revalidate()
is used when a property of a Swing component is changed that will possibly affect the size of the component. Since the size of the component may change the layout of components on the panel may be effected. So the revalidate()
is basically used to make sure the layout manager is invoked.
Swing components are smart enough to invoke revalidate()
and repaint()
when needed. Note AWT components did not invoke invalidate() and validate() automatically so it was more of an issue when using AWT.
That is when you invoke any “setter” method on a Swing component it does the revalidate()
and repaint()
for you.
That is why in your simple example above you don’t need to invoke revalidate()
.
One case where you need to invoke revalidate()
manually is when you add components to a panel on a visible GUI. After you add all the components to the panel you would invoke revalidate()
to invoke the layout manager of the panel.