11508 Control, DefaultControl refactoring
authorStephen Talley <stephen.talley@sun.com>
Tue, 22 Sep 2009 16:46:54 -0400
changeset 360 8943c58ad2f5
parent 359 2bd667ea3c04
child 361 d3611020acea
11508 Control, DefaultControl refactoring
usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/AppRootControl.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/control/Control.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/control/DefaultControl.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/control/SwingControl.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/control/TabbedControl.java
usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/GlobalControl.java
usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/MimeTypeControl.java
usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/MimeTypesControl.java
usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/ModuleControl.java
usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/ModulesControl.java
usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/VirtualHostGeneralControl.java
usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/VirtualHostSSLControl.java
usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CoreAdmSettingsTab.java
usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CoresTab.java
usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CustomCoreSchemeEditControl.java
usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/FirewallDefaultTab.java
usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/FirewallOpenPortsTab.java
usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/FirewallOverrideTab.java
usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/GlobalControl.java
usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/MainControl.java
usr/src/java/vpanels/panels/sharemgr/org/opensolaris/os/vp/panels/sharemgr/client/swing/MainControl.java
usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/InstanceEditControl.java
usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/ServiceEditControl.java
usr/src/java/vpanels/panels/svcs/org/opensolaris/os/vp/panels/svcs/client/swing/InstancesControl.java
--- a/usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/AppRootControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/client/org/opensolaris/os/vp/client/swing/AppRootControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -120,49 +120,6 @@
     //
 
     @Override
-    public Control getChildControl(String id) {
-	Control child = super.getChildControl(id);
-	if (child == null) {
-	    ClientContext context = instance;
-	    try {
-		// Throws IOException
-		MBeanServerConnection mbsc = context.getConnectionInfo().
-		    getConnector().getMBeanServerConnection();
-
-		// Get proxy to VSystemMXBean
-		VSystemMXBean appMBean = VSystemMXBean.Util.getSystemBean(mbsc);
-
-		PanelBundle bundle = appMBean.getRegisteredPanel(id);
-		if (bundle != null) {
-		    PanelDescriptor descriptor =
-			instance.getPanelDescriptorFactory().
-			getBestFitPanelDescriptor(bundle);
-
-		    if (descriptor != null) {
-			child = descriptor.getControl();
-
-			if (child != null) {
-			    addChildren(child);
-			}
-		    }
-		}
-	    } catch (IOException e) {
-		context.getLog().log(Level.WARNING, "error contacting server",
-		    e);
-	    } catch (PanelConfigException e) {
-		context.getLog().log(Level.WARNING,
-		    "server couldn't provide panel: " + id, e);
-	    }
-	}
-
-	return child;
-    }
-
-    //
-    // DefaultControl methods
-    //
-
-    @Override
     public void childStarted(Control control) {
 	super.childStarted(control);
 
@@ -243,6 +200,49 @@
     }
 
     @Override
+    public Control getChildControl(String id) {
+	Control child = super.getChildControl(id);
+	if (child == null) {
+	    ClientContext context = instance;
+	    try {
+		// Throws IOException
+		MBeanServerConnection mbsc = context.getConnectionInfo().
+		    getConnector().getMBeanServerConnection();
+
+		// Get proxy to VSystemMXBean
+		VSystemMXBean appMBean = VSystemMXBean.Util.getSystemBean(mbsc);
+
+		PanelBundle bundle = appMBean.getRegisteredPanel(id);
+		if (bundle != null) {
+		    PanelDescriptor descriptor =
+			instance.getPanelDescriptorFactory().
+			getBestFitPanelDescriptor(bundle);
+
+		    if (descriptor != null) {
+			child = descriptor.getControl();
+
+			if (child != null) {
+			    addChildren(child);
+			}
+		    }
+		}
+	    } catch (IOException e) {
+		context.getLog().log(Level.WARNING, "error contacting server",
+		    e);
+	    } catch (PanelConfigException e) {
+		context.getLog().log(Level.WARNING,
+		    "server couldn't provide panel: " + id, e);
+	    }
+	}
+
+	return child;
+    }
+
+    //
+    // DefaultControl methods
+    //
+
+    @Override
     public String getTitle() {
 	return Finder.getString("app.title");
     }
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/control/Control.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/control/Control.java	Tue Sep 22 16:46:54 2009 -0400
@@ -30,6 +30,7 @@
 import java.net.*;
 import java.util.*;
 import org.opensolaris.os.vp.panel.common.action.*;
+import org.opensolaris.os.vp.util.misc.Finder;
 
 /**
  * The {@code Control} class encapsulates the control over all aspects of a
@@ -37,6 +38,14 @@
  */
 public abstract class Control implements Navigable, HasControl {
     //
+    // Enums
+    //
+
+    public enum UnsavedChangesAction {
+	CANCEL, DISCARD, SAVE
+    }
+
+    //
     // Static data
     //
 
@@ -50,10 +59,11 @@
     // Instance data
     //
 
-    private Navigator navigator;
     private String id;
     private String name;
+    private Navigator navigator;
     private Map<String, String> parameters;
+    private Control child;
 
     private StructuredAction<?, ?, ?> resetAction =
 	new StructuredAction<Object, Object, Object>(null) {
@@ -61,7 +71,7 @@
 	    public Object work(Object pInput, Object rtInput)
 		throws ActionAbortedException, ActionFailedException {
 
-		reset();
+		resetAll();
 		return null;
 	    }
 	};
@@ -73,7 +83,7 @@
 		throws ActionAbortedException, ActionFailedException {
 
 		try {
-		    save();
+		    saveAll();
 		} catch (ActionUnauthorizedException e) {
 		    throw new ActionFailedException(e);
 		}
@@ -158,11 +168,44 @@
     //
 
     /**
+     * Saves the given child as the {@link #getRunningChild running child}.
+     * Called by {@link #descendantStarted} when a child of this {@code Control}
+     * is started.
+     *
+     * @exception   IllegalStateException
+     *		    if the running child has already been set
+     */
+    public void childStarted(Control child) {
+	if (this.child != null) {
+	    throw new IllegalStateException("child already started");
+	}
+
+	this.child = child;
+    }
+
+    /**
+     * Removes the given child as the {@link #getRunningChild running child}.
+     * Called by {@link #descendantStopped} when a child of this {@code Control}
+     * is stopped.
+     *
+     * @exception   IllegalStateException
+     *		    if the given control is not the running child
+     */
+    public void childStopped(Control child) {
+	if (this.child != child) {
+	    throw new IllegalStateException("not running child");
+	}
+
+	this.child = null;
+    }
+
+    /**
+     * Calls {@link #childStarted} iff the given path refers to an immediate
+     * child of this {@code Control}.
+     * <p/>
      * Called by the {@link Navigator} just after a descendant {@code Control}
      * of this {@code Control} has been started and pushed onto the {@link
      * Navigator}'s {@code Control} stack.
-     * <p>
-     * This default implementation does nothing.
      *
      * @param	    path
      *		    the path to the descendant {@code Control}, relative to this
@@ -170,14 +213,18 @@
      *		    the last element)
      */
     public void descendantStarted(Control[] path) {
+	if (path.length == 1) {
+	    childStarted(path[0]);
+	}
     }
 
     /**
+     * Calls {@link #childStopped} iff the given path refers to an immediate
+     * child of this {@code Control}.
+     * <p/>
      * Called by the {@link Navigator} just after a descendant {@code Control}
      * of this {@code Control} has been stopped and popped off the {@link
      * Navigator}'s {@code Control} stack.
-     * <p>
-     * This default implementation does nothing.
      *
      * @param	    path
      *		    the path to the descendant {@code Control}, relative to this
@@ -185,6 +232,9 @@
      *		    the last element)
      */
     public void descendantStopped(Control[] path) {
+	if (path.length == 1) {
+	    childStopped(path[0]);
+	}
     }
 
     /**
@@ -244,10 +294,10 @@
      * intermediate stop to another {@code Control}).  This method is called by
      * the {@link Navigator} <strong>after</strong> this {@code Control} has
      * been started.
-     * <p>
+     * <p/>
      * If the first element is {@code null}, the returned path is considered
      * absolute.  Otherwise, it is relative to this {@code Control}.
-     * <p>
+     * <p/>
      * This default implementation returns {@code null}.
      *
      * @return	    a {@link Navigable} array, or {@code null} if no automatic
@@ -258,6 +308,17 @@
     }
 
     /**
+     * Gets the help URL for this {@code DefaultControl}.
+     * <p/>
+     * This default implementation returns {@code null}.
+     *
+     * @return	    a URL, or {@code null} if no URL applies
+     */
+    public URL getHelpURL() {
+	return null;
+    }
+
+    /**
      * Gets the {@link Navigator} passed to the {@link #start} method, if
      * this {@code Control} is started, or {@code null} if this {@code Control}
      * is stopped.
@@ -274,6 +335,14 @@
     }
 
     /**
+     * Gets the child {@code Control} currently running, or {@code null} if
+     * there is none.
+     */
+    public Control getRunningChild() {
+	return child;
+    }
+
+    /**
      * Gets a {@link StructuredAction} that invokes {@link #saveAll}.
      */
     public StructuredAction<?, ?, ?> getSaveAction() {
@@ -281,19 +350,38 @@
     }
 
     /**
+     * Called by {@link #stop} when there are unsaved changes, gets the action
+     * that should be taken to handle them.
+     * <p/>
+     * This default implementation returns {@link UnsavedChangesAction#DISCARD}.
+     * Subclasses may wish to prompt the user to determine the appropriate
+     * action to take.
+     */
+    protected UnsavedChangesAction getUnsavedChangesAction() {
+	return UnsavedChangesAction.DISCARD;
+    }
+
+    /**
      * Gets a hint as to whether this {@code Control} should be returned by a
      * parent {@code Control}'s {@link #getBrowsable} method.  The parent may
      * choose to ignore this hint.
+     * <p/>
+     * This default implementation returns {@code true}.
      */
-    public abstract boolean isBrowsable();
+    public boolean isBrowsable() {
+	return true;
+    }
 
     /**
-     * Indicates whether there are any unsaved changes; specifically, whether
-     * {@link #save} should be called before stopping this {@code Control}.
+     * Indicates whether there are any unsaved changes in this {@code Control}.
+     * <p/>
+     * This default implementation returns {@code false}.
      */
-    protected abstract boolean isSaveNeeded();
+    protected boolean isSaveNeeded() {
+	return false;
+    }
 
-    protected boolean isStarted() {
+    public boolean isStarted() {
 	return navigator != null;
     }
 
@@ -324,15 +412,12 @@
      *		    see {@link #reset}
      *
      * @exception   IllegalStateException
-     *		    if this method is called when this {@link Control} is not
-     *		    started
+     *		    if this {@link Control} is not started
      */
     protected void resetAll() throws ActionAbortedException,
 	ActionFailedException {
 
-	if (navigator == null) {
-	    throw new IllegalStateException();
-	}
+	assertStartState(true);
 
 	List<Control> path = navigator.getPath();
 	if (!path.contains(this)) {
@@ -382,15 +467,12 @@
      *		    see {@link #save}
      *
      * @exception   IllegalStateException
-     *		    if this method is called when this {@link Control} is not
-     *		    started
+     *		    if this {@link Control} is not started
      */
     protected void saveAll() throws ActionAbortedException,
 	ActionFailedException, ActionUnauthorizedException {
 
-	if (navigator == null) {
-	    throw new IllegalStateException();
-	}
+	assertStartState(true);
 
 	List<Control> path = navigator.getPath();
 	if (!path.contains(this)) {
@@ -422,21 +504,12 @@
 	this.name = name;
     }
 
-    protected void setNavigator(Navigator navigator) {
-	this.navigator = navigator;
-    }
-
-    private void setParameters(Map<String, String> parameters) {
-	this.parameters = parameters;
-    }
-
     /**
+     * Saves references to the given {@link #getNavigator Navigator} and {@link
+     * #getParameters initialization parameters}.
+     * <p/>
      * Called by the {@link Navigator} when this {@code Control} is pushed onto
      * the {@code Control} stack.
-     * <p>
-     * This default implementation saves references to the given {@link
-     * #getNavigator Navigator} and {@link #getParameters initialization
-     * parameters}.
      *
      * @param	    navigator
      *		    the {@link Navigator} that handles navigation to/from this
@@ -453,19 +526,27 @@
      * @exception   InvalidParameterException
      *		    if this {@code Control} could not be started due to invalid
      *		    intialization parameters
+     *
+     * @exception   IllegalStateException
+     *		    if this {@link Control} is already started
      */
     public void start(Navigator navigator, Map<String, String> parameters)
 	throws NavigationAbortedException, InvalidParameterException {
-	setNavigator(navigator);
-	setParameters(parameters);
+
+	assertStartState(false);
+	this.navigator = navigator;
+	this.parameters = parameters;
     }
 
     /**
+     * If {@code isCancel} is {@code false}, saves, resets, or cancels changes
+     * {@link #isSaveNeeded if necessary}, based on the return value of {@link
+     * #getUnsavedChangesAction}.  Then resets the references to the {@link
+     * #getNavigator Navigator} and {@link #getParameters initialization
+     * parameters}.
+     * <p/>
      * Called by the {@link Navigator} prior to this {@code Control} being
      * removed as the current {@code Control}.
-     * <p>
-     * This default implementation resets the reference to the {@code
-     * Navigator} and removes any set parameters.
      *
      * @param	    isCancel
      *		    {@code true} if this {@code Control} is being stopped as
@@ -474,10 +555,48 @@
      * @exception   NavigationAbortedException
      *		    if this {@code Control} should remain the current {@code
      *		    Control}
+     *
+     * @exception   IllegalStateException
+     *		    if this {@link Control} is not started
      */
     public void stop(boolean isCancel) throws NavigationAbortedException {
-	setNavigator(null);
-	setParameters(null);
+	assertStartState(true);
+
+	if (!isCancel && isSaveNeeded()) {
+	    try {
+		switch (getUnsavedChangesAction()) {
+		    case SAVE:
+			getSaveAction().invoke();
+			break;
+
+		    case DISCARD:
+			getResetAction().invoke();
+			break;
+
+		    default:
+		    case CANCEL:
+			throw new NavigationAbortedException();
+		}
+
+	    // Thrown by invoke()
+	    } catch (ActionException e) {
+		throw new NavigationAbortedException(e);
+	    }
+	}
+
+	this.navigator = null;
+	this.parameters = null;
+    }
+
+    //
+    // Private methods
+    //
+
+    private void assertStartState(boolean started) {
+	if (isStarted() != started) {
+	    throw new IllegalStateException(started ? "control started" :
+		"control not started");
+	}
     }
 
     //
@@ -485,6 +604,19 @@
     //
 
     /**
+     * Builds a help URL from a page and section, falling back to the
+     * page if the section is invalid.
+     */
+    protected static URL buildHelpURL(String page, String section) {
+	URL url = Finder.getResource(page);
+	try {
+	    url = new URL(url, section);
+	} catch (MalformedURLException ignore) {
+	}
+	return url;
+    }
+
+    /**
      * Decodes the given encoded {@code String} into an identifier and
      * parameters, encapsulated by a {@link SimpleNavigable}.
      *
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/control/DefaultControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/control/DefaultControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -26,13 +26,12 @@
 
 package org.opensolaris.os.vp.panel.common.control;
 
-import java.net.*;
+import java.net.URL;
 import java.util.*;
+import javax.help.HelpBroker;
 import org.opensolaris.os.vp.panel.common.ClientContext;
 import org.opensolaris.os.vp.panel.common.action.*;
-import org.opensolaris.os.vp.panel.common.model.HasPanelDescriptor;
-import org.opensolaris.os.vp.panel.common.model.PanelDescriptor;
-import org.opensolaris.os.vp.util.misc.Finder;
+import org.opensolaris.os.vp.panel.common.model.*;
 
 /**
  * The {@code DefaultControl} class is a {@link Control} that provides a
@@ -42,14 +41,6 @@
     implements HasPanelDescriptor<P> {
 
     //
-    // Enums
-    //
-
-    public enum UnsavedChangesAction {
-	CANCEL, DISCARD, SAVE
-    }
-
-    //
     // Instance data
     //
 
@@ -58,7 +49,6 @@
     protected List<Control> children = new ArrayList<Control>();
     private String savedTitle;
     private boolean titleIsSaved;
-    private Control child;
 
     // Flag to ClassUtil.getCallerClass
     private static int NOT_CALLER;
@@ -118,28 +108,6 @@
     //
 
     /**
-     * Calls {@link #childStarted} iff the given path refers to an immediate
-     * child of this {@code DefaultControl}.
-     */
-    @Override
-    public void descendantStarted(Control[] path) {
-	if (path.length == 1) {
-	    childStarted(path[0]);
-	}
-    }
-
-    /**
-     * Calls {@link #childStopped} iff the given path refers to an immediate
-     * child of this {@code DefaultControl}.
-     */
-    @Override
-    public void descendantStopped(Control[] path) {
-	if (path.length == 1) {
-	    childStopped(path[0]);
-	}
-    }
-
-    /**
      * Calls {@link #ensureChildrenCreated}, then iterates through all {@link
      * Control}s added via {@link #addChildren addChildren} until it finds one
      * whose {@link Control#getId getId} method returns a value matching {@code
@@ -164,7 +132,7 @@
      * Calls {@link #ensureChildrenCreated}, then returns a list of all child
      * {@link Control}s that return {@code true} from their {@link #isBrowsable}
      * methods.
-     * <p>
+     * <p/>
      * Subclasses may wish to override this method to apply different criteria
      * to the returned list.
      */
@@ -204,31 +172,9 @@
     }
 
     /**
-     * Default implementation that returns {@code true}.
-     */
-    @Override
-    public boolean isBrowsable() {
-	return true;
-    }
-
-    /**
-     * Default implementation that returns {@code false}.
-     */
-    @Override
-    protected boolean isSaveNeeded() {
-	return false;
-    }
-
-    /**
-     * <ol>
-     *	 <li>
-     *	   Calls the {@link Control#start superclass implementation}.
-     *	 </li>
-     *	 <li>
-     *	   {@link ClientContext#setTitle Sets the title}, if non-{@code null},
-     *	   of this {@code DefaultControl}'s {@code ClientContext}.
-     *	 </li>
-     * </ol>
+     * Calls the {@link Control#start superclass implementation}, then {@link
+     * ClientContext#setTitle sets the title}, if non-{@code null}, of this
+     * {@code DefaultControl}'s {@code ClientContext}.
      */
     @Override
     public void start(Navigator navigator, Map<String, String> parameters)
@@ -248,37 +194,12 @@
     }
 
     /**
-     * If a {@code #isSaveNeeded save is needed}, {@code
-     * #getUnsavedChangesAction prompts} the user to save, discard, or cancel.
-     * <p/>
-     * Then calls the {@link Control#stop superclass implementation}, and
+     * Calls the {@link Control#stop superclass implementation}, then
      * {@link ClientContext#setTitle resets the title} of this {@code
      * DefaultControl}'s {@code ClientContext}.
      */
     @Override
     public void stop(boolean isCancel) throws NavigationAbortedException {
-	if (!isCancel && isSaveNeeded()) {
-	    try {
-		switch (getUnsavedChangesAction()) {
-		    case SAVE:
-			getSaveAction().invoke();
-			break;
-
-		    case DISCARD:
-			getResetAction().invoke();
-			break;
-
-		    default:
-		    case CANCEL:
-			throw new NavigationAbortedException();
-		}
-
-	    // Thrown by invoke()
-	    } catch (ActionException e) {
-		throw new NavigationAbortedException(e);
-	    }
-	}
-
 	super.stop(isCancel);
 
 	if (titleIsSaved) {
@@ -302,43 +223,10 @@
     }
 
     /**
-     * Builds a help URL from a page and section, falling back to the
-     * page if the section is invalid.
-     */
-    protected URL buildHelpURL(String page, String section) {
-	URL url = Finder.getResource(page);
-	try {
-	    url = new URL(url, section);
-	} catch (MalformedURLException ignore) {
-	}
-	return url;
-    }
-
-    /**
-     * Saves the given child as the {@link #getRunningChild running child}.
-     * Called by {@link #descendantStarted} when a child of this {@code
-     * DefaultControl} is started.
-     */
-    public void childStarted(Control child) {
-	assert (this.child == null);
-	this.child = child;
-    }
-
-    /**
-     * Removes the given child as the {@link #getRunningChild running child}.
-     * Called by {@link #descendantStopped} when a child of this {@code
-     * DefaultControl} is stopped.
-     */
-    public void childStopped(Control child) {
-	assert (this.child == child);
-	this.child = null;
-    }
-
-    /**
      * Ensures that any child {@link Control}s that should be available from the
      * {@link #getChildControl} method have been created.  This method is called
      * from the {@link #getChildControl} and {@link #getBrowsable} methods.
-     * <p>
+     * <p/>
      * This default implementation does nothing.
      */
     protected void ensureChildrenCreated() {
@@ -349,17 +237,6 @@
     }
 
     /**
-     * Gets the help URL for this {@code DefaultControl}.
-     * <p>
-     * This default implementation returns {@code null}.
-     *
-     * @return	    a URL, or {@code null} if no URL applies
-     */
-    public URL getHelpURL() {
-	return null;
-    }
-
-    /**
      * Convenience method to retrieve a parameter from a given parameter {@code
      * Map}, or throw a {@link MissingParameterException} if the parameter does
      * not exist.  Intended to be called from within {@link #start}.
@@ -375,18 +252,10 @@
     }
 
     /**
-     * Gets the child {@code Control} currently running, or {@code null} if
-     * there is none.
-     */
-    public Control getRunningChild() {
-	return child;
-    }
-
-    /**
      * Gets the title of this {@code DefaultControl}.  If non-{@code null}, this
      * value is set in this {@code DefaultControl}'s {@link
      * ClientContext#setTitle} when started.
-     * <p>
+     * <p/>
      * This default implementation returns {@code null}.
      */
     public String getTitle() {
@@ -394,21 +263,8 @@
     }
 
     /**
-     * Called by {@link #stop} when there are unsaved changes, gets the action
-     * that should be taken to handle them.
-     * <p/>
-     * This default implementation returns {@link UnsavedChangesAction#DISCARD}.
-     * Subclasses may wish to prompt the user to determine the appropriate
-     * action to take.
-     */
-    protected UnsavedChangesAction getUnsavedChangesAction() {
-	return UnsavedChangesAction.DISCARD;
-    }
-
-    /**
      * Loads this {@code DefaultControl}'s {@code #getHelpURL help URL} into the
-     * {@code HelpBroker} of the {@link #getClientContext ClientContext} of its
-     * {@link #getPanelDescriptor PanelDescriptor}
+     * {@code HelpBroker} of the {@link #getClientContext ClientContext}.
      */
     protected void loadHelpURL() {
 	URL url = getHelpURL();
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/control/SwingControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/control/SwingControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -279,6 +279,43 @@
     }
 
     /**
+     * Prompts the user to save changes, discard changes, or cancel navigation,
+     * when navigating away from a {@code Control} with unsaved changes.
+     *
+     * @see	    #getUnsavedChangesMessage
+     */
+    @Override
+    protected UnsavedChangesAction getUnsavedChangesAction() {
+	String message = getUnsavedChangesMessage();
+	if (message == null) {
+	    message = Finder.getString("settings.unsavedchanges.message");
+	}
+
+	String title = Finder.getString("settings.unsavedchanges.title");
+	int messageType = JOptionPane.WARNING_MESSAGE;
+	int optionType = JOptionPane.DEFAULT_OPTION;
+	Icon icon = GUIUtil.getIcon(JOptionPane.WARNING_MESSAGE);
+
+	Object[] options = {
+	    Finder.getString("settings.unsavedchanges.button.cancel"),
+	    Finder.getString("settings.unsavedchanges.button.discard"),
+	    Finder.getString("settings.unsavedchanges.button.save"),
+	};
+
+	Object defaultOption = options[0];
+
+	int result = JOptionPane.showOptionDialog(getComponent(), message,
+	    title, optionType, messageType, icon, options, defaultOption);
+
+	switch (result) {
+	    default:
+	    case 0: return UnsavedChangesAction.CANCEL;
+	    case 1: return UnsavedChangesAction.DISCARD;
+	    case 2: return UnsavedChangesAction.SAVE;
+	}
+    }
+
+    /**
      * If this {@code SwingControl} has a {@link #getChangeableAggregator
      * ChangeableAggregator}, returns the value from the aggregator's {@link
      * ChangeableAggregator#isChanged isChanged} method.  Otherwise, returns
@@ -389,43 +426,6 @@
     // DefaultControl methods
     //
 
-    /**
-     * Prompts the user to save changes, discard changes, or cancel navigation,
-     * when navigating away from a {@code Control} with unsaved changes.
-     *
-     * @see	    #getUnsavedChangesMessage
-     */
-    @Override
-    protected UnsavedChangesAction getUnsavedChangesAction() {
-	String message = getUnsavedChangesMessage();
-	if (message == null) {
-	    message = Finder.getString("settings.unsavedchanges.message");
-	}
-
-	String title = Finder.getString("settings.unsavedchanges.title");
-	int messageType = JOptionPane.WARNING_MESSAGE;
-	int optionType = JOptionPane.DEFAULT_OPTION;
-	Icon icon = GUIUtil.getIcon(JOptionPane.WARNING_MESSAGE);
-
-	Object[] options = {
-	    Finder.getString("settings.unsavedchanges.button.cancel"),
-	    Finder.getString("settings.unsavedchanges.button.discard"),
-	    Finder.getString("settings.unsavedchanges.button.save"),
-	};
-
-	Object defaultOption = options[0];
-
-	int result = JOptionPane.showOptionDialog(getComponent(), message,
-	    title, optionType, messageType, icon, options, defaultOption);
-
-	switch (result) {
-	    default:
-	    case 0: return UnsavedChangesAction.CANCEL;
-	    case 1: return UnsavedChangesAction.DISCARD;
-	    case 2: return UnsavedChangesAction.SAVE;
-	}
-    }
-
     @Override
     protected void removeChild(int index) {
 	synchronized (children) {
@@ -456,7 +456,7 @@
      * Configures the just-{@code #createComponent created} {@code Component}
      * for this {@code SwingControl}.  This method is called automatically just
      * after {@code createComponent}.
-     * <p>
+     * <p/>
      * This default implementation does nothing.  Most subclasses can do all
      * configuration in {@link #createComponent}.  Only implementors that wish
      * to provide a common configuration for all {@code Component}s created by
@@ -470,7 +470,7 @@
 
     /**
      * Creates the {@code Component} for this {@code SwingControl}.
-     * <p>
+     * <p/>
      * This default implementation does nothing and returns {@code null}.
      *
      * @return	    the newly-created {@code Component}
@@ -482,7 +482,7 @@
     /**
      * De-initializes the {@code Component} for this {@code SwingControl}.  This
      * method is called automatically when this {@code Control} is stopped.
-     * <p>
+     * <p/>
      * This default implementation does nothing.
      */
     protected void deinitComponent() {
@@ -511,7 +511,7 @@
      * This default implementation returns {@code null}.
      *
      * @return	    a {@link ChangeableAggregator}, or {@code null} if this
-     *        	    {@code SwingControl} has none
+     *		    {@code SwingControl} has none
      */
     public ChangeableAggregator getChangeableAggregator() {
 	return null;
@@ -590,7 +590,7 @@
     /**
      * Gets a custom message to display in the dialog that prompts the user to
      * {@link #getUnsavedChangesAction handle unsaved changes}.
-     * <p>
+     * <p/>
      * This default implementation returns {@code null}.
      *
      * @return	    a {@code String}, or {@code null} to use the default message
@@ -602,7 +602,7 @@
     /**
      * Initializes the {@code Component} for this {@code SwingControl}.  This
      * method is called automatically when this {@code Control} is started.
-     * <p>
+     * <p/>
      * This default implementation does nothing.
      */
     protected void initComponent() {
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/control/TabbedControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/control/TabbedControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -106,6 +106,17 @@
     //
 
     @Override
+    public void childStarted(Control child) {
+	super.childStarted(child);
+
+	int index = children.indexOf(child);
+	if (index != -1) {
+	    // Set viewable tab directly without going through the Navigator
+	    tabSelModel.setSelectedIndexDirectly(index);
+	}
+    }
+
+    @Override
     public Navigable[] getForwardingPath() {
 	ensureChildrenCreated();
 
@@ -118,21 +129,6 @@
     }
 
     //
-    // DefaultControl methods
-    //
-
-    @Override
-    public void childStarted(Control child) {
-	super.childStarted(child);
-
-	int index = children.indexOf(child);
-	if (index != -1) {
-	    // Set viewable tab directly without going through the Navigator
-	    tabSelModel.setSelectedIndexDirectly(index);
-	}
-    }
-
-    //
     // SwingControl methods
     //
 
--- a/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/GlobalControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/GlobalControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -79,6 +79,18 @@
     //
 
     @Override
+    public URL getHelpURL() {
+	return buildHelpURL("help/apache.html", "#apache-settings");
+    }
+
+    @Override
+    protected UnsavedChangesAction getUnsavedChangesAction() {
+	// Automatically save changes to the ApachePanelDescriptor --
+	// let MainControl prompt the user to save them to the repo
+	return UnsavedChangesAction.SAVE;
+    }
+
+    @Override
     protected boolean isSaveNeeded() {
 	// Save unconditionally, since a property that reports itself as
 	// unchanged in the panel may still be changed from the corresponding
@@ -153,18 +165,6 @@
 	}
     }
 
-    @Override
-    public URL getHelpURL() {
-	return buildHelpURL("help/apache.html", "#apache-settings");
-    }
-
-    @Override
-    protected UnsavedChangesAction getUnsavedChangesAction() {
-	// Automatically save changes to the ApachePanelDescriptor --
-	// let MainControl prompt the user to save them to the repo
-	return UnsavedChangesAction.SAVE;
-    }
-
     //
     // SwingControl methods
     //
--- a/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/MimeTypeControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/MimeTypeControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -66,6 +66,13 @@
     //
 
     @Override
+    protected UnsavedChangesAction getUnsavedChangesAction() {
+	// Automatically save changes to the MimeType -- let MainControl
+	// prompt the user to save them to the repo
+	return UnsavedChangesAction.SAVE;
+    }
+
+    @Override
     public boolean isBrowsable() {
 	// This Control requires init parameters
 	return false;
@@ -138,17 +145,6 @@
     }
 
     //
-    // DefaultControl methods
-    //
-
-    @Override
-    protected UnsavedChangesAction getUnsavedChangesAction() {
-	// Automatically save changes to the MimeType -- let MainControl
-	// prompt the user to save them to the repo
-	return UnsavedChangesAction.SAVE;
-    }
-
-    //
     // SwingControl methods
     //
 
--- a/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/MimeTypesControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/MimeTypesControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -96,6 +96,11 @@
 	return null;
     }
 
+    @Override
+    public URL getHelpURL() {
+	return buildHelpURL("help/apache.html", "#apache-mimetypes");
+    }
+
     //
     // DefaultControl methods
     //
@@ -110,11 +115,6 @@
 	}
     }
 
-    @Override
-    public URL getHelpURL() {
-	return buildHelpURL("help/apache.html", "#apache-mimetypes");
-    }
-
     //
     // SwingControl methods
     //
--- a/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/ModuleControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/ModuleControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -66,6 +66,13 @@
     //
 
     @Override
+    protected UnsavedChangesAction getUnsavedChangesAction() {
+	// Automatically save changes to the Module -- let MainControl
+	// prompt the user to save them to the repo
+	return UnsavedChangesAction.SAVE;
+    }
+
+    @Override
     public boolean isBrowsable() {
 	// This Control requires init parameters
 	return false;
@@ -136,17 +143,6 @@
     }
 
     //
-    // DefaultControl methods
-    //
-
-    @Override
-    protected UnsavedChangesAction getUnsavedChangesAction() {
-	// Automatically save changes to the Module -- let MainControl
-	// prompt the user to save them to the repo
-	return UnsavedChangesAction.SAVE;
-    }
-
-    //
     // SwingControl methods
     //
 
--- a/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/ModulesControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/ModulesControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -95,6 +95,11 @@
 	return null;
     }
 
+    @Override
+    public URL getHelpURL() {
+	return buildHelpURL("help/apache.html", "#apache-modules");
+    }
+
     //
     // DefaultControl methods
     //
@@ -109,11 +114,6 @@
 	}
     }
 
-    @Override
-    public URL getHelpURL() {
-	return buildHelpURL("help/apache.html", "#apache-modules");
-    }
-
     //
     // SwingControl methods
     //
--- a/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/VirtualHostGeneralControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/VirtualHostGeneralControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -75,6 +75,18 @@
     //
 
     @Override
+    public URL getHelpURL() {
+	return buildHelpURL("help/apache.html", "#apache-vhosts-edit");
+    }
+
+    @Override
+    protected UnsavedChangesAction getUnsavedChangesAction() {
+	// Automatically save changes to the VirtualHost -- let MainControl
+	// prompt the user to save them to the repo
+	return UnsavedChangesAction.SAVE;
+    }
+
+    @Override
     protected boolean isSaveNeeded() {
 	// Save unconditionally, since a property that reports itself as
 	// unchanged in the panel may still be changed from the corresponding
@@ -160,18 +172,6 @@
 	}
     }
 
-    @Override
-    public URL getHelpURL() {
-	return buildHelpURL("help/apache.html", "#apache-vhosts-edit");
-    }
-
-    @Override
-    protected UnsavedChangesAction getUnsavedChangesAction() {
-	// Automatically save changes to the VirtualHost -- let MainControl
-	// prompt the user to save them to the repo
-	return UnsavedChangesAction.SAVE;
-    }
-
     //
     // SwingControl methods
     //
--- a/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/VirtualHostSSLControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/VirtualHostSSLControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -65,6 +65,18 @@
     //
 
     @Override
+    public URL getHelpURL() {
+	return buildHelpURL("help/apache.html", "#apache-vhosts-edit");
+    }
+
+    @Override
+    protected UnsavedChangesAction getUnsavedChangesAction() {
+	// Automatically save changes to the VirtualHost -- let MainControl
+	// prompt the user to save them to the repo
+	return UnsavedChangesAction.SAVE;
+    }
+
+    @Override
     protected boolean isSaveNeeded() {
 	// Save unconditionally, since a property that reports itself as
 	// unchanged in the panel may still be changed from the corresponding
@@ -139,22 +151,6 @@
     }
 
     //
-    // DefaultControl methods
-    //
-
-    @Override
-    public URL getHelpURL() {
-	return buildHelpURL("help/apache.html", "#apache-vhosts-edit");
-    }
-
-    @Override
-    protected UnsavedChangesAction getUnsavedChangesAction() {
-	// Automatically save changes to the VirtualHost -- let MainControl
-	// prompt the user to save them to the repo
-	return UnsavedChangesAction.SAVE;
-    }
-
-    //
     // SwingControl methods
     //
 
--- a/usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CoreAdmSettingsTab.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CoreAdmSettingsTab.java	Tue Sep 22 16:46:54 2009 -0400
@@ -84,6 +84,11 @@
     //
 
     @Override
+    public URL getHelpURL() {
+	return buildHelpURL("help/coreadm.html", "#coreadm-settings");
+    }
+
+    @Override
     protected void save() throws ActionAbortedException, ActionFailedException,
 	ActionUnauthorizedException {
 
@@ -117,15 +122,6 @@
     }
 
     //
-    // DefaultControl methods
-    //
-
-    @Override
-    public URL getHelpURL() {
-	return buildHelpURL("help/coreadm.html", "#coreadm-settings");
-    }
-
-    //
     // SwingControl methods
     //
 
--- a/usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CoresTab.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CoresTab.java	Tue Sep 22 16:46:54 2009 -0400
@@ -66,7 +66,7 @@
     }
 
     //
-    // DefaultControl methods
+    // Control methods
     //
 
     @Override
@@ -74,10 +74,6 @@
 	return buildHelpURL("help/coreadm.html", "#coreadm-activity");
     }
 
-    //
-    // SwingControl methods
-    //
-
     @Override
     public void start(Navigator navigator, Map<String, String> parameters)
 	throws NavigationAbortedException, InvalidParameterException {
@@ -86,6 +82,10 @@
 	getPanelDescriptor().updateCoreConfig();
     }
 
+    //
+    // SwingControl methods
+    //
+
     @Override
     protected CoresPanel createComponent() {
 	CoresPanel panel = new CoresPanel(getPanelDescriptor(), actions, null);
--- a/usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CustomCoreSchemeEditControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CustomCoreSchemeEditControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -62,30 +62,13 @@
 	this.configProperty = configProperty;
     }
 
-    @Override
-    public URL getHelpURL() {
-	return buildHelpURL("help/coreadm.html", "#coreadm-edit");
-    }
-
     //
-    // SwingControl methods
+    // Control methods
     //
 
     @Override
-    protected CustomCoreSchemeEditPanel createComponent() {
-	CustomCoreSchemeEditPanel panel = new CustomCoreSchemeEditPanel();
-
-	addDefaultCancelAction(panel, false);
-	addDefaultOkayAction(panel, false);
-	addDefaultHelpAction(panel);
-
-	return panel;
-    }
-
-    @Override
-    protected void initComponent() {
-	getComponent().init(configProperty.getSavedValue(),
-	    configProperty.getValue());
+    public URL getHelpURL() {
+	return buildHelpURL("help/coreadm.html", "#coreadm-edit");
     }
 
     @Override
@@ -111,4 +94,25 @@
 
 	descriptor.setCoreConfig(value);
     }
+
+    //
+    // SwingControl methods
+    //
+
+    @Override
+    protected CustomCoreSchemeEditPanel createComponent() {
+	CustomCoreSchemeEditPanel panel = new CustomCoreSchemeEditPanel();
+
+	addDefaultCancelAction(panel, false);
+	addDefaultOkayAction(panel, false);
+	addDefaultHelpAction(panel);
+
+	return panel;
+    }
+
+    @Override
+    protected void initComponent() {
+	getComponent().init(configProperty.getSavedValue(),
+	    configProperty.getValue());
+    }
 }
--- a/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/FirewallDefaultTab.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/FirewallDefaultTab.java	Tue Sep 22 16:46:54 2009 -0400
@@ -63,6 +63,13 @@
     //
 
     @Override
+    protected UnsavedChangesAction getUnsavedChangesAction() {
+	// Automatically save changes to the FirewallPanelDescriptor --
+	// let MainControl prompt the user to save them to the repo
+	return UnsavedChangesAction.SAVE;
+    }
+
+    @Override
     public void save() throws ActionAbortedException, ActionFailedException,
         ActionUnauthorizedException {
 
@@ -98,17 +105,6 @@
     }
 
     //
-    // DefaultControl
-    //
-
-    @Override
-    protected UnsavedChangesAction getUnsavedChangesAction() {
-	// Automatically save changes to the FirewallPanelDescriptor --
-	// let MainControl prompt the user to save them to the repo
-	return UnsavedChangesAction.SAVE;
-    }
-
-    //
     // SwingControl methods
     //
 
--- a/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/FirewallOpenPortsTab.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/FirewallOpenPortsTab.java	Tue Sep 22 16:46:54 2009 -0400
@@ -61,6 +61,13 @@
     //
 
     @Override
+    protected UnsavedChangesAction getUnsavedChangesAction() {
+	// Automatically save changes to the FirewallPanelDescriptor --
+	// let MainControl prompt the user to save them to the repo
+	return UnsavedChangesAction.SAVE;
+    }
+
+    @Override
     protected void save() throws ActionAbortedException, ActionFailedException,
         ActionUnauthorizedException {
 
@@ -85,17 +92,6 @@
     }
 
     //
-    // DefaultControl methods
-    //
-
-    @Override
-    protected UnsavedChangesAction getUnsavedChangesAction() {
-	// Automatically save changes to the FirewallPanelDescriptor --
-	// let MainControl prompt the user to save them to the repo
-	return UnsavedChangesAction.SAVE;
-    }
-
-    //
     // SwingControl methods
     //
 
--- a/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/FirewallOverrideTab.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/FirewallOverrideTab.java	Tue Sep 22 16:46:54 2009 -0400
@@ -63,6 +63,13 @@
     //
 
     @Override
+    protected UnsavedChangesAction getUnsavedChangesAction() {
+	// Automatically save changes to the ApachePanelDescriptor --
+	// let MainControl prompt the user to save them to the repo
+	return UnsavedChangesAction.SAVE;
+    }
+
+    @Override
     protected boolean isSaveNeeded() {
 	return (getComponent().getAccessProperty().isChanged());
     }
@@ -92,17 +99,6 @@
     }
 
     //
-    // DefaultControl methods
-    //
-
-    @Override
-    protected UnsavedChangesAction getUnsavedChangesAction() {
-	// Automatically save changes to the ApachePanelDescriptor --
-	// let MainControl prompt the user to save them to the repo
-	return UnsavedChangesAction.SAVE;
-    }
-
-    //
     // SwingControl methods
     //
 
--- a/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/GlobalControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/GlobalControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -69,6 +69,20 @@
     //
 
     @Override
+    public void childStarted(Control child) {
+	super.childStarted(child);
+
+	ChangeableAggregator childAgg =
+	    ((SwingSettingsControl<?, ?>)child).getComponent().
+	    getChangeableAggregator();
+
+	if (changeableAggregator.getChangeables().contains(childAgg))
+	    return;
+
+	changeableAggregator.addChangeables(childAgg);
+    }
+
+    @Override
     protected boolean isSaveNeeded() {
 	return (changeableAggregator.isChanged());
     }
@@ -110,20 +124,6 @@
     //
 
     @Override
-    public void childStarted(Control child) {
-	super.childStarted(child);
-
-	ChangeableAggregator childAgg =
-	    ((SwingSettingsControl<?, ?>)child).getComponent().
-	    getChangeableAggregator();
-
-	if (changeableAggregator.getChangeables().contains(childAgg))
-	    return;
-
-	changeableAggregator.addChangeables(childAgg);
-    }
-
-    @Override
     protected void ensureChildrenCreated() {
 	if (children.size() == 0) {
 
--- a/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/MainControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/MainControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -59,17 +59,6 @@
     //
 
     @Override
-    public Navigable[] getForwardingPath() {
-	return new Navigable[] {
-	    new SimpleNavigable(GlobalControl.ID, null)
-	};
-    }
-
-    //
-    // DefaultControl methods
-    //
-
-    @Override
     public void childStarted(Control child) {
 	super.childStarted(child);
 
@@ -98,6 +87,17 @@
     }
 
     @Override
+    public Navigable[] getForwardingPath() {
+	return new Navigable[] {
+	    new SimpleNavigable(GlobalControl.ID, null)
+	};
+    }
+
+    //
+    // DefaultControl methods
+    //
+
+    @Override
     protected void ensureChildrenCreated() {
 	if (children.size() == 0) {
 	    FirewallPanelDescriptor descriptor = getPanelDescriptor();
--- a/usr/src/java/vpanels/panels/sharemgr/org/opensolaris/os/vp/panels/sharemgr/client/swing/MainControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/sharemgr/org/opensolaris/os/vp/panels/sharemgr/client/swing/MainControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -81,25 +81,6 @@
     //
 
     @Override
-    public Navigable[] getForwardingPath() {
-	List<GroupManagedObject> groups =
-	    getPanelDescriptor().getChildren();
-
-	if (!groups.isEmpty()) {
-	    return new Navigable[] {
-		new SimpleNavigable(GroupTabbedControl.ID, null,
-		    GroupTabbedControl.PARAM_GROUP, groups.get(0).getId())
-	    };
-	}
-
-	return super.getForwardingPath();
-    }
-
-    //
-    // DefaultControl methods
-    //
-
-    @Override
     public void childStarted(Control child) {
 	super.childStarted(child);
 	// Allow our ChangeableAggregator, which indirectly controls the enabled
@@ -131,6 +112,25 @@
     }
 
     @Override
+    public Navigable[] getForwardingPath() {
+	List<GroupManagedObject> groups =
+	    getPanelDescriptor().getChildren();
+
+	if (!groups.isEmpty()) {
+	    return new Navigable[] {
+		new SimpleNavigable(GroupTabbedControl.ID, null,
+		    GroupTabbedControl.PARAM_GROUP, groups.get(0).getId())
+	    };
+	}
+
+	return super.getForwardingPath();
+    }
+
+    //
+    // DefaultControl methods
+    //
+
+    @Override
     protected void ensureChildrenCreated() {
 	if (children.size() == 0) {
 	    SharemgrPanelDescriptor descriptor = getPanelDescriptor();
--- a/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/InstanceEditControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/InstanceEditControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -50,7 +50,7 @@
     }
 
     //
-    // DefaultControl methods
+    // Control methods
     //
 
     @Override
--- a/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/ServiceEditControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/ServiceEditControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -53,7 +53,7 @@
     }
 
     //
-    // DefaultControl methods
+    // Control methods
     //
 
     @Override
--- a/usr/src/java/vpanels/panels/svcs/org/opensolaris/os/vp/panels/svcs/client/swing/InstancesControl.java	Tue Sep 22 10:41:15 2009 -0400
+++ b/usr/src/java/vpanels/panels/svcs/org/opensolaris/os/vp/panels/svcs/client/swing/InstancesControl.java	Tue Sep 22 16:46:54 2009 -0400
@@ -92,6 +92,11 @@
     //
 
     @Override
+    public URL getHelpURL() {
+	return buildHelpURL("help/smf.html", "#smf-instance");
+    }
+
+    @Override
     public boolean isBrowsable() {
 	// This Control requires init parameters
 	return false;
@@ -121,15 +126,6 @@
 	filter_ = null;
     }
 
-    //
-    // DefaultControl methods
-    //
-
-    @Override
-    public URL getHelpURL() {
-	return buildHelpURL("help/smf.html", "#smf-instance");
-    }
-
     /*
      * SwingControl methods
      */