Class ViewManager
BaseView instances
in an MDI application.
Responsibilities
- Maintain the ordered collection of currently-registered views.
- Maintain the "Views"
JMenu: one item per registered view, plus italic placeholder items for lazy configurations whose views have not yet been created. - Notify
IViewListeners when views are added or removed. - Track the active
VirtualView(if any) and route view activation requests to it. - Support lazy registration of views through
ViewConfiguration.
Views menu conventions
Each realized view has a normal-weight menu item labelled with the view's
title. Unrealized lazy configurations have an italic item labelled with
the configuration's menu title
(no "Create " prefix — the italic style alone signals "not yet open").
When a lazy view is realized its italic placeholder is replaced in-place by
the normal item so that menu ordering is preserved.
Threading
All Swing state mutations (menu items, view visibility) are dispatched to
the EDT. The backing view list is guarded by synchronized(this) for
all add, remove, and iteration operations.
Migration note
This class previously extended Vector for legacy iteration
compatibility. It now implements Iterable<BaseView> instead,
which is sufficient for for-each loops and is a strictly cleaner
contract. Code that called Vector-specific methods (e.g.
elementAt, indexOf) should migrate to get(int) and
getViews() respectively.
-
Method Summary
Modifier and TypeMethodDescriptionbooleanRegister a view with this manager.voidaddConfiguration(ViewConfiguration<?> config) Register aViewConfiguration.voidaddViewListener(IViewListener listener) Add a view lifecycle listener.voidclear()Removes all registered views through the standard cleanup path.booleanReturnstrueif the given view is currently registered.get(int index) Returns the view at the given zero-based index in registration order.static ViewManagerReturns the singletonViewManagerinstance, creating it on first call.Returns the managed Views menu, creating a default one lazily if none has been set viasetViewMenu(JMenu).getViews()Returns an unmodifiable, point-in-time snapshotListof all currently registered views in registration order.iterator()Returns an iterator over the currently registered views in registration order.voidAsk the activeVirtualViewto scroll so that the column containing the given view becomes visible.booleanUnregister a view.voidremoveViewListener(IViewListener listener) Remove a view lifecycle listener.voidRealizes every currently-unrealized lazy configuration that was open the last timeDesktop's layout was saved -- the counterpart toDesktop's own position-only restoration, which can only reposition views the application already creates on its own; it has no way to reopen an optional (lazy) view the application doesn't otherwise create.voidsetViewMenu(JMenu viewMenu) Replace the managed Views menu.intsize()Returns the number of currently registered views.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface java.lang.Iterable
forEach, spliterator
-
Method Details
-
getInstance
Returns the singletonViewManagerinstance, creating it on first call.- Returns:
- the global
ViewManager
-
iterator
Returns an iterator over the currently registered views in registration order.The iterator operates on a snapshot copy taken at call time, so it is safe to call
add(BaseView)orremove(BaseView)while iterating without aConcurrentModificationException. The snapshot reflects the state of the registry at the momentiterator()is called; views added or removed afterwards are not visible through the returned iterator. -
getViews
Returns an unmodifiable, point-in-time snapshotListof all currently registered views in registration order.The returned list will not reflect subsequent additions or removals. Callers that need to iterate once should prefer
iterator(); callers that need random access or must pass aListto other APIs should use this method.- Returns:
- an unmodifiable snapshot; never
null
-
setViewMenu
Replace the managed Views menu.The new menu is immediately populated from the current set of registered views and unrealized lazy configurations.
- Parameters:
viewMenu- the menu to manage;nullclears the reference
-
getViewMenu
Returns the managed Views menu, creating a default one lazily if none has been set viasetViewMenu(JMenu).This method never returns
null.- Returns:
- the Views menu
-
add
Register a view with this manager.A corresponding menu item is added to the Views menu. Registered
IViewListeners are notified. If the view is aVirtualViewit becomes the active virtual desktop.This method is idempotent: registering the same instance twice is a no-op.
- Parameters:
view- the view to register; ignored ifnullor already registered- Returns:
trueif the view was newly added
-
remove
Unregister a view.Its menu item is removed, registered listeners are notified, and the view is disposed on the EDT.
- Parameters:
view- the view to remove; ignored ifnullor not registered- Returns:
trueif the view was removed
-
clear
public void clear()Removes all registered views through the standard cleanup path.Each view is disposed and its listeners are notified in reverse registration order so that dependent views are torn down before the views they depend on.
-
contains
Returnstrueif the given view is currently registered.- Parameters:
view- the view to test;nullalways returnsfalse- Returns:
trueif registered
-
size
public int size()Returns the number of currently registered views.- Returns:
- the view count; never negative
-
get
Returns the view at the given zero-based index in registration order.- Parameters:
index- zero-based position- Returns:
- the view at that position
- Throws:
IndexOutOfBoundsException- ifindexis out of range
-
addConfiguration
Register aViewConfiguration.If the configuration is eager (
ViewConfiguration.lazilyisfalse) the view is created immediately by callingViewConfiguration.getView(). If it is lazy, an italic placeholder item is inserted into the Views menu; the view is created only when the user selects that item.- Parameters:
config- the configuration to register; ignored ifnull
-
restorePreviouslyOpenLazyViews
public void restorePreviouslyOpenLazyViews()Realizes every currently-unrealized lazy configuration that was open the last timeDesktop's layout was saved -- the counterpart toDesktop's own position-only restoration, which can only reposition views the application already creates on its own; it has no way to reopen an optional (lazy) view the application doesn't otherwise create.Call this once at startup, after the saved layout has already been loaded (see
Desktop#loadConfigurationFile(), invoked byBaseMDIApplication#standardVirtualDesktopReadybefore it runs the application's own default-layout hook) so thatViewConfiguration.wasOpenInSavedLayout()has saved data to check against -- calling this before the layout is loaded is a harmless no-op, not an error, since every probe simply reportsfalse.Each newly-realized view's own
ViewConfiguration.getView()call restores its saved position through the exact same path already used when a user manually opens a lazy view that happens to have saved layout data. Two things that path assumes are true only for a single, user-initiated open are corrected here for the bulk-restore case:- Menu placeholder. Realizing a lazy configuration by
calling
getView()directly (as opposed to clicking its italic placeholder, whose action listener also swaps the placeholder for the real menu item) leaves the stale italic placeholder in the Views menu next to a second, correct item --ensureRealizedMenuItem(edu.cnu.mdi.view.BaseView)unconditionally appends one the moment the view registers itself. Swapped here exactly as the placeholder's own listener would. - Virtual-desktop column. Each restored view's placement
independently navigates to its own saved column --
correct for a single interactive open, but restoring several
views at once would leave whichever one finishes last silently
deciding the startup column, undoing the application's own
explicit startup placement (e.g. a
defaultViewLayout()override that documents relying on running last to "win" the same placement race, for exactly this reason). The column showing when this method was called is restored via one moreinvokeLater, which FIFO ordering guarantees runs after every placement this method triggered.
- Menu placeholder. Realizing a lazy configuration by
calling
-
makeViewVisibleInVirtualWorld
Ask the activeVirtualViewto scroll so that the column containing the given view becomes visible.This is a no-op if no virtual view is registered, or if
viewis itself the virtual view.- Parameters:
view- the view to make visible in the virtual desktop
-
addViewListener
Add a view lifecycle listener.Duplicate registrations are silently ignored.
- Parameters:
listener- the listener to add; ignored ifnull
-
removeViewListener
Remove a view lifecycle listener.- Parameters:
listener- the listener to remove; ignored ifnull
-