components/visual-panels/core/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/control/SwingControl.java
changeset 3553 f1d133b09a8c
parent 3552 077ebe3d0d24
child 3554 ef58713bafc4
--- a/components/visual-panels/core/src/java/vpanels/panel/com/oracle/solaris/vp/panel/swing/control/SwingControl.java	Tue Dec 16 05:53:51 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,571 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
- */
-
-package com.oracle.solaris.vp.panel.swing.control;
-
-import java.awt.*;
-import java.beans.*;
-import java.util.Map;
-import javax.swing.*;
-import com.oracle.solaris.vp.panel.common.ClientContext;
-import com.oracle.solaris.vp.panel.common.action.*;
-import com.oracle.solaris.vp.panel.common.control.*;
-import com.oracle.solaris.vp.panel.common.model.*;
-import com.oracle.solaris.vp.panel.swing.action.SwingStructuredAction;
-import com.oracle.solaris.vp.util.misc.*;
-import com.oracle.solaris.vp.util.misc.finder.Finder;
-import com.oracle.solaris.vp.util.swing.*;
-
-public class SwingControl<P extends PanelDescriptor, C extends Component>
-    extends DefaultControl<P> implements HasComponent<C>,
-    PropertyChangeListener {
-
-    //
-    // Instance data
-    //
-
-    private ManagedObject propSource;
-    private String[] propNames;
-    private boolean ignorePropChange;
-
-    private C comp;
-    private Stackable<Component> stack;
-
-    private SwingStructuredAction<Object, Object, Object> resetAction =
-	new SwingStructuredAction<Object, Object, Object>(null, null, null,
-	    this) {
-
-	    @Override
-	    public Object workBusy(Object pInput, Object rtInput)
-		throws ActionAbortedException, ActionFailedException,
-		ActionUnauthorizedException {
-
-		resetAll();
-		return null;
-	    }
-	};
-
-    private SwingStructuredAction<Object, Object, Object> saveAction =
-	new SwingStructuredAction<Object, Object, Object>(null, null, null,
-	    this) {
-
-	    @Override
-	    public Object workBusy(Object pInput, Object rtInput)
-		throws ActionAbortedException, ActionFailedException,
-		ActionUnauthorizedException {
-
-		saveAll();
-		return null;
-	    }
-	};
-
-    //
-    // Constructors
-    //
-
-    public SwingControl(String id, String name, ClientContext context) {
-	super(id, name, context);
-    }
-
-    public SwingControl(String id, String name, P descriptor) {
-	super(id, name, descriptor);
-    }
-
-    //
-    // HasComponent methods
-    //
-
-    /**
-     * Gets the {@code Component} for this {@code SwingControl}.
-     *
-     * @return	    a {@code Component}, or {@code null} if this {@code
-     *		    SwingControl} has no {@code Component}.
-     *
-     * @see	    #setComponent
-     */
-    @Override
-    public C getComponent() {
-	return comp;
-    }
-
-    //
-    // PropertyChangeListener methods
-    //
-
-    /**
-     * Convenience implementation that calls {@link #initComponentOnEventThread}
-     * if property changes are not temporarilty being {@link
-     * #getPropertyChangeIgnore ignored}.  If this {@link SwingControl}'s
-     * component displayed the properties of a {@link ManagedObject}, for
-     * example, it may make sense to add this {@code SwingControl} as a {@code
-     * PropertyListener} to that object.
-     */
-    @Override
-    public void propertyChange(PropertyChangeEvent event) {
-	if (!ignorePropChange && getComponent() != null) {
-	    initComponentOnEventThread();
-	}
-    }
-
-    //
-    // Control methods
-    //
-
-    /**
-     * If a) this {@code SwingControl} defines a {@link #getComponentStack
-     * Component stack}, b) the just-started {@link Control} implements {@link
-     * HasComponent}, and c) its {@code Component} does not yet have a parent,
-     * this method adds that {@code Component} to the stack.
-     */
-    @Override
-    public void descendantStarted(Control[] path) {
-	super.descendantStarted(path);
-
-	final Stackable<Component> stack = getComponentStack();
-	if (stack != null) {
-	    Control control = path[path.length - 1];
-	    if (control instanceof HasComponent) {
-		final Component comp = ((HasComponent)control).getComponent();
-		if (comp != null && !(comp instanceof Window) &&
-		    comp.getParent() == null) {
-
-		    GUIUtil.invokeAndWait(
-			new Runnable() {
-			    @Override
-			    public void run() {
-				stack.push(comp);
-			    }
-			});
-		}
-	    }
-	}
-    }
-
-    /**
-     * If a) this {@code SwingControl} defines a {@link #getComponentStack
-     * Component stack}, b) the just-stopped {@link Control} implements {@link
-     * HasComponent}, and c) its {@code Component} is at the top of the stack,
-     * this method removes that {@code Component} from the stack.
-     */
-    @Override
-    public void descendantStopped(Control[] path) {
-	super.descendantStopped(path);
-
-	final Stackable<Component> stack = getComponentStack();
-	if (stack != null) {
-	    Control control = path[path.length - 1];
-	    if (control instanceof HasComponent) {
-		final Component comp = ((HasComponent)control).getComponent();
-		if (comp != null && !(comp instanceof Window)) {
-		    GUIUtil.invokeAndWait(
-			new Runnable() {
-			    @Override
-			    public void run() {
-				StackUtil.popIfAtTop(stack, comp);
-			    }
-			});
-		}
-	    }
-	}
-    }
-
-    /**
-     * Gets a {@link SwingStructuredAction} that invokes {@link #resetAll},
-     * displaying errors.
-     */
-    @Override
-    public SwingStructuredAction<?, ?, ?> getResetAction() {
-	return resetAction;
-    }
-
-    /**
-     * Gets a {@link SwingStructuredAction} that invokes {@link #saveAll},
-     * displaying errors and prompting for login on {@code
-     * ActionUnauthorizedException}s.
-     */
-    @Override
-    public SwingStructuredAction<?, ?, ?> getSaveAction() {
-	return saveAction;
-    }
-
-    /**
-     * 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
-     * {@code false}.
-     */
-    @Override
-    protected boolean isChanged() {
-	ChangeableAggregator aggregator = getChangeableAggregator();
-	if (aggregator != null) {
-	    return aggregator.isChanged();
-	}
-	return false;
-    }
-
-    /**
-     * If this {@code SwingControl} has a {@link #getChangeableAggregator
-     * ChangeableAggregator}, calls its {@link ChangeableAggregator#reset}
-     * method on the AWT event thread and waits for its completion.
-     */
-    @Override
-    protected void reset() throws ActionAbortedException, ActionFailedException
-    {
-	final ChangeableAggregator aggregator = getChangeableAggregator();
-	if (aggregator != null) {
-	    GUIUtil.invokeAndWait(
-		new Runnable() {
-		    @Override
-		    public void run() {
-			aggregator.reset();
-		    }
-		});
-	}
-    }
-
-    /**
-     * If this {@code SwingControl} has a {@link #getChangeableAggregator
-     * ChangeableAggregator}, calls its {@link ChangeableAggregator#save}
-     * method on the AWT event thread and waits for its completion.
-     */
-    @Override
-    protected void save() throws ActionAbortedException, ActionFailedException,
-	ActionUnauthorizedException {
-
-	final ChangeableAggregator aggregator = getChangeableAggregator();
-	if (aggregator != null) {
-	    GUIUtil.invokeAndWait(
-		new Runnable() {
-		    @Override
-		    public void run() {
-			aggregator.save();
-		    }
-		});
-	}
-    }
-
-    /**
-     * Calls the superclass implementation, {@link #getComponentCreate creates}
-     * this {@code SwingControl}'s {@code Component} if necessary, then
-     * {@link #initComponentOnEventThread initializes} it.
-     */
-    @Override
-    public void start(Navigator navigator, Map<String, String> parameters)
-	throws NavigationAbortedException, InvalidParameterException,
-	NavigationFailedException {
-
-	super.start(navigator, parameters);
-
-	if (propSource != null) {
-	    if (propNames == null) {
-		propSource.addPropertyChangeListener(this);
-	    } else {
-		for (String propName : propNames) {
-		    propSource.addPropertyChangeListener(propName, this);
-		}
-	    }
-	}
-
-	Component comp = getComponentCreate();
-	if (comp != null) {
-	    initComponentOnEventThread();
-	}
-    }
-
-    /**
-     * Calls the superclass implementation, then {@link
-     * #deinitComponentOnEventThread deinitializes} this {@code SwingControl}'s
-     * {@code Component}.
-     *
-     * @exception   NavigationAbortedException
-     *		    if the navigation is cancelled, or a save fails
-     */
-    @Override
-    public void stop(boolean isCancel) throws NavigationAbortedException {
-	super.stop(isCancel);
-
-	Component comp = getComponent();
-	if (comp != null) {
-	    deinitComponentOnEventThread();
-	}
-
-	if (propSource != null) {
-	    propSource.removePropertyChangeListener(this);
-	    propSource = null;
-	    propNames = null;
-	}
-    }
-
-    //
-    // SwingControl methods
-    //
-
-    /**
-     * Configures the just-{@code #createComponent created} {@code Component}
-     * for this {@code SwingControl}.  This method is called automatically just
-     * after {@code createComponent}.
-     * <p/>
-     * 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 their subclasses need to implement this
-     * method.
-     * <p/>
-     * Subclasses that override this method should call {@code
-     * super.configComponent(comp)} to ensure that any present or future
-     * functionality in any superclass implementation is executed.
-     * <p/>
-     * This default implementation does nothing.
-     *
-     * @param	    comp
-     *		    the newly-created {@code Component}
-     */
-    protected void configComponent(C comp) {
-    }
-
-    /**
-     * Creates the {@code Component} for this {@code SwingControl}.
-     * <p/>
-     * This default implementation does nothing and returns {@code null}.
-     *
-     * @return	    the newly-created {@code Component}
-     */
-    protected C createComponent() {
-	return null;
-    }
-
-    /**
-     * De-initializes the {@code Component} for this {@code SwingControl}.  This
-     * method is called automatically when this {@code Control} is stopped.
-     * <p/>
-     * This default implementation does nothing.
-     */
-    protected void deinitComponent() {
-    }
-
-    /**
-     * Calls {@link #deinitComponent} on the event queue thread and waits until
-     * it has completed.  This method is called automatically when this {@code
-     * Control} is stopped.
-     */
-    protected void deinitComponentOnEventThread() {
-	GUIUtil.invokeAndWait(
-	    new Runnable() {
-		@Override
-		public void run() {
-		    deinitComponent();
-		}
-	    });
-    }
-
-    /**
-     * Gets the {@link ChangeableAggregator}, if any, for this class.  This is
-     * used in the default implementation of some {@link Control} methods to
-     * track changes to this {@code Control}.
-     * <p/>
-     * This default implementation returns {@code null}.
-     *
-     * @return	    a {@link ChangeableAggregator}, or {@code null} if this
-     *		    {@code SwingControl} has none
-     */
-    public ChangeableAggregator getChangeableAggregator() {
-	return null;
-    }
-
-    /**
-     * Gets the {@code Component} for this {@code SwingControl}, {@link
-     * #createComponent creating} it, {@code #configComponent configuring} it,
-     * and {@code #setComponent setting} it first if necessary.
-     * <p/>
-     * This method is not thread-safe; external locking may be necessary to
-     * ensure that {@link #createComponent} is not called by multiple threads.
-     *
-     * @return	    a {@code Component}, or {@code null} if this {@code
-     *		    SwingControl} has no {@code Component}.
-     */
-    public C getComponentCreate() {
-	C comp = getComponent();
-	if (comp == null) {
-	    comp = createComponent();
-	    if (comp != null) {
-		setComponent(comp);
-		configComponent(comp);
-	    }
-	}
-	return comp;
-    }
-
-    /**
-     * Gets the {@code {@link Stackable}<Component>} to which {@code Component}s
-     * of descendant {@code SwingControl}s may be added.
-     *
-     * @return	    a {@code {@link Stackable}<Component>}, or {@code null} to
-     *		    defer to {@code SwingControl}s higher in the navigation
-     *		    stack
-     */
-    public Stackable<Component> getComponentStack() {
-	return stack;
-    }
-
-    /**
-     * Gets whether property changes to the {@link #setPropertyChangeSource
-     * property change source} are temporarily ignored.
-     *
-     * @see	    #setPropertyChangeIgnore
-     */
-    public boolean getPropertyChangeIgnore() {
-	return ignorePropChange;
-    }
-
-    /**
-     * Gets a custom message to display in the dialog that prompts the user to
-     * {@link #getUnsavedChangesAction handle unsaved changes}.
-     * <p/>
-     * This default implementation returns {@code null}.
-     *
-     * @return	    a {@code String}, or {@code null} to use the default message
-     */
-    protected String getUnsavedChangesMessage() {
-	return null;
-    }
-
-    /**
-     * Initializes the {@code Component} for this {@code SwingControl}.  This
-     * method is called automatically when this {@code Control} is started.
-     * <p/>
-     * This default implementation does nothing.
-     */
-    protected void initComponent() {
-    }
-
-    /**
-     * Calls {@link #initComponent} on the event queue thread and waits until it
-     * has completed.  This method is called automatically when this {@code
-     * Control} is started.
-     */
-    protected void initComponentOnEventThread() {
-	GUIUtil.invokeAndWait(
-	    new Runnable() {
-		@Override
-		public void run() {
-		    initComponent();
-		}
-	    });
-    }
-
-    /**
-     * Gets the {@code Component} for this {@code SwingControl}.
-     *
-     * @param	    comp
-     *		    a {@code Component}, or {@code null} if this {@code
-     *		    SwingControl} has no {@code Component}.
-     *
-     * @see	    #getComponent
-     */
-    protected void setComponent(C comp) {
-	this.comp = comp;
-    }
-
-    /**
-     * Sets the {@code {@link Stackable}<Component>} to which {@code Component}s
-     * of descendant {@code SwingControl}s may be added.
-     *
-     * @param	    stack
-     *		    a {@code {@link Stackable}<Component>} or {@code null} to
-     *		    defer to {@code SwingControl}s higher in the navigation
-     *		    stack
-     */
-    protected void setComponentStack(Stackable<Component> stack) {
-	this.stack = stack;
-    }
-
-    /**
-     * Sets whether property changes to the {@link #setPropertyChangeSource
-     * property change source} are temporarily ignored.
-     *
-     * @see	    #getPropertyChangeIgnore
-     */
-    public void setPropertyChangeIgnore(boolean ignorePropChange) {
-	this.ignorePropChange = ignorePropChange;
-    }
-
-    /**
-     * Sets a {@link ManagedObject} to which this control should listen
-     * for {@code PropertyChangeEvent}s once it is started.  Should not
-     * be called while the control is started.
-     *
-     * @param	    propSource
-     *		    the {@link ManagedObject} to listen to
-     *
-     * @param	    propNames
-     *		    the names of the properties in which to listen for changes,
-     *		    or an empty array to listen for changes in all properties on
-     *		    {@code propSource}
-     */
-    protected void setPropertyChangeSource(ManagedObject propSource,
-	String... propNames) {
-
-	assert !isStarted();
-	this.propSource = propSource;
-	this.propNames = propNames == null || propNames.length == 0 ? null :
-	    propNames;
-    }
-}