Before evaluation there is need to know a couple details of JScrollPane implementation:
1. ScrollBar visibility are set in ScrollPaneLayout#layoutContainer. That method is invoked after invalidate is invoked, therefore the layoutContainer method isn't invoked directly but postponed like invokeLater does.
2. ScrollBar values are set in the BasicScrollPaneUI#syncScrollPaneWithViewport method. That method is invoked from JViewport#fireStateChanged and can be invoked from the ScrollPaneLayout#layoutContainer method if viewport.bounds are changed, for example.
Below are four lines of code from the attached Test.java that shows the problem with comments:
/* BasicScrollPaneUI#syncScrollPaneWithViewport will be invoked and scrollbars will be initialized for empty text. Note: scrollbars visibility is not corrected yet, but