[kepler-dev] Re: [kepler-cvs] kepler/src/exp/ptolemy/vergil/basic BasicGraphFrame.java

Matt Jones jones at nceas.ucsb.edu
Thu Jun 24 11:21:04 PDT 2004


Steve,

Yes, I agree these changes should go into Ptolemy.  I made the original 
changes in a way that is compatible with the configuration mechanism in 
Ptolemy so that a configuration could choose whether it wanted a tabbed 
pane or the original window in Kepler, and what components reside in 
those panes.  Once we get synchronized with the 4.0 tree, and hopefully 
after that to the PTII CVS head, we'll submit the needed classes to 
Ptolemy for review and inclusion there.

On a related note, we are anticipating a bunch of UI extensions, and so 
have discussed in a couple of venues how to best integrate our tree with 
Ptolemy.  I have a task to write up a proposed means of keeping Kepler 
synchronized with PTII and sending it to the Edward and the PTII group 
for review.  I'm planning on doing this once we get the current Kepler 
version working with PTII 4.0 so we know what the major synchronization 
issues are.

Matt

Stephen Andrew Neuendorffer wrote:
> 
> Dan: This is exactly a case where I think it would be well worth it to 
> avoid making these changes
> each version of Ptolemy...  Some of these improvements (the 
> LibraryPaneFactory, in particular)
> look like things that should refined and go in Ptolemy, specifically so 
> that you don't have to
> continue to make these merges.
> 
> What do you think?
> 
> Steve
> 
> At 11:13 AM 6/23/2004, Daniel Higgins wrote:
> 
>> higgins     04/06/23 11:13:21
>>
>>   Modified:    src/exp/ptolemy/vergil/basic Tag: 
>> KEPLER_PTII4_MERGE_BRANCH
>>                         BasicGraphFrame.java
>>   Log:
>>   Started with the new Ptolemy4.0Beta version of this file and then 
>> made the same changes as had been made previously by Matt Jones for 
>> Kepler operation with PT3.02. Code now compiles and tabbed tree 
>> appears on the left side of kepler/vergil window.
>>
>>   Revision  Changes    Path
>>   No                   revision
>>
>>
>>   No                   revision
>>
>>
>>   1.1.2.1   +447 -595  
>> kepler/src/exp/ptolemy/vergil/basic/BasicGraphFrame.java
>>
>>   Index: BasicGraphFrame.java
>>   ===================================================================
>>   RCS file: 
>> /cvs/kepler/src/exp/ptolemy/vergil/basic/BasicGraphFrame.java,v
>>   retrieving revision 1.1
>>   retrieving revision 1.1.2.1
>>   diff -u -r1.1 -r1.1.2.1
>>   --- BasicGraphFrame.java      28 Apr 2004 00:56:59 -0000      1.1
>>   +++ BasicGraphFrame.java      23 Jun 2004 18:13:21 -0000      1.1.2.1
>>   @@ -1,31 +1,29 @@
>>    /* A simple graph view for Ptolemy models
>>
>>   - Copyright (c) 1998-2003 The Regents of the University of California.
>>   - All rights reserved.
>>   - Permission is hereby granted, without written agreement and without
>>   - license or royalty fees, to use, copy, modify, and distribute this
>>   - software and its documentation for any purpose, provided that the 
>> above
>>   - copyright notice and the following two paragraphs appear in all 
>> copies
>>   - of this software.
>>   -
>>   - IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
>>   - FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
>>   - ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, 
>> EVEN IF
>>   - THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
>>   - SUCH DAMAGE.
>>   -
>>   - THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
>>   - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
>>   - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
>>   - PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
>>   - CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, 
>> UPDATES,
>>   - ENHANCEMENTS, OR MODIFICATIONS.
>>   -
>>   -                                        PT_COPYRIGHT_VERSION_2
>>   -                                        COPYRIGHTENDKEY
>>   -
>>   - at ProposedRating Red (neuendor at eecs.berkeley.edu)
>>   - at AcceptedRating Red (johnr at eecs.berkeley.edu)
>>   +Copyright (c) 1998-2004 The Regents of the University of California.
>>   +All rights reserved.
>>   +Permission is hereby granted, without written agreement and without
>>   +license or royalty fees, to use, copy, modify, and distribute this
>>   +software and its documentation for any purpose, provided that the 
>> above
>>   +copyright notice and the following two paragraphs appear in all copies
>>   +of this software.
>>   +
>>   +IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
>>   +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
>>   +ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
>>   +THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
>>   +SUCH DAMAGE.
>>   +
>>   +THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
>>   +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
>>   +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
>>   +PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
>>   +CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
>>   +ENHANCEMENTS, OR MODIFICATIONS.
>>   +
>>   +PT_COPYRIGHT_VERSION_2
>>   +COPYRIGHTENDKEY
>>   +2
>>    */
>>
>>    package ptolemy.vergil.basic;
>>   @@ -37,6 +35,7 @@
>>    import java.awt.Event;
>>    import java.awt.Frame;
>>    import java.awt.Graphics;
>>   +import java.awt.Toolkit;
>>    import java.awt.datatransfer.Clipboard;
>>    import java.awt.datatransfer.ClipboardOwner;
>>    import java.awt.datatransfer.DataFlavor;
>>   @@ -53,14 +52,13 @@
>>    import java.awt.print.Printable;
>>    import java.awt.print.PrinterException;
>>    import java.io.File;
>>   -import java.io.FileReader;
>>    import java.io.IOException;
>>    import java.io.StringWriter;
>>    import java.net.URL;
>>    import java.util.HashMap;
>>    import java.util.HashSet;
>>    import java.util.Iterator;
>>   -import java.util.LinkedHashSet;
>>   +import java.util.LinkedHashSet;    // kepler add - DFH
>>
>>    import javax.swing.AbstractAction;
>>    import javax.swing.Action;
>>   @@ -69,16 +67,20 @@
>>    import javax.swing.JComponent;
>>    import javax.swing.JFileChooser;
>>    import javax.swing.JMenu;
>>   +import javax.swing.JMenuItem;
>>    import javax.swing.JPanel;
>>   +import javax.swing.JScrollPane;
>>    import javax.swing.JSplitPane;
>>    import javax.swing.JToolBar;
>>   +import javax.swing.JTree;
>>    import javax.swing.KeyStroke;
>>    import javax.swing.SwingUtilities;
>>
>>   -import org.ecoinformatics.seek.ecogrid.BasicLibraryPane;
>>   -import org.ecoinformatics.seek.ecogrid.LibraryPane;
>>   -import org.ecoinformatics.seek.ecogrid.LibraryPaneFactory;
>>   -import org.ecoinformatics.seek.ecogrid.TabbedLibraryPane;
>>   +import org.ecoinformatics.seek.ecogrid.BasicLibraryPane;    // 
>> kepler add - DFH
>>   +import org.ecoinformatics.seek.ecogrid.LibraryPane;         // 
>> kepler add - DFH
>>   +import org.ecoinformatics.seek.ecogrid.LibraryPaneFactory;  // 
>> kepler add - DFH
>>   +import org.ecoinformatics.seek.ecogrid.TabbedLibraryPane;   // 
>> kepler add - DFH
>>   +
>>
>>    import ptolemy.actor.IOPort;
>>    import ptolemy.actor.IORelation;
>>   @@ -90,31 +92,38 @@
>>    import ptolemy.actor.gui.SizeAttribute;
>>    import ptolemy.actor.gui.Tableau;
>>    import ptolemy.actor.gui.WindowPropertiesAttribute;
>>   -import ptolemy.gui.CancelException;
>>   -import ptolemy.gui.MessageHandler;
>>   +import ptolemy.data.ArrayToken;
>>   +import ptolemy.data.DoubleToken;
>>   +import ptolemy.data.Token;
>>   +import ptolemy.data.expr.ExpertParameter;
>>   +import ptolemy.data.expr.Parameter;
>>    import ptolemy.kernel.ComponentEntity;
>>    import ptolemy.kernel.CompositeEntity;
>>    import ptolemy.kernel.Entity;
>>   -import ptolemy.kernel.Port;
>>   -import ptolemy.kernel.Relation;
>>   +import ptolemy.kernel.undo.RedoChangeRequest;
>>   +import ptolemy.kernel.undo.UndoChangeRequest;
>>   +import ptolemy.kernel.undo.UndoStackAttribute;
>>    import ptolemy.kernel.util.Attribute;
>>    import ptolemy.kernel.util.ChangeListener;
>>    import ptolemy.kernel.util.ChangeRequest;
>>    import ptolemy.kernel.util.IllegalActionException;
>>    import ptolemy.kernel.util.InternalErrorException;
>>    import ptolemy.kernel.util.KernelException;
>>   -import ptolemy.kernel.util.KernelRuntimeException;
>>    import ptolemy.kernel.util.Locatable;
>>    import ptolemy.kernel.util.Location;
>>    import ptolemy.kernel.util.NamedObj;
>>   +import ptolemy.kernel.util.Settable;
>>    import ptolemy.kernel.util.Workspace;
>>    import ptolemy.moml.LibraryAttribute;
>>    import ptolemy.moml.MoMLChangeRequest;
>>   -import ptolemy.moml.MoMLUndoChangeRequest;
>>    import ptolemy.moml.MoMLUndoEntry;
>>   -import ptolemy.moml.UndoInfoAttribute;
>>   +import ptolemy.util.CancelException;
>>   +import ptolemy.util.MessageHandler;
>>    import ptolemy.util.StringUtilities;
>>   +import ptolemy.vergil.toolbox.MenuItemFactory;
>>    import ptolemy.vergil.tree.EntityTreeModel;
>>   +import ptolemy.vergil.tree.PTree;
>>   +import ptolemy.vergil.tree.PTreeMenuCreator;
>>    import ptolemy.vergil.tree.VisibleTreeModel;
>>    import diva.canvas.CanvasUtilities;
>>    import diva.canvas.Figure;
>>   @@ -122,6 +131,8 @@
>>    import diva.canvas.Site;
>>    import diva.canvas.connector.FixedNormalSite;
>>    import diva.canvas.connector.Terminal;
>>   +import diva.canvas.event.LayerAdapter;
>>   +import diva.canvas.event.LayerEvent;
>>    import diva.canvas.interactor.SelectionModel;
>>    import diva.graph.GraphController;
>>    import diva.graph.GraphEvent;
>>   @@ -133,35 +144,39 @@
>>    import diva.graph.layout.LayoutTarget;
>>    import diva.graph.layout.LevelLayout;
>>    import diva.gui.GUIUtilities;
>>   -import diva.gui.toolbox.FocusMouseListener;
>>   +
>>    import diva.gui.toolbox.JCanvasPanner;
>>   +import diva.gui.toolbox.JContextMenu;
>>    import diva.util.java2d.ShapeUtilities;
>>   +
>>    
>> ////////////////////////////////////////////////////////////////////////// 
>>
>>    //// BasicGraphFrame
>>    /**
>>   -A simple graph view for ptolemy models.  This represents a level of 
>> the
>>   -hierarchy of a ptolemy model as a diva graph.  Cut, copy and paste 
>> operations
>>   -are supported using MoML.
>>   -
>>   - at author  Steve Neuendorffer, Edward A. Lee
>>   - at version $Id: BasicGraphFrame.java,v 1.1 2004/04/28 00:56:59 jones 
>> Exp $
>>   - at since Ptolemy II 2.0
>>   +   A simple graph view for ptolemy models.  This represents a level of
>>   +   the hierarchy of a ptolemy model as a diva graph.  Cut, copy and
>>   +   paste operations are supported using MoML.
>>   +
>>   +   @author  Steve Neuendorffer, Edward A. Lee
>>   +   @version $Id: BasicGraphFrame.java,v 1.1.2.1 2004/06/23 18:13:21 
>> higgins Exp $
>>   +   @since Ptolemy II 2.0
>>   +   @Pt.ProposedRating Red (neuendor)
>>   +   @Pt.AcceptedRating Red (johnr)
>>    */
>>    public abstract class BasicGraphFrame extends PtolemyFrame
>>        implements Printable, ClipboardOwner, ChangeListener {
>>
>>   -    /** Construct a frame associated with the specified Ptolemy II 
>> model.
>>   -     *  After constructing this, it is necessary
>>   +    /** Construct a frame associated with the specified Ptolemy II 
>> model
>>   +     *  or object. After constructing this, it is necessary
>>         *  to call setVisible(true) to make the frame appear.
>>         *  This is typically done by calling show() on the controlling 
>> tableau.
>>         *  This constructor results in a graph frame that obtains its 
>> library
>>         *  either from the model (if it has one) or the default 
>> library defined
>>         *  in the configuration.
>>         *  @see Tableau#show()
>>   -     *  @param entity The model to put in this frame.
>>   +     *  @param entity The model or object to put in this frame.
>>         *  @param tableau The tableau responsible for this frame.
>>         */
>>   -    public BasicGraphFrame(CompositeEntity entity, Tableau tableau) {
>>   +    public BasicGraphFrame(NamedObj entity, Tableau tableau) {
>>            this(entity, tableau, null);
>>        }
>>
>>   @@ -174,13 +189,13 @@
>>         *  argument (if it is non-null), or the default library defined
>>         *  in the configuration.
>>         *  @see Tableau#show()
>>   -     *  @param entity The model to put in this frame.
>>   +     *  @param entity The model or object to put in this frame.
>>         *  @param tableau The tableau responsible for this frame.
>>         *  @param defaultLibrary An attribute specifying the default 
>> library
>>         *   to use if the model does not have a library.
>>         */
>>        public BasicGraphFrame(
>>   -            CompositeEntity entity,
>>   +            NamedObj entity,
>>                Tableau tableau,
>>                LibraryAttribute defaultLibrary) {
>>            super(entity, tableau);
>>   @@ -194,12 +209,12 @@
>>
>>            _jgraph = new JGraph(pane);
>>
>>   -        new EditorDropTarget(_jgraph);
>>   +        _dropTarget = new EditorDropTarget(_jgraph);
>>
>>            ActionListener deletionListener = new ActionListener() {
>>   -                /** Delete any nodes or edges from the graph that 
>> are currently
>>   -                 *  selected.  In addition, delete any edges that 
>> are connected to
>>   -                 *  any deleted nodes.
>>   +                /** Delete any nodes or edges from the graph that are
>>   +                 *  currently selected.  In addition, delete any edges
>>   +                 *  that are connected to any deleted nodes.
>>                     */
>>                    public void actionPerformed(ActionEvent e) {
>>                        delete();
>>   @@ -209,8 +224,30 @@
>>            _jgraph.registerKeyboardAction(deletionListener, "Delete",
>>                    KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0),
>>                    JComponent.WHEN_IN_FOCUSED_WINDOW);
>>   +        _jgraph.registerKeyboardAction(deletionListener, "BackSpace",
>>   +                KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0),
>>   +                JComponent.WHEN_IN_FOCUSED_WINDOW);
>>   +
>>            _jgraph.setRequestFocusEnabled(true);
>>   -        _jgraph.addMouseListener(new FocusMouseListener());
>>   +        pane.getForegroundEventLayer().setConsuming(false);
>>   +        pane.getForegroundEventLayer().setEnabled(true);
>>   +        pane.getForegroundEventLayer().addLayerListener(
>>   +                new LayerAdapter() {
>>   +                    /** Invoked when the mouse is pressed on a layer
>>   +                     * or figure.
>>   +                     */
>>   +                    public void mousePressed (LayerEvent event) {
>>   +                        Component component = event.getComponent();
>>   +                        if (!component.hasFocus()) {
>>   +                            component.requestFocus();
>>   +                        }
>>   +                    }
>>   +                });
>>   +
>>   +        // We used to do this, but it would result in context menus
>>   +        // getting lost on the mac.
>>   +
>>   +        // _jgraph.addMouseListener(new FocusMouseListener());
>>            _jgraph.setAlignmentX(1);
>>            _jgraph.setAlignmentY(1);
>>            _jgraph.setBackground(BACKGROUND_COLOR);
>>   @@ -235,6 +272,29 @@
>>                    _jgraph.setPreferredSize(new Dimension(600, 400));
>>                    _jgraph.setSize(600, 400);
>>                }
>>   +
>>   +            // Set the zoom factor.
>>   +            Parameter zoom = (Parameter)getModel().getAttribute(
>>   +                    "_vergilZoomFactor", Parameter.class);
>>   +            if (zoom != null) {
>>   +                zoom(((DoubleToken)zoom.getToken()).doubleValue());
>>   +                // Make sure the visibility is only expert.
>>   +                zoom.setVisibility(Settable.EXPERT);
>>   +            }
>>   +
>>   +            // Set the pan position.
>>   +            Parameter pan = (Parameter)getModel().getAttribute(
>>   +                    "_vergilCenter", Parameter.class);
>>   +            if (pan != null) {
>>   +                ArrayToken panToken = (ArrayToken)pan.getToken();
>>   +                Point2D center = new Point2D.Double(
>>   + ((DoubleToken)panToken.getElement(0)).doubleValue(),
>>   + ((DoubleToken)panToken.getElement(1)).doubleValue());
>>   +                setCenter(center);
>>   +                // Make sure the visibility is only expert.
>>   +                pan.setVisibility(Settable.EXPERT);
>>   +            }
>>   +
>>            } catch (Exception ex) {
>>                // Ignore problems here.  Errors simply result in a 
>> default
>>                // size and location.
>>   @@ -282,29 +342,12 @@
>>            if (!gotLibrary) {
>>                // Neither the model nor the argument have specified a 
>> library.
>>                // See if there is a default library in the configuration.
>>   -            Configuration configuration = getConfiguration();
>>   -            if (configuration != null) {
>>   -                _topLibrary = (CompositeEntity)
>>   -                    configuration.getEntity("actor library");
>>   -                if (_topLibrary == null) {
>>   -                    // Create an empty library by default.
>>   -                    Workspace workspace = entity.workspace();
>>   -                    _topLibrary = new CompositeEntity(workspace);
>>   -                    try {
>>   -                        _topLibrary.setName("topLibrary");
>>   -                        // Put a marker in so that this is
>>   -                        // recognized as a library.
>>   -                        new Attribute(_topLibrary, "_libraryMarker");
>>   -                    } catch (Exception ex) {
>>   -                        throw new InternalErrorException(
>>   -                                "Library configuration failed: " + 
>> ex);
>>   -                    }
>>   -                }
>>   -            }
>>   +            _topLibrary = _createDefaultLibrary(entity.workspace());
>>            }
>>
>>            _libraryModel = new VisibleTreeModel(_topLibrary);
>>   -
>>   +
>>   +// added for kepler-DFH
>>            Configuration config = getConfiguration();
>>            LibraryPaneFactory factory = (LibraryPaneFactory)
>>                 config.getAttribute("libraryPaneFactory");
>>   @@ -324,15 +367,40 @@
>>                    // Do nothing, the library will not show
>>                }
>>            }
>>   +
>>   +// end kepler add-DFH
>>   +/* ---------- removed for Kepler - DFH
>>   +        _library = new PTree(_libraryModel);
>>   +        _library.setRootVisible(false);
>>   +        _library.setBackground(BACKGROUND_COLOR);
>>   +
>>   +        // If you want to expand the top-level libraries, uncomment 
>> this.
>>
>>   -        //_libraryPane = new BasicLibraryPane(_libraryModel);
>>   -        //_libraryPane = new BasicLibraryPane(_libraryModel);
>>   +        //  Object[] path = new Object[2];
>>   +        //  path[0] = topLibrary;
>>   +        //  Iterator libraries = topLibrary.entityList().iterator();
>>   +        //  while (libraries.hasNext()) {
>>   +        //  path[1] = libraries.next();
>>   +        //  _library.expandPath(new TreePath(path));
>>   +        //  }
>>
>>   +
>>   +        _libraryContextMenuCreator = new PTreeMenuCreator();
>>   +        _libraryContextMenuCreator.addMenuItemFactory(
>>   +                new OpenLibraryMenuItemFactory());
>>   +        _library.addMouseListener(_libraryContextMenuCreator);
>>   +
>>   +        _libraryScrollPane = new JScrollPane(_library);
>>   +        _libraryScrollPane.setMinimumSize(new Dimension(200, 200));
>>   +        _libraryScrollPane.setPreferredSize(new Dimension(200, 200));
>>   +// -----------DFH
>>   +*/
>>            // create the palette on the left.
>>            _palettePane = new JPanel();
>>            _palettePane.setBorder(null);
>>            _palettePane.setLayout(new BoxLayout(_palettePane, 
>> BoxLayout.Y_AXIS));
>>
>>   +//DFH        _palettePane.add(_libraryScrollPane, 
>> BorderLayout.CENTER);
>>            _palettePane.add(_libraryPane, BorderLayout.CENTER);
>>            _palettePane.add(_graphPanner, BorderLayout.SOUTH);
>>
>>   @@ -341,7 +409,6 @@
>>            _splitPane.setRightComponent(_jgraph);
>>            getContentPane().add(_splitPane, BorderLayout.CENTER);
>>
>>   -        // FIXME: hotkeys, shortcuts and move to a base class.
>>            _toolbar = new JToolBar();
>>            getContentPane().add(_toolbar, BorderLayout.NORTH);
>>
>>   @@ -353,10 +420,6 @@
>>            _cutAction = new CutAction();
>>            _copyAction = new CopyAction();
>>            _pasteAction = new PasteAction();
>>   -        _createHierarchyAction = new CreateHierarchyAction();
>>   -        _layoutAction = new LayoutAction();
>>   -        _saveInLibraryAction = new SaveInLibraryAction();
>>   -        _importLibraryAction = new ImportLibraryAction();
>>        }
>>
>>        
>> ///////////////////////////////////////////////////////////////////
>>   @@ -379,7 +442,9 @@
>>                    setModified(persistent);
>>                }
>>            }
>>   -        _graphPanner.repaint();
>>   +        if (_graphPanner != null) {
>>   +            _graphPanner.repaint();
>>   +        }
>>        }
>>
>>        /** React to the fact that a change has triggered an error by
>>   @@ -440,11 +505,11 @@
>>                        while (!(headOK && tailOK) && objects.hasNext()) {
>>                            Object object = objects.next();
>>                            if (!headOK && 
>> GraphUtilities.isContainedNode(head,
>>   -                                object, graphModel)) {
>>   +                                    object, graphModel)) {
>>                                headOK = true;
>>                            }
>>                            if (!tailOK && 
>> GraphUtilities.isContainedNode(tail,
>>   -                                object, graphModel)) {
>>   +                                    object, graphModel)) {
>>                                tailOK = true;
>>                            }
>>                        }
>>   @@ -463,10 +528,13 @@
>>                    NamedObj element = (NamedObj)elements.next();
>>                    // first level to avoid obnoxiousness with
>>                    // toplevel translations.
>>   -                element.exportMoML(buffer, 1);
>>   +                element.exportMoML(buffer, 0);
>>   +            }
>>   +            NamedObj container = (NamedObj)graphModel.getRoot();
>>   +            if (container instanceof CompositeEntity) {
>>   +                buffer.write(((CompositeEntity)container)
>>   +                        .exportLinks(1, namedObjSet));
>>                }
>>   -            CompositeEntity container = 
>> (CompositeEntity)graphModel.getRoot();
>>   -            buffer.write(container.exportLinks(1, namedObjSet));
>>
>>                // The code below does not use a PtolemyTransferable,
>>                // to work around
>>   @@ -507,11 +575,17 @@
>>
>>            // First get all the nodes.
>>            try {
>>   -            final CompositeEntity container =
>>   -                (CompositeEntity)graphModel.getRoot();
>>   -            final String name = container.uniqueName("typed 
>> composite actor");
>>   +            final NamedObj container =
>>   +                (NamedObj)graphModel.getRoot();
>>   +            if (!(container instanceof CompositeEntity)) {
>>   +                // This is an internal error because a reasonable 
>> GUI should not
>>   +                // provide access to this functionality.
>>   +                throw new InternalErrorException(
>>   +                        "Cannot create hierarchy if the container 
>> is not a CompositeEntity.");
>>   +            }
>>   +            final String name = 
>> container.uniqueName("CompositeActor");
>>                final TypedCompositeActor compositeActor = new 
>> TypedCompositeActor(
>>   -                    container, name);
>>   +                    (CompositeEntity)container, name);
>>
>>                double[] location = new double[2];
>>                boolean gotLocation = false;
>>   @@ -551,11 +625,11 @@
>>                            while (!(headOK && tailOK) && 
>> objects.hasNext()) {
>>                                Object object = objects.next();
>>                                if (!headOK && 
>> GraphUtilities.isContainedNode(head,
>>   -                                    object, graphModel)) {
>>   +                                        object, graphModel)) {
>>                                    headOK = true;
>>                                }
>>                                if (!tailOK && 
>> GraphUtilities.isContainedNode(tail,
>>   -                                    object, graphModel)) {
>>   +                                        object, graphModel)) {
>>                                    tailOK = true;
>>                                }
>>                            }
>>   @@ -755,7 +829,8 @@
>>                        this, container, moml.toString()) {
>>                        protected void _execute() throws Exception {
>>                            super._execute();
>>   -                        NamedObj newObject = 
>> container.getEntity(name);
>>   +                        NamedObj newObject = 
>> ((CompositeEntity)container)
>>   +                            .getEntity(name);
>>                            //_setLocation(compositeActor, point);
>>                        }
>>                    };
>>   @@ -783,45 +858,43 @@
>>            // and handing that MoML to the parser
>>
>>            GraphPane graphPane = _jgraph.getGraphPane();
>>   -        GraphController controller =
>>   -            (GraphController)graphPane.getGraphController();
>>   +        GraphController controller
>>   +            = (GraphController)graphPane.getGraphController();
>>            SelectionModel model = controller.getSelectionModel();
>>
>>   -        AbstractBasicGraphModel graphModel =
>>   -            (AbstractBasicGraphModel)controller.getGraphModel();
>>   +        AbstractBasicGraphModel graphModel
>>   +            = (AbstractBasicGraphModel)controller.getGraphModel();
>>            Object selection[] = model.getSelectionAsArray();
>>
>>   +        // First collect selected objects into the userObjects array
>>   +        // and deselect them.
>>            Object userObjects[] = new Object[selection.length];
>>   -        // First remove the selection.
>>            for (int i = 0; i < selection.length; i++) {
>>                userObjects[i] = ((Figure)selection[i]).getUserObject();
>>                model.removeSelection(selection[i]);
>>            }
>>
>>   -        // Holds a set of those elements whose deletion goes 
>> through MoML.
>>   -        // This is the large majority of deleted objects.
>>   -        // Currently the only exception are links from a port to 
>> nowhere.
>>   -        HashSet namedObjNodeSet = new HashSet();
>>   -        HashSet namedObjEdgeSet = new HashSet();
>>   -        // Holds those elements whose deletion does not go through 
>> MoML. This
>>   -        // is only links which are no connected to another port or 
>> a relation.
>>   +        // Create a set to hold those elements whose deletion
>>   +        // does not go through MoML. This is only links that
>>   +        // are not connected to another port or a relation.
>>            HashSet edgeSet = new HashSet();
>>
>>            // Generate the MoML to carry out the deletion
>>   -        StringBuffer moml = new StringBuffer();
>>   -        moml.append("<group>\n");
>>   +        StringBuffer moml = new StringBuffer("<group>\n");
>>
>>            // Delete edges then nodes, since deleting relations may
>>            // result in deleting links to that relation.
>>            for (int i = 0; i < selection.length; i++) {
>>                Object userObject = userObjects[i];
>>                if (graphModel.isEdge(userObject)) {
>>   -                NamedObj actual =
>>   -                    
>> (NamedObj)graphModel.getSemanticObject(userObject);
>>   -                if (actual != null) {
>>   -                    
>> moml.append(graphModel.getDeleteEdgeMoML(userObject));
>>   -                } else {
>>   +                NamedObj actual
>>   +                    = 
>> (NamedObj)graphModel.getSemanticObject(userObject);
>>   +                // If there is no semantic object, then this edge is
>>   +                // not fully connected, so we can't go through MoML.
>>   +                if (actual == null) {
>>                        edgeSet.add(userObject);
>>   +                } else {
>>   +                    
>> moml.append(graphModel.getDeleteEdgeMoML(userObject));
>>                    }
>>                }
>>            }
>>   @@ -860,20 +933,11 @@
>>            // of most deletions.
>>            try {
>>                // Finally create and request the change
>>   -            NamedObj object = (NamedObj)graphModel.getRoot();
>>   -            NamedObj container = 
>> MoMLChangeRequest.getDeferredToParent(object);
>>   -            if (container == null) {
>>   -                container = (NamedObj)object.getContainer();
>>   -            }
>>   -            if (container == null) {
>>   -                container = object;
>>   -            }
>>   -
>>   -            CompositeEntity toplevel = (CompositeEntity)container;
>>   -            MoMLChangeRequest change =
>>   -                new MoMLChangeRequest(this, toplevel, 
>> moml.toString());
>>   +            NamedObj container = graphModel.getPtolemyModel();
>>   +            MoMLChangeRequest change
>>   +                = new MoMLChangeRequest(this, container, 
>> moml.toString());
>>                change.setUndoable(true);
>>   -            toplevel.requestChange(change);
>>   +            container.requestChange(change);
>>            }
>>            catch (Exception ex) {
>>                MessageHandler.error("Delete failed, changeRequest 
>> was:" + moml,
>>   @@ -887,150 +951,6 @@
>>
>>        }
>>
>>   -    /** Delete the currently selected objects from this document.
>>   -     */
>>   -    public void deleteOld() {
>>   -        // Note that we previously a delete was handled at the 
>> model level.
>>   -        // Now a delete is handled by generating MoML to carry out 
>> the delete
>>   -        // and handing that MoML to the parser
>>   -
>>   -        GraphPane graphPane = _jgraph.getGraphPane();
>>   -        GraphController controller =
>>   -            (GraphController)graphPane.getGraphController();
>>   -        SelectionModel model = controller.getSelectionModel();
>>   -        // AbstractPtolemyGraphModel graphModel =
>>   -        //    (AbstractPtolemyGraphModel)controller.getGraphModel();
>>   -        AbstractBasicGraphModel graphModel =
>>   -            (AbstractBasicGraphModel)controller.getGraphModel();
>>   -        Object selection[] = model.getSelectionAsArray();
>>   -
>>   -        Object userObjects[] = new Object[selection.length];
>>   -        // First remove the selection.
>>   -        for (int i = 0; i < selection.length; i++) {
>>   -            userObjects[i] = ((Figure)selection[i]).getUserObject();
>>   -            model.removeSelection(selection[i]);
>>   -        }
>>   -
>>   -        // Holds a set of those elements whose deletion goes 
>> through MoML.
>>   -        // This is the large majority of deleted objects.
>>   -        // Currently the only exception are links from a port to 
>> nowhere.
>>   -        HashSet namedObjNodeSet = new HashSet();
>>   -        HashSet namedObjEdgeSet = new HashSet();
>>   -        // Holds those elements whose deletion does no go through 
>> MoML. This
>>   -        // is only links which are no connected to another port or 
>> a relation.
>>   -        HashSet edgeSet = new HashSet();
>>   -        // First make a set of all the semantic objects as they may
>>   -        // appear more than once
>>   -        for (int i = 0; i < selection.length; i++) {
>>   -            Object userObject = userObjects[i];
>>   -            if (graphModel.isEdge(userObject) ||
>>   -                    graphModel.isNode(userObject)) {
>>   -                NamedObj actual =
>>   -                    
>> (NamedObj)graphModel.getSemanticObject(userObject);
>>   -                if (actual != null) {
>>   -                    if (graphModel.isEdge(userObject)) {
>>   -                        namedObjEdgeSet.add(actual);
>>   -                    } else {
>>   -                        namedObjNodeSet.add(actual);
>>   -                    }
>>   -                }
>>   -                else {
>>   -                    // Special case, do not handle through MoML but
>>   -                    // simply delete which means this deletion is not
>>   -                    // undoable
>>   -                    edgeSet.add(userObject);
>>   -                }
>>   -            }
>>   -
>>   -        }
>>   -        // Merge the two hashsets so that any edges get deleted first.
>>   -        // This is need to avoid problems with relations not 
>> existing due to
>>   -        // the way some relations are hidden and ports are shown 
>> directly
>>   -        // connected
>>   -
>>   -        // Formerly, we used an ArrayList here, but this caused 
>> problems
>>   -        // if we had a relation between two links and the user 
>> selected
>>   -        // the relation and a link by dragging a box.
>>   -        // JDK1.4 provides us with a LinkedHashSet that is ordered and
>>   -        // has unique elements, so we use that. -cxh 11/16/02
>>   -        //
>>   -        //ArrayList namedObjList = new ArrayList(namedObjEdgeSet);
>>   -        //namedObjList.addAll(namedObjNodeSet);
>>   -
>>   -        LinkedHashSet namedObjList = new 
>> LinkedHashSet(namedObjEdgeSet);
>>   -        namedObjList.addAll(namedObjNodeSet);
>>   -
>>   -        // Generate the MoML to carry out the deletion
>>   -        StringBuffer moml = new StringBuffer();
>>   -        moml.append("<group>\n");
>>   -        Iterator elements = namedObjList.iterator();
>>   -        while (elements.hasNext()) {
>>   -            NamedObj element = (NamedObj)elements.next();
>>   -            String deleteElemName = "";
>>   -            if (element instanceof Relation) {
>>   -                deleteElemName = "deleteRelation";
>>   -            }
>>   -            else if (element instanceof Entity) {
>>   -                deleteElemName = "deleteEntity";
>>   -            }
>>   -            else if (element instanceof Attribute) {
>>   -                deleteElemName = "deleteProperty";
>>   -            }
>>   -            else if (element instanceof Port) {
>>   -                deleteElemName = "deletePort";
>>   -            }
>>   -            else {
>>   -                // What else is there?
>>   -            }
>>   -            if (deleteElemName.length() > 0) {
>>   -                moml.append("<" + deleteElemName + " name=\"" +
>>   -                        element.getName() + "\" />\n");
>>   -            }
>>   -        }
>>   -        moml.append("</group>\n");
>>   -
>>   -        // Have both MoML to perform deletion and set of objects whose
>>   -        // deletion does not go through MoML. This set of objects
>>   -        // should be very small and so far consists of only links 
>> that are not
>>   -        // connected to a relation
>>   -        try {
>>   -            // First manually delete any objects whose deletion 
>> does not go
>>   -            // through MoML and so are not undoable
>>   -            // Note that we turn off event dispatching so that each 
>> individual
>>   -            // removal does not trigger graph redrawing.
>>   -            graphModel.setDispatchEnabled(false);
>>   -            Iterator edges = edgeSet.iterator();
>>   -            while (edges.hasNext()) {
>>   -                Object nextEdge = edges.next();
>>   -                if (graphModel.isEdge(nextEdge)) {
>>   -                    graphModel.disconnectEdge(this, nextEdge);
>>   -                }
>>   -            }
>>   -        }
>>   -        finally {
>>   -            graphModel.setDispatchEnabled(true);
>>   -            /*graphModel.dispatchGraphEvent(new GraphEvent(
>>   -              this,
>>   -              GraphEvent.STRUCTURE_CHANGED,
>>   -              graphModel.getRoot()));*/
>>   -        }
>>   -
>>   -        // Next process the deletion MoML. This should be the large 
>> majority
>>   -        // of most deletions.
>>   -        try {
>>   -            // Finally create and request the change
>>   -            CompositeEntity toplevel = 
>> (CompositeEntity)graphModel.getRoot();
>>   -            MoMLChangeRequest change =
>>   -                new MoMLChangeRequest(this, toplevel, 
>> moml.toString());
>>   -            change.setUndoable(true);
>>   -            toplevel.requestChange(change);
>>   -        }
>>   -        catch (Exception ex) {
>>   -            MessageHandler.error("Delete failed, changeRequest 
>> was:" + moml,
>>   -                    ex);
>>   -        }
>>   -    }
>>   -
>>        /** Override the dispose method to unattach any listeners that 
>> may keep
>>         *  this model from getting garbage collected.
>>         */
>>   @@ -1050,7 +970,7 @@
>>            return new Point2D.Double(rect.getCenterX(), 
>> rect.getCenterY());
>>        }
>>
>>   -    /** Return the jgraph instance that this view uses to represent 
>> the
>>   +    /** Return the JGraph instance that this view uses to represent 
>> the
>>         *  ptolemy model.
>>         */
>>        public JGraph getJGraph() {
>>   @@ -1105,7 +1025,7 @@
>>            // Before doing the layout, need to take a copy of all the 
>> current
>>            // node locations  which can be used to undo the effects of 
>> the move.
>>            try {
>>   -            CompositeEntity composite = model.getPtolemyModel();
>>   +            NamedObj composite = model.getPtolemyModel();
>>                StringBuffer moml = new StringBuffer();
>>                moml.append("<group>\n");
>>                // NOTE: this gives at iteration over locations.
>>   @@ -1122,12 +1042,12 @@
>>                    }
>>                    // Create the MoML, wrapping the location attribute
>>                    // in an element refering to the container
>>   -                String containingElementName = 
>> element.getMoMLInfo().elementName;
>>   +                String containingElementName = 
>> element.getElementName();
>>                    moml.append("<" + containingElementName + " name=\"" +
>>                            element.getName() + "\" >\n");
>>                    // NOTE: use the moml info element name here in 
>> case the
>>                    // location is a vertex
>>   -                moml.append("<" + 
>> location.getMoMLInfo().elementName + " name=\"" +
>>   +                moml.append("<" + location.getElementName() + " 
>> name=\"" +
>>                            location.getName() + "\" value=\"" + 
>> expression + "\" />\n");
>>                    moml.append("</" + containingElementName + ">\n");
>>                }
>>   @@ -1135,8 +1055,8 @@
>>
>>                // Push the undo entry onto the stack
>>                MoMLUndoEntry undoEntry = new MoMLUndoEntry(composite, 
>> moml.toString());
>>   -            UndoInfoAttribute undoInfo = 
>> UndoInfoAttribute.getUndoInfo(composite);
>>   -            undoInfo.pushUndoEntry(undoEntry);
>>   +            UndoStackAttribute undoInfo = 
>> UndoStackAttribute.getUndoInfo(composite);
>>   +            undoInfo.push(undoEntry);
>>            } catch (Exception e) {
>>                // operation not undoable
>>            }
>>   @@ -1166,27 +1086,15 @@
>>            GraphModel model = controller.getGraphModel();
>>            if (transferable == null) return;
>>            try {
>>   -            CompositeEntity toplevel = 
>> (CompositeEntity)model.getRoot();
>>   -            NamedObj container =
>>   -                MoMLChangeRequest.getDeferredToParent(toplevel);
>>   -            if (container == null) {
>>   -                container = toplevel;
>>   -            }
>>   +            NamedObj container = (NamedObj)model.getRoot();
>>                StringBuffer moml = new StringBuffer();
>>                // The pasted version will have the names generated by the
>>                // uniqueName() method of the container, to ensure that 
>> they
>>                // do not collide with objects already in the container.
>>   -            if (container != toplevel) {
>>   -                moml.append("<entity name=\"" +
>>   -                        toplevel.getName(container) + "\">\n");
>>   -            }
>>                moml.append("<group name=\"auto\">\n");
>>                moml.append((String)
>>
>> transferable.getTransferData(DataFlavor.stringFlavor));
>>                moml.append("</group>\n");
>>   -            if (container != toplevel) {
>>   -                moml.append("</entity>");
>>   -            }
>>
>>                MoMLChangeRequest change =
>>                    new MoMLChangeRequest(this, container, 
>> moml.toString());
>>   @@ -1216,8 +1124,7 @@
>>            }
>>        }
>>
>>   -    /**
>>   -     *  Redo the last undone change on the model
>>   +    /** Redo the last undone change on the model
>>         */
>>        public void redo() {
>>            GraphPane graphPane = _jgraph.getGraphPane();
>>   @@ -1225,19 +1132,85 @@
>>                (GraphController)graphPane.getGraphController();
>>            GraphModel model = controller.getGraphModel();
>>            try {
>>   -            CompositeEntity toplevel = 
>> (CompositeEntity)model.getRoot();
>>   -            MoMLUndoChangeRequest change =
>>   -                new MoMLUndoChangeRequest(this, toplevel);
>>   -            change.setRedoable();
>>   +            NamedObj toplevel = (NamedObj)model.getRoot();
>>   +            RedoChangeRequest change =
>>   +                new RedoChangeRequest(this, toplevel);
>>                toplevel.requestChange(change);
>>            }
>>            catch (Exception ex) {
>>                MessageHandler.error("Redo failed", ex);
>>            }
>>        }
>>   +
>>   +    /** Open a file browser and save the given entity in the file 
>> specified
>>   +     *  by the user.
>>   +     *  @param entity The entity to save.
>>   +     *  @exception If something goes wrong.
>>   +     *  @since Ptolemy 4.0
>>   +     */
>>   +    public void saveComponentInFile(Entity entity) throws Exception {
>>   +        // NOTE: This mirrors similar code in Top and TableauFrame, 
>> but
>>   +        // I can't find any way to re-use that code, since the details
>>   +        // are slightly different at each step here.
>>   +        JFileChooser fileDialog = new JFileChooser();
>>   +        fileDialog.setDialogTitle("Save actor as...");
>>   +        if (_directory != null) {
>>   +            fileDialog.setCurrentDirectory(_directory);
>>   +        } else {
>>   +            // The default on Windows is to open at user.home, 
>> which is
>>   +            // typically not what we want.
>>   +            // So we use the current directory instead.
>>   +            // This will fail with a security exception in applets.
>>   +            String currentWorkingDirectory
>>   +                    = StringUtilities.getProperty("user.dir");
>>   +            if (currentWorkingDirectory != null) {
>>   +                fileDialog.setCurrentDirectory(
>>   +                        new File(currentWorkingDirectory));
>>   +            }
>>   +        }
>>   +        fileDialog.setSelectedFile(
>>   +                new File(fileDialog.getCurrentDirectory(),
>>   +                entity.getName() + ".xml"));
>>   +
>>   +        // Show the dialog.
>>   +        int returnVal = fileDialog.showSaveDialog(this);
>>   +
>>   +        if (returnVal == JFileChooser.APPROVE_OPTION) {
>>   +            File file = fileDialog.getSelectedFile();
>>   +            if (!_confirmFile(entity, file)) {
>>   +                return;
>>   +            }
>>   +            // Record the selected directory.
>>   +            _directory = fileDialog.getCurrentDirectory();
>>   +
>>   +            java.io.FileWriter fileWriter = new 
>> java.io.FileWriter(file);
>>   +
>>   +            // Make sure the entity name saved matches the file name.
>>   +            String name = entity.getName();
>>   +            String filename = file.getName();
>>   +            int period = filename.indexOf(".");
>>   +            if (period > 0) {
>>   +                name = filename.substring(0, period);
>>   +            } else {
>>   +                name = filename;
>>   +            }
>>   +            try {
>>   +                fileWriter.write("<?xml version=\"1.0\" 
>> standalone=\"no\"?>\n"
>>   +                        + "<!DOCTYPE " + entity.getElementName() + 
>> " PUBLIC "
>>   +                        + "\"-//UC Berkeley//DTD MoML 1//EN\"\n"
>>   +                        + "    \"http://ptolemy.eecs.berkeley.edu"
>>   +                        + "/xml/dtd/MoML_1.dtd\">\n");
>>   +
>>   +                entity.exportMoML(fileWriter, 0, name);
>>   +            } finally {
>>   +                fileWriter.close();
>>   +            }
>>   +        }
>>   +    }
>>
>>        /** Save the given entity in the user library in the given
>>         *  configuration.
>>   +     *  @param configuration The configuration.
>>         *  @param entity The entity to save.
>>         *  @since Ptolemy 2.1
>>         */
>>   @@ -1258,7 +1231,7 @@
>>
>>                StringWriter buffer = new StringWriter();
>>
>>   -            // Check if there is already something existing in the
>>   +            // Check whether there is already something existing in 
>> the
>>                // user library with this name.
>>                if (library.getEntity(entity.getName()) != null) {
>>                    MessageHandler.error(
>>   @@ -1272,11 +1245,9 @@
>>                ChangeRequest request =
>>                    new MoMLChangeRequest(entity, library, 
>> buffer.toString());
>>                library.requestChange(request);
>>   -        }
>>   -        catch (IOException ex) {
>>   +        } catch (IOException ex) {
>>                // Ignore.
>>   -        }
>>   -        catch (KernelException ex) {
>>   +        } catch (KernelException ex) {
>>                // Ignore.
>>            }
>>        }
>>   @@ -1298,8 +1269,7 @@
>>        }
>>
>>
>>   -    /**
>>   -     *  Undo the last undoable change on the model
>>   +    /** Undo the last undoable change on the model
>>         */
>>        public void undo() {
>>            GraphPane graphPane = _jgraph.getGraphPane();
>>   @@ -1307,9 +1277,9 @@
>>                (GraphController)graphPane.getGraphController();
>>            GraphModel model = controller.getGraphModel();
>>            try {
>>   -            CompositeEntity toplevel = 
>> (CompositeEntity)model.getRoot();
>>   -            MoMLUndoChangeRequest change =
>>   -                new MoMLUndoChangeRequest(this, toplevel);
>>   +            NamedObj toplevel = (NamedObj)model.getRoot();
>>   +            UndoChangeRequest change =
>>   +                new UndoChangeRequest(this, toplevel);
>>                toplevel.requestChange(change);
>>            }
>>            catch (Exception ex) {
>>   @@ -1331,7 +1301,9 @@
>>            canvas.getCanvasPane().setTransform(current);
>>            // Reset the center.
>>            setCenter(center);
>>   -        _graphPanner.repaint();
>>   +        if (_graphPanner != null) {
>>   +            _graphPanner.repaint();
>>   +        }
>>        }
>>
>>        /** Zoom to fit the current figures.
>>   @@ -1348,7 +1320,9 @@
>>                CanvasUtilities.computeFitTransform(bounds, viewSize);
>>            JCanvas canvas = pane.getCanvas();
>>            canvas.getCanvasPane().setTransform(newTransform);
>>   -        _graphPanner.repaint();
>>   +        if (_graphPanner != null) {
>>   +            _graphPanner.repaint();
>>   +        }
>>        }
>>
>>        /** Set zoom to the nominal.
>>   @@ -1359,17 +1333,19 @@
>>                
>> canvas.getCanvasPane().getTransformContext().getTransform();
>>            current.setToIdentity();
>>            canvas.getCanvasPane().setTransform(current);
>>   -        _graphPanner.repaint();
>>   +        if (_graphPanner != null) {
>>   +            _graphPanner.repaint();
>>   +        }
>>        }
>>
>>        
>> ///////////////////////////////////////////////////////////////////
>>        ////                         public variables                  
>> ////
>>
>>        /** The name of the user library.  The default value is
>>   -     *  "user library".  The value of this variable is what appears
>>   +     *  "UserLibrary".  The value of this variable is what appears
>>         *  in the Vergil left hand tree menu.
>>         */
>>   -    public static String VERGIL_USER_LIBRARY_NAME = "user library";
>>   +    public static String VERGIL_USER_LIBRARY_NAME = "UserLibrary";
>>
>>        
>> ///////////////////////////////////////////////////////////////////
>>        ////                         protected methods                 
>> ////
>>   @@ -1414,19 +1390,6 @@
>>            GUIUtilities.addMenuItem(_viewMenu, _zoomFitAction);
>>            GUIUtilities.addHotKey(_jgraph, _zoomOutAction);
>>            GUIUtilities.addMenuItem(_viewMenu, _zoomOutAction);
>>   -
>>   -        _graphMenu = new JMenu("Graph");
>>   -        _graphMenu.setMnemonic(KeyEvent.VK_G);
>>   -        _menubar.add(_graphMenu);
>>   -        GUIUtilities.addHotKey(_jgraph, _layoutAction);
>>   -        GUIUtilities.addMenuItem(_graphMenu, _layoutAction);
>>   -        GUIUtilities.addHotKey(_jgraph, _saveInLibraryAction);
>>   -        GUIUtilities.addMenuItem(_graphMenu, _saveInLibraryAction);
>>   -        GUIUtilities.addHotKey(_jgraph, _importLibraryAction);
>>   -        GUIUtilities.addMenuItem(_graphMenu, _importLibraryAction);
>>   -        _graphMenu.addSeparator();
>>   -        diva.gui.GUIUtilities.addHotKey(_jgraph, 
>> _createHierarchyAction);
>>   -        diva.gui.GUIUtilities.addMenuItem(_graphMenu, 
>> _createHierarchyAction);
>>        }
>>
>>        /** Override the base class to remove the listeners we have
>>   @@ -1447,6 +1410,41 @@
>>            return result;
>>        }
>>
>>   +    /** Create the default library to use if an entity has no
>>   +     *  LibraryAttribute.  Note that this is called in the
>>   +     *  constructor and therefore overrides in subclasses
>>   +     *  should not refer to any members that may not have been
>>   +     *  initialized. If no library is found in the configuration,
>>   +     *  then an empty one is created in the specified workspace.
>>   +     *  @param workspace The workspace in which to create
>>   +     *   the library, if one needs to be created.
>>   +     *  @return The new library, or null if there is no
>>   +     *   configuration.
>>   +     */
>>   +    protected CompositeEntity _createDefaultLibrary(Workspace 
>> workspace) {
>>   +        Configuration configuration = getConfiguration();
>>   +        if (configuration != null) {
>>   +            CompositeEntity result = (CompositeEntity)
>>   +                configuration.getEntity("actor library");
>>   +            if (result == null) {
>>   +                // Create an empty library by default.
>>   +                result = new CompositeEntity(workspace);
>>   +                try {
>>   +                    result.setName("topLibrary");
>>   +                    // Put a marker in so that this is
>>   +                    // recognized as a library.
>>   +                    new Attribute(result, "_libraryMarker");
>>   +                } catch (Exception ex) {
>>   +                    throw new InternalErrorException(
>>   +                            "Library configuration failed: " + ex);
>>   +                }
>>   +            }
>>   +            return result;
>>   +        } else {
>>   +            return null;
>>   +        }
>>   +    }
>>   +
>>        /** Create a new graph pane.  Subclasses will override this to 
>> change
>>         *  the pane that is created.  Note that this method is called in
>>         *  constructor, so derived classes must be careful to not 
>> reference
>>   @@ -1467,22 +1465,6 @@
>>            return _directory;
>>        }
>>
>>   -    /** Query the user for a filename and save the model to that file.
>>   -     *  This overrides the base class so that if we are in
>>   -     *  an inside composite actor, then only that composite actor is
>>   -     *  saved.  In addition, since the superclass clones the model,
>>   -     *  we need to clear and reconstruct the model.
>>   -     *  @return True if the save succeeds.
>>   -     */
>>   -    protected boolean _saveAs() {
>>   -        try {
>>   -            _saveAsFlag = true;
>>   -            return super._saveAs();
>>   -        } finally {
>>   -            _saveAsFlag = false;
>>   -        }
>>   -    }
>>   -
>>        /** Set the directory that was last accessed by this window.
>>         *  @see #_getDirectory
>>         *  @param directory The directory last accessed.
>>   @@ -1533,24 +1515,42 @@
>>                    size = new SizeAttribute(getModel(), "_vergilSize");
>>                }
>>                size.recordSize(_jgraph);
>>   +
>>   +            // Also record zoom and pan state.
>>   +            JCanvas canvas = _jgraph.getGraphPane().getCanvas();
>>   +            AffineTransform current =
>>   + canvas.getCanvasPane().getTransformContext().getTransform();
>>   +            // We assume the scaling in the X and Y directions are 
>> the same.
>>   +            double scale = current.getScaleX();
>>   +            Parameter zoom = (Parameter)getModel().getAttribute(
>>   +                    "_vergilZoomFactor", Parameter.class);
>>   +            if (zoom == null) {
>>   +                // NOTE: This will not propagate.
>>   +                zoom = new ExpertParameter(getModel(), 
>> "_vergilZoomFactor");
>>   +            }
>>   +            zoom.setToken(new DoubleToken(scale));
>>   +            // Make sure the visibility is only expert.
>>   +            zoom.setVisibility(Settable.EXPERT);
>>   +
>>   +            // Save the center, to record the pan state.
>>   +            Point2D center = getCenter();
>>   +            Parameter pan = (Parameter)getModel().getAttribute(
>>   +                    "_vergilCenter", Parameter.class);
>>   +            if (pan == null) {
>>   +                // NOTE: This will not propagate.
>>   +                pan = new ExpertParameter(getModel(), 
>> "_vergilCenter");
>>   +            }
>>   +            Token[] centerArray = new Token[2];
>>   +            centerArray[0] = new DoubleToken(center.getX());
>>   +            centerArray[1] = new DoubleToken(center.getY());
>>   +            pan.setToken(new ArrayToken(centerArray));
>>   +            // Make sure the visibility is only expert.
>>   +            pan.setVisibility(Settable.EXPERT);
>>   +
>>            } catch (Exception ex) {
>>                // Ignore problems here.  Errors simply result in a 
>> default
>>                // size and location.
>>            }
>>   -        // NOTE: This used to override the base class so that saveAs
>>   -        // on a submodel would save only the submodel.  But this was
>>   -        // strange, to have behavior different from save, and also it
>>   -        // broke save for top-level modal models.  So now we just do
>>   -        // the same thing in saveAs as in save.
>>   -        /*
>>   -          if (_saveAsFlag && getModel().getContainer() != null) {
>>   -          java.io.FileWriter fout = new java.io.FileWriter(file);
>>   -          getModel().exportMoML(fout);
>>   -          fout.close();
>>   -          } else {
>>   -          super._writeFile(file);
>>   -          }
>>   -        */
>>
>>            super._writeFile(file);
>>        }
>>   @@ -1558,34 +1558,56 @@
>>        
>> ///////////////////////////////////////////////////////////////////
>>        ////                         protected variables               
>> ////
>>
>>   -    /** The library. */
>>   -    protected CompositeEntity _topLibrary;
>>   +    /** Default background color is a light grey. */
>>   +    protected static Color BACKGROUND_COLOR = new Color(0xe5e5e5);
>>
>>   -    // FIXME: Comments are needed on all these.
>>   -    // FIXME: Need to be in alphabetical order.
>>   +    /** The cut action. */
>>   +    protected Action _cutAction;
>>   +
>>   +    /** The copy action. */
>>   +    protected Action _copyAction;
>>
>>   -    // NOTE: should be somewhere else?
>>   -    // Default background color is a light grey.
>>   -    protected static Color BACKGROUND_COLOR = new Color(0xe5e5e5);
>>   +    /** The instance of EditorDropTarget associated with this 
>> object. */
>>   +    protected EditorDropTarget _dropTarget;
>>
>>   -    protected JGraph _jgraph;
>>   +    /** The edit menu. */
>>   +    protected JMenu _editMenu;
>>   +
>>   +    /** The panner. */
>>        protected JCanvasPanner _graphPanner;
>>   +
>>   +    /** The instance of JGraph for this editor. */
>>   +    protected JGraph _jgraph;
>>   +
>>   +    /** The library display widget. */
>>   +    protected JTree _library;
>>   +
>>   +    /** The library context menu creator. */
>>   +    protected PTreeMenuCreator _libraryContextMenuCreator;
>>   +
>>   +    /** The library model. */
>>        protected EntityTreeModel _libraryModel;
>>   +
>>   +    /** The library pane. */
>>        protected LibraryPane _libraryPane;
>>   +
>>   +    /** The library scroll pane. */
>>   +    protected JScrollPane _libraryScrollPane;
>>   +
>>   +    /** The library display panel. */
>>        protected JPanel _palettePane;
>>   +
>>   +    /** The paste action. */
>>   +    protected Action _pasteAction;
>>   +
>>   +    /** The split pane for library and editor. */
>>        protected JSplitPane _splitPane;
>>
>>   +    /** The toolbar. */
>>        protected JToolBar _toolbar;
>>   -    protected JMenu _editMenu;
>>   -    protected Action _cutAction;
>>   -    protected Action _copyAction;
>>   -    protected Action _pasteAction;
>>   -    /** action for creating a level of hierarchy. */
>>   -    protected Action _createHierarchyAction;
>>   -    protected JMenu _graphMenu;
>>   -    protected Action _layoutAction;
>>   -    protected Action _saveInLibraryAction;
>>   -    protected Action _importLibraryAction;
>>   +
>>   +    /** The library. */
>>   +    protected CompositeEntity _topLibrary;
>>
>>        
>> ///////////////////////////////////////////////////////////////////
>>        ////                         private methods                   
>> ////
>>   @@ -1593,8 +1615,8 @@
>>        /** Delete the currently selected objects from this document 
>> without
>>         *  undo
>>         */
>>   -    public void _deleteWithoutUndo() {
>>   -        //FIXME: This is the old delete() method, before undo was 
>> added
>>   +    private void _deleteWithoutUndo() {
>>   +        // FIXME: This is the old delete() method, before undo was 
>> added.
>>            // createHierarch() calls this method.
>>            GraphPane graphPane = _jgraph.getGraphPane();
>>            GraphController controller =
>>   @@ -1632,9 +1654,9 @@
>>            } finally {
>>                graphModel.setDispatchEnabled(true);
>>                graphModel.dispatchGraphEvent(new GraphEvent(
>>   -                    this,
>>   -                    GraphEvent.STRUCTURE_CHANGED,
>>   -                    graphModel.getRoot()));
>>   +                                                  this,
>>   + GraphEvent.STRUCTURE_CHANGED,
>>   +                                                  
>> graphModel.getRoot()));
>>            }
>>        }
>>
>>   @@ -1645,9 +1667,6 @@
>>        /** Action to redo the last undone MoML change. */
>>        private Action _redoAction = new RedoAction();
>>
>>   -    /** Flag indicating "save as" action rather than "save". */
>>   -    private boolean _saveAsFlag = false;
>>   -
>>        /** Action to undo the last MoML change. */
>>        private Action _undoAction = new UndoAction();
>>
>>   @@ -1679,7 +1698,7 @@
>>                        "Copy the current selection onto the clipboard.");
>>                putValue(GUIUtilities.ACCELERATOR_KEY,
>>                        KeyStroke.getKeyStroke(KeyEvent.VK_C,
>>   -                            Event.CTRL_MASK));
>>   + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
>>                putValue(GUIUtilities.MNEMONIC_KEY,
>>                        new Integer(KeyEvent.VK_C));
>>            }
>>   @@ -1690,33 +1709,6 @@
>>            }
>>        }
>>
>>   -    
>> /////////////////////////////////////////////////////////////////////
>>   -    //// CreateHierarchy
>>   -
>>   -    /** Action to create a typed composite actor that contains the
>>   -     *  the selected actors.
>>   -     */
>>   -    private class CreateHierarchyAction extends AbstractAction {
>>   -
>>   -        /**  Create a new action to introduce a level of hierarchy.
>>   -         */
>>   -        public CreateHierarchyAction() {
>>   -            super("CreateHierarchy");
>>   -            putValue("tooltip",
>>   -                    "Create a TypedCompositeActor that contains the"
>>   -                    + " selected actors.");
>>   -            //putValue(diva.gui.GUIUtilities.ACCELERATOR_KEY,
>>   -            //        KeyStroke.getKeyStroke(KeyEvent.VK_H,
>>   -            //                java.awt.Event.CTRL_MASK));
>>   -            //putValue(diva.gui.GUIUtilities.MNEMONIC_KEY,
>>   -            //        new Integer(KeyEvent.VK_H));
>>   -        }
>>   -
>>   -        public void actionPerformed(ActionEvent e) {
>>   -            createHierarchy();
>>   -        }
>>   -    }
>>   -
>>        
>> ///////////////////////////////////////////////////////////////////
>>        //// CutAction
>>
>>   @@ -1730,7 +1722,7 @@
>>                        "Cut the current selection onto the clipboard.");
>>                putValue(GUIUtilities.ACCELERATOR_KEY,
>>                        KeyStroke.getKeyStroke(KeyEvent.VK_X,
>>   -                            Event.CTRL_MASK));
>>   + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
>>                putValue(GUIUtilities.MNEMONIC_KEY,
>>                        new Integer(KeyEvent.VK_T));
>>            }
>>   @@ -1742,44 +1734,6 @@
>>        }
>>
>>        
>> ///////////////////////////////////////////////////////////////////
>>   -    //// EditIconAction
>>   -
>>   -    // 'Edit Icon' pop up menu not shipped with PtII1.0.
>>   -    // See also ptolemy.vergil.basic/kernel/ActorGraphFrame.java
>>   -    //     public class EditIconAction extends FigureAction {
>>   -    //         public EditIconAction() {
>>   -    //             super("Edit Icon");
>>   -    //         }
>>   -
>>   -    //         public void actionPerformed(ActionEvent e) {
>>   -    //             // Figure out what entity.
>>   -    //             super.actionPerformed(e);
>>   -    //             NamedObj object = getTarget();
>>   -    //             if (!(object instanceof Entity)) return;
>>   -    //             Entity entity = (Entity) object;
>>   -    //             XMLIcon icon = null;
>>   -    //             List iconList = 
>> entity.attributeList(XMLIcon.class);
>>   -    //             if (iconList.size() == 0) {
>>   -    //                 try {
>>   -    //                     icon = new XMLIcon(entity, 
>> entity.uniqueName("icon"));
>>   -    //                 } catch (Exception ex) {
>>   -    //                     throw new InternalErrorException(
>>   -    //                             "duplicated name, but there were 
>> no other icons.");
>>   -    //                 }
>>   -    //             } else if (iconList.size() == 1) {
>>   -    //                 icon = (XMLIcon)iconList.get(0);
>>   -    //             } else {
>>   -    //                 throw new InternalErrorException("entity " + 
>> entity +
>>   -    //                         " contains more than one icon");
>>   -    //             }
>>   -    //             // FIXME make a tableau.
>>   -    //             ApplicationContext appContext = new 
>> ApplicationContext();
>>   -    //             appContext.setTitle("Icon editor");
>>   -    //             new IconEditor(appContext, icon);
>>   -    //         }
>>   -    //     }
>>   -
>>   -    
>> ///////////////////////////////////////////////////////////////////
>>        //// ExecuteSystemAction
>>
>>        /** An action to open a run control window. */
>>   @@ -1791,7 +1745,7 @@
>>                putValue("tooltip", "Execute The Model");
>>                putValue(GUIUtilities.ACCELERATOR_KEY,
>>                        KeyStroke.getKeyStroke(KeyEvent.VK_G,
>>   -                            Event.CTRL_MASK));
>>   + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
>>                putValue(GUIUtilities.MNEMONIC_KEY,
>>                        new Integer(KeyEvent.VK_G));
>>            }
>>   @@ -1809,99 +1763,6 @@
>>        }
>>
>>        
>> ///////////////////////////////////////////////////////////////////
>>   -    //// ImportLibraryAction
>>   -
>>   -    /** An action to import a library of components. */
>>   -    private class ImportLibraryAction extends AbstractAction {
>>   -
>>   -        /** Create a new action to import a library of components. */
>>   -        public ImportLibraryAction() {
>>   -            super("Import Library");
>>   -            putValue("tooltip", "Import a library into the Palette");
>>   -            putValue(GUIUtilities.MNEMONIC_KEY,
>>   -                    new Integer(KeyEvent.VK_M));
>>   -        }
>>   -
>>   -        /** Import a library by first opening a file chooser dialog 
>> and
>>   -         *  then importing the specified library.
>>   -         */
>>   -        public void actionPerformed(ActionEvent e) {
>>   -            // NOTE: this code is mostly copied from Top.
>>   -            JFileChooser chooser = new JFileChooser();
>>   -            chooser.setDialogTitle("Select a library");
>>   -
>>   -            if (_getDirectory() != null) {
>>   -                chooser.setCurrentDirectory(_getDirectory());
>>   -            } else {
>>   -                // The default on Windows is to open at user.home, 
>> which is
>>   -                // typically an absurd directory inside the O/S 
>> installation.
>>   -                // So we use the current directory instead.
>>   -                // FIXME: This will throw a security exception in 
>> an applet?
>>   -                String cwd = StringUtilities.getProperty("user.dir");
>>   -                if (cwd != null) {
>>   -                    chooser.setCurrentDirectory(new File(cwd));
>>   -                }
>>   -            }
>>   -            int result = chooser.showOpenDialog(BasicGraphFrame.this);
>>   -            if (result == JFileChooser.APPROVE_OPTION) {
>>   -                try {
>>   -                    File file = chooser.getSelectedFile();
>>   -                    // FIXME it would be nice if MoMLChangeRequest 
>> had the
>>   -                    // ability to read from a URL
>>   -                    StringBuffer buffer = new StringBuffer();
>>   -                    FileReader reader = new FileReader(file);
>>   -                    char[] chars = new char[50];
>>   -                    while (reader.ready()) {
>>   -                        int count = reader.read(chars, 0, 50);
>>   -                        buffer.append(chars, 0, count);
>>   -                    }
>>   -                    PtolemyEffigy effigy =
>>   -                        (PtolemyEffigy)getTableau().getContainer();
>>   -                    Configuration configuration =
>>   -                        (Configuration)effigy.toplevel();
>>   -                    NamedObj library =
>>   -                        configuration.getEntity("actor library");
>>   -                    if (library == null) return;
>>   -                    ChangeRequest request =
>>   -                        new MoMLChangeRequest(this, library,
>>   -                                buffer.toString(),
>>   -                                file.toURL());
>>   -                    library.requestChange(request);
>>   -                    _setDirectory(chooser.getCurrentDirectory());
>>   -                } catch (Exception ex) {
>>   -                    MessageHandler.error("Library import failed.", 
>> ex);
>>   -                }
>>   -            }
>>   -        }
>>   -    };
>>   -
>>   -    
>> ///////////////////////////////////////////////////////////////////
>>   -    //// LayoutAction
>>   -
>>   -    /** Action to automatically lay out the graph. */
>>   -    private class LayoutAction extends AbstractAction {
>>   -
>>   -        /** Create a new action to automatically lay out the graph. */
>>   -        public LayoutAction() {
>>   -            super("Automatic Layout");
>>   -            putValue("tooltip", "Layout the Graph (Ctrl+T)");
>>   -            putValue(GUIUtilities.ACCELERATOR_KEY,
>>   -                    KeyStroke.getKeyStroke(KeyEvent.VK_T, 
>> Event.CTRL_MASK));
>>   -            putValue(GUIUtilities.MNEMONIC_KEY,
>>   -                    new Integer(KeyEvent.VK_L));
>>   -        }
>>   -
>>   -        /** Lay out the graph. */
>>   -        public void actionPerformed(ActionEvent e) {
>>   -            try {
>>   -                layoutGraph();
>>   -            } catch (Exception ex) {
>>   -                MessageHandler.error("Layout failed", ex);
>>   -            }
>>   -        }
>>   -    }
>>   -
>>   -    
>> ///////////////////////////////////////////////////////////////////
>>        //// PasteAction
>>
>>        /** Paste the current contents of the clipboard into the 
>> current model. */
>>   @@ -1916,7 +1777,7 @@
>>                        "Paste the contents of the clipboard.");
>>                putValue(GUIUtilities.ACCELERATOR_KEY,
>>                        KeyStroke.getKeyStroke(KeyEvent.VK_V,
>>   -                            Event.CTRL_MASK));
>>   + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
>>                putValue(GUIUtilities.MNEMONIC_KEY,
>>                        new Integer(KeyEvent.VK_P));
>>            }
>>   @@ -2118,10 +1979,40 @@
>>        }
>>
>>        
>> /////////////////////////////////////////////////////////////////////
>>   +    //// OpenLibraryMenuItemFactory
>>   +
>>   +    /**
>>   +     *  Create a menu item that will open a library in editable form.
>>   +     */
>>   +    private class OpenLibraryMenuItemFactory implements 
>> MenuItemFactory {
>>   +        /**
>>   +         * Add an item to the given context menu that will open the
>>   +         * given object as an editable model.
>>   +         */
>>   +        public JMenuItem create(
>>   +                final JContextMenu menu, final NamedObj object) {
>>   +            Action action = new AbstractAction("Open for Editing") {
>>   +                    public void actionPerformed(ActionEvent e) {
>>   +                        try {
>>   +                            getConfiguration().openModel(object);
>>   +                        } catch(KernelException ex) {
>>   +                            MessageHandler.error("Open failed.", ex);
>>   +                        }
>>   +                    }
>>   +                };
>>   +            action.putValue("tooltip",
>>   +                    "Open library for editing.");
>>   +            action.putValue(diva.gui.GUIUtilities.MNEMONIC_KEY,
>>   +                    new Integer(KeyEvent.VK_O));
>>   +            return menu.add(action, 
>> (String)action.getValue(Action.NAME));
>>   +        }
>>   +    }
>>   +
>>   +    
>> /////////////////////////////////////////////////////////////////////
>>        //// RedoAction
>>
>>        /**
>>   -     *  Undo the last undoable MoML change on the current current 
>> model.
>>   +     *  Redo the last undone MoML change on the current current model.
>>         */
>>        private class RedoAction extends AbstractAction {
>>
>>   @@ -2135,59 +2026,21 @@
>>                        "Redo the last change undone.");
>>                putValue(diva.gui.GUIUtilities.ACCELERATOR_KEY,
>>                        KeyStroke.getKeyStroke(KeyEvent.VK_Y,
>>   -                            (java.awt.Event.CTRL_MASK)));
>>   -            // FIXME: Why is this R?
>>   + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
>>                putValue(diva.gui.GUIUtilities.MNEMONIC_KEY,
>>                        new Integer(KeyEvent.VK_R));
>>            }
>>
>>            /**
>>   -         *  Paste the current contents of the clipboard into the 
>> current model.
>>   +         *  Redo the last undone MoML change on the current current 
>> model.
>>             *
>>   -         * @param  e  Description of Parameter
>>   +         * @param e The event for the action.
>>             */
>>            public void actionPerformed(ActionEvent e) {
>>                redo();
>>            }
>>        }
>>
>>   -    
>> ///////////////////////////////////////////////////////////////////
>>   -    //// SaveInLibraryAction
>>   -
>>   -    // FIXME: The following needs quite a bit of work.
>>   -    // Changes to the library are not persistent.
>>   -    /** An action to save the current model in a library. */
>>   -    private class SaveInLibraryAction extends AbstractAction {
>>   -
>>   -        /** Create a new action to save a model in a library. */
>>   -        public SaveInLibraryAction() {
>>   -            super("Save In Library");
>>   -            putValue("tooltip", "Save as a Component in Library");
>>   -            putValue(GUIUtilities.MNEMONIC_KEY,
>>   -                    new Integer(KeyEvent.VK_S));
>>   -        }
>>   -
>>   -        /** Create a new instance of the current model in the
>>   -         *  actor library of the configuration.
>>   -         */
>>   -        public void actionPerformed(ActionEvent e) {
>>   -            PtolemyEffigy effigy =
>>   -                (PtolemyEffigy)getTableau().getContainer();
>>   -            NamedObj object = effigy.getModel();
>>   -            if (object == null) {
>>   -                return;
>>   -            }
>>   -            if (!(object instanceof Entity)) {
>>   -                throw new KernelRuntimeException("Could not save in "
>>   -                        + "library, '" + object + "' is not an 
>> Entity");
>>   -            }
>>   -
>>   -            Entity entity = (Entity) object;
>>   -            Configuration configuration = 
>> (Configuration)effigy.toplevel();
>>   -            saveComponentInLibrary(configuration, entity);
>>   -        }
>>   -    }
>>   -
>>        
>> /////////////////////////////////////////////////////////////////////
>>        //// UndoAction
>>
>>   @@ -2206,16 +2059,15 @@
>>                        "Undo the last change.");
>>                putValue(diva.gui.GUIUtilities.ACCELERATOR_KEY,
>>                        KeyStroke.getKeyStroke(KeyEvent.VK_Z,
>>   -                            java.awt.Event.CTRL_MASK));
>>   -            // FIXME: Why is this U?
>>   + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
>>                putValue(diva.gui.GUIUtilities.MNEMONIC_KEY,
>>                        new Integer(KeyEvent.VK_U));
>>            }
>>
>>            /**
>>   -         *  Paste the current contents of the clipboard into the 
>> current model.
>>   +         *  Undo the last undoable MoML change on the current 
>> current model.
>>             *
>>   -         * @param  e  Description of Parameter
>>   +         * @param e The event for the action.
>>             */
>>            public void actionPerformed(ActionEvent e) {
>>                undo();
>>   @@ -2246,7 +2098,7 @@
>>                // work, so we have to do it this way.
>>                putValue(GUIUtilities.ACCELERATOR_KEY,
>>                        KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS,
>>   -                            Event.CTRL_MASK
>>   + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()
>>                                | Event.SHIFT_MASK));
>>                putValue(GUIUtilities.MNEMONIC_KEY,
>>                        new Integer(KeyEvent.VK_Z));
>>   @@ -2278,7 +2130,7 @@
>>                putValue("tooltip", description + " (Ctrl+=)");
>>                putValue(GUIUtilities.ACCELERATOR_KEY,
>>                        KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS,
>>   -                            Event.CTRL_MASK));
>>   + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
>>                putValue(GUIUtilities.MNEMONIC_KEY,
>>                        new Integer(KeyEvent.VK_M));
>>            }
>>   @@ -2309,7 +2161,7 @@
>>                putValue("tooltip", description + " (Ctrl+Shift+-)");
>>                putValue(GUIUtilities.ACCELERATOR_KEY,
>>                        KeyStroke.getKeyStroke(KeyEvent.VK_MINUS,
>>   -                            Event.CTRL_MASK
>>   + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()
>>                                | Event.SHIFT_MASK));
>>                putValue(GUIUtilities.MNEMONIC_KEY,
>>                        new Integer(KeyEvent.VK_F));
>>   @@ -2341,7 +2193,7 @@
>>                putValue("tooltip", description + " (Ctrl+-)");
>>                putValue(GUIUtilities.ACCELERATOR_KEY,
>>                        KeyStroke.getKeyStroke(KeyEvent.VK_MINUS,
>>   -                            Event.CTRL_MASK));
>>   + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
>>                putValue(GUIUtilities.MNEMONIC_KEY,
>>                        new Integer(KeyEvent.VK_U));
>>            }
>>
>>
>>
>> _______________________________________________
>> kepler-cvs mailing list
>> kepler-cvs at ecoinformatics.org
>> http://www.ecoinformatics.org/mailman/listinfo/kepler-cvs
> 
> 
> 
> _______________________________________________
> kepler-cvs mailing list
> kepler-cvs at ecoinformatics.org
> http://www.ecoinformatics.org/mailman/listinfo/kepler-cvs

-- 
-------------------------------------------------------------------
Matt Jones                                     jones at nceas.ucsb.edu
http://www.nceas.ucsb.edu/    Fax: 425-920-2439    Ph: 907-789-0496
National Center for Ecological Analysis and Synthesis (NCEAS)
University of California Santa Barbara
Interested in ecological informatics? http://www.ecoinformatics.org
-------------------------------------------------------------------



More information about the Kepler-dev mailing list