Best way to create/switch Views?

We use a Navigator in our application to handle switching between several views. The views are all created at once when the application starts so no extra work has to be done to display the view. I assumed this approach would improve performance when switching to another view and back since the view doesn’t have to be reconstructed every time, and it also preserves the state of the view, such as the selected tab. BoV does the same thing in its
, but notes that constructing the view in the enter() method has the advantage of the view being attached to the view container and the UI at that time.

Lacking said advantage may be related to our problem. Certain events in our application (which don’t happen nearly as often as switching views) require all the views to be recreated. This means that the old views should be detached so all the listeners associated with them can be removed and everything GC’d. However, since the other views are not currently attached to the UI, detach is never called, and the listeners (attached to the data source which is not reconstructed) still exist and fire causing all sorts of problems.

It appears that Navigator considers only the current view as “attached”. Is there a reliable way to either have all views be attached to the UI at once (setParent()?) or forcibly call detach (without causing a null pointer exception when AbstractClientConnector.detach() calls getUI()), or should we be creating the views in enter() every time and not hold any references to them elsewhere?

‘Attached’ is a Vaadin framework term that means ‘currently part of the visible UI hierarchy’. This means that views that are not visible at that time are always in a detached state from the point of view of Vaadin. Of course, if you have your own listeners in the views, they need to be aware of this. You should never call the attach or detach methods of a component yourself; that will only lead to more problems.

The way we (or at least I) usually deal with this is to always have a ‘create()’ method in all my views that can be called from anywhere. I can then put a flag in the view ‘isRefreshNeeded’, change it in my own listener method, and check that in the enter method of the view. This way you can still use the same view objects, you just recreate the innards when necessary.

Thanks for the tip, that flag is just what I needed.