[kepler-dev] Copies of diva and vergil files?

David Welker david.v.welker at gmail.com
Tue Feb 10 14:48:13 PST 2009


Hi Matt and Christopher and everyone,

With respect to the issue of multiple copies of the same jar:

The original idea was that each module should have a copy of all the jar 
files it uses for management purposes. The idea being that this would 
increase transparency, since we would know exactly which jars a module 
depended on. Also, that this would allow for more flexibility, in that 
you could easily remove a jar from your module without worrying that 
another module would break as a result. Finally, there was the idea that 
this would increase, somewhat, the independence of modules. The build 
system actually has not ever prevented anyone from depending on the jars 
in another module, certainly not from the command-line. However, back in 
the day, it used to be that with the IDE files that were generated, each 
module would not export its jars to other modules by default. Thus, to 
get everything to look good in your IDE, each module had to have all the 
jars it depended on. This was quite intentional.

However, my views, at least, on this issue have shifted. I think what we 
need is better reporting abilities in order to increase transparency. In 
much the same way that the build system now has a command "ant 
report-overrides" that will show all the overrides that exist in a 
particular suite, we could build a tool that precisely traces particular 
classes that depend on jars to the jars they depend on. This would allow 
us to increase our transparency goals without duplicating jars. Also, as 
is, any change to a module might disturb another module that depends on 
the trunk of that module (as opposed to a tag of the module that is 
frozen) anyway. Given this, module developers should not worry about the 
impact of removing a jar from a module for modules that depend on them 
anymore than they worry about changing source code. In general, if you 
depend on the trunk of a module, you have to be aware that it could 
change and adapt accordingly. (In this case, if a module you depended on 
removed a jar you needed, the remedy would be to include that jar in 
your own module yourself.)

Anyway, at this point, there is no reason from a technical perspective 
for their to be multiple instances of the same jar in the same suite. 
(Note, however, that it is completely legitimate to have the same jar in 
multiple modules that are not part of the same suite and who never share 
a common lower priority module.) Of course, this problem of multiple 
modules could be ameliorated to some degree by having a common lower 
priority module (or modules) available to many suites that stores jars.  
However, this solution has its own problems, since a suite that 
incorporates such a common module (but not common functionality) is 
going to have access to a lot of dependencies it does not need, which 
means longer download times for suites that use such a module. Of 
course, right now we already have longer download times that necessary, 
given unnecessary duplication of jars. But, I think we could do better.

Furthermore, and I think this is also very problematic, if we have a 
tendency to store jars in a common area, such jars are likely to 
"check-in, but never check-out" of that common area since they will not 
be associated with code that uses them. One would always be very worried 
about breaking software in other modules when one is thinking of 
deleting such a jar. This is especially problematic in the context of 
upgrades. Worries that some other module, somewhere, might depend not 
only on that jar, but that particular version of the jar, in such a 
common module will make us very hesitant to upgrade.

For these reasons, I think we should stick to the following principle. 
As a general matter, lower priority modules should only worry about 
themselves and not about higher priority modules that depend on them. If 
they want to upgrade a library, the should not worry too much about the 
impact on higher priority modules that depend on them. Instead, the 
solution if a higher priority module doesn't want to go along with the 
upgrade is to take a forever frozen snapshot of the lower priority 
module and store it in a tag. In this way, accessing the features of a 
new version of a library and better ensuring that lower priority modules 
can remain on the cutting edge (to the extent that they want to) is enabled.

I think the better solution is as follows: Jars generally should be 
stored in the lowest priority module that actually utilizes the 
functionality of that jar. If the code is refactored in a module such 
that a jar is no longer needed, that jar should be deleted. Higher 
priority modules that depend on lower priority modules should not copy 
such jars, *unless* they are also used in a different context where they 
do not have access to that or another lower priority module that 
contains the jar. (This will be a common case when modules are also 
meant to be run stand-alone.) In such cases, there will be some jar 
duplication, but it will be kept to a minimum.

We could then further develop a reporting mechanism that examines all 
the suites in the system and (1) detects when there is jar duplication 
within a particular suite so we can inquire whether it is justified and 
(2) reports any jars that are stored in modules that do not utilize any 
of the functionality of that jar so that such jars can be deleted. 
Further, we could develop a system (ideally one that outputs a picture 
in graphical form) that reports on the particular jars that a class 
depends on in the context of a particular suite. Such tools would enable 
us to minimize jar duplication on one hand, but avoid the problem of 
jars "checking in, but never checking out" (kind of like the Hotel 
California) and thereby allow for much easier jar upgrades and deletions.

David
> Hi Christopher,
>
> In theory I think we are all on the same page here... we discussed
> this the other day in our group and I think everyone wants there to be
> only one copy of the ptolemy classes, with appropriate extension hooks
> for altering behavior for Kepler in the cases where the behavior can't
> be universally changed.  That said, this kind of refactoring takes
> time, and practically speaking we need a way to temporarily break
> things while designing and implementing a new architecture with
> extensions.  Let's say it takes two to four weeks to redesign and
> implement the new classes with their appropriate hooks in the case of
> the reporting system. We need people to check in on a regular basis
> (e.g., daily), exposing the incremental changes people are making in
> order to have the 4 developers working on this feature to synchronize
> their development.  Thus, we have used a copy and override model
> during the development process.  Once the hooks are in place and it is
> safe to move the code back to Ptolemy without breaking things for the
> ptolemy team, we will do just that.   Do you have a suggestion as to
> how we can check in daily incremental changes that would break ptolemy
> (e.g., significantly change the GUI) without making a temporary copy?
> The way I think of the modules in Kepler now is that each of them is a
> self contained branch where experimental development can occur, but it
> is fundamentally important that any overrides be merged back into the
> main classes.  If they don't, then we'll end up with significant
> incompatibilities due to bit rot and incompatible changes across
> modules.
>
> That we have a lot of copies in many modules, especially in older
> modules, is a problem that we need to resolve.  The jar copies are
> also a problem, and I think can be solved with a good dependency
> injection system where the jar files are managed in their own modules
> that other modules can depend upon.  I'll bring this issue up with the
> Kepler leadership team for discussion to find a solution.
>
> Matt
>
> On Mon, Feb 9, 2009 at 5:08 PM, Christopher Brooks
> <cxh at eecs.berkeley.edu> wrote:
>   
>> Hi Debi,
>> I've seen "temporary" turn into "shipped"  :-)
>> Thomas Feng has a way to add dropdowns to the Toolbar.
>> Thomas, can you write up something about this?
>> It might help.
>>
>> It might make more sense to figure out how to embed the
>> Ptolemy graph viewer inside a Pane instead of how it currently
>> expect to use ptolemy.gui.Top, which extends JFrame.
>>
>>
>> I was curious, so I took a look in the Kepler svn repository
>> for java files in a /ptolemy/ directory and found these:
>>
>> ./modules/comad/src/ptolemy/domains/pn/kernel/PNDirector.java
>> ./modules/comad/src/ptolemy/domains/pn/kernel/NPNDirector.java
>> ./modules/runtimemonitor/src/ptolemy/actor/OrderedMerge.java
>> ./modules/util/tests/src/test/ptolemy/util/OrderedResourceBundleTest.java
>> ./modules/util/src/ptolemy/vergil/actor/ActorController.java
>> ./modules/util/src/ptolemy/vergil/basic/BasicGraphFrame.java
>> ./modules/util/src/ptolemy/vergil/basic/MenuMapper.java
>> ./modules/util/src/ptolemy/vergil/basic/BasicGraphController.java
>> ./modules/reporting/src/ptolemy/vergil/actor/ActorEditorGraphController.java
>> ./modules/reporting/src/ptolemy/gui/Top.java
>> ./modules/reporting/src/ptolemy/diva/gui/GUIUtilities.java
>> ./modules/gaa/src/ptolemy/vergil/actor/ActorController.java
>> ./modules/gaa/src/ptolemy/moml/MoMLParser.java
>> ./modules/gaa/src/ptolemy/kernel/Entity.java
>> ./modules/pn-branching/src/ptolemy/domains/sdf/lib/ArrayToSequence.java
>> ./modules/core/src/ptolemy/kernel/util/ComponentEntityConfig.java
>> ./modules/core/src/ptolemy/kernel/util/KeplerIconLoader.java
>> ./modules/ppod-gui/src/ptolemy/actor/gui/PtolemyFrame.java
>>
>> There is also the diva file you checked in:
>> ./modules/reporting/src/ptolemy/diva/gui/GUIUtilities.java
>>
>> I'm not sure about these:
>> /modules/reporting/src/ptolemy.vergil.tree/PtolemyTreeCellRenderer.java
>> /modules/reporting/src/ptolemy.vergil.tree/PTree.java
>>
>> I was curious, so below are Java files that share the same name:
>>      8 Main.java
>>      6 FileReader.java
>>      5 Test.java
>>      5 ParseException.java
>>      4 Token.java
>>      4 Sequence.java
>>      4 HelloWorld.java
>>      4 DataToken.java
>>      4 CorbaIllegalActionException.java
>>      4 CorbaIllegalActionExceptionHolder.java
>>      4 CorbaIllegalActionExceptionHelper.java
>>      3 XMLParser.java
>>      3 Utilities.java
>>      3 Transformer.java
>>      3 Top.java
>>      3 TokenMgrError.java
>>      3 Time.java
>>      3 TextFileWriter.java
>>      3 StreamWriter.java
>>      3 StreamDiscarder.java
>>      3 StreamBuffer.java
>>      3 SetMetadata.java
>>      3 Report.java
>>      3 RecordAssembler.java
>>      3 Queue.java
>>      3 Project.java
>>      3 Port.java
>>      3 OrderedMerge.java
>>      3 Node.java
>>      3 Multiplexor.java
>>      3 MoMLSimpleApplication.java
>>      3 List.java
>>      3 Label.java
>>      3 Kepler.java
>>      3 IncomingCollectionManager.java
>>      3 Entity.java
>>      3 Counter.java
>>      3 CollectionTransformer.java
>>      3 BasicGraphController.java
>>      3 AtomicCoactor.java
>>      3 AsyncStreamRouter.java
>>      3 All.java
>>      3 ActorController.java
>>      3 AbstractCollectionManager.java
>> ...
>> Interestingly, there are also lots of duplicated jar files:
>>
>>      6 batik-all-1.6.jar
>>      5 commons-discovery.jar
>>      4 xalan.jar
>>      4 wsdl4j.jar
>>      4 jaxrpc.jar
>>      4 jargon_v2.0.jar
>>      4 ij.jar
>>      4 commons-logging.jar
>>      4 axis.jar
>>      3 xmlsec.jar
>>      3 xml-apis.jar
>>      3 xercesImpl.jar
>>      3 wss4j-1.5.4.jar
>>      3 mail.jar
>>      3 log4j-1.2.8.jar
>>      3 jython.jar
>>      3 junit.jar
>>      3 jode.jar
>>      3 jdom.jar
>>      3 cryptix-asn1.jar
>>      3 cryptix32.jar
>>      3 concurrent.jar
>>      3 commons-httpclient-3.0.1.jar
>>      3 commons-codec-1.3.jar
>>      3 antlr.jar
>>      3 ant.jar
>>      2 xmlsec-1.4.1.jar
>>      2 xml-apis-1.3.04.jar
>>      2 xerces-2.4.0.jar
>>      2 xdoclet-1.2.2.jar
>>      2 xalan-2.7.0.jar
>>      2 woden-impl-dom-1.0M8.jar
>>      2 woden-api-1.0M8.jar
>>      2 wmsd.jar
>>      2 tar.jar
>>      2 stax-api-1.0.1.jar
>>      2 soaplab.jar
>>      2 servlet.jar
>>      2 servlet-api.jar
>>      2 saaj.jar
>>      2 saaj-impl.jar
>>      2 saaj-api.jar
>>      2 rampart-trust-1.4.jar
>>      2 rampart-policy-1.4.jar
>>      2 rampart-core-1.4.jar
>>      2 qaqc.jar
>>      2 puretls.jar
>>      2 org.ecoinformatics.ecogrid.RegistryService-stub.jar
>>      2 org.ecoinformatics.ecogrid.QueryService-stub.jar
>>      2 org.ecoinformatics.ecogrid.PutService-stub.jar
>>      2 org.ecoinformatics.ecogrid.IdentifierService-stub.jar
>>      2 org.ecoinformatics.ecogrid.AuthenticationService-stub.jar
>>      2 org.ecoinformatics.ecogrid.AuthenticatedQueryService-stub.jar
>>      2 opensaml-1.1.jar
>>      2 neethi-2.0.4.jar
>>      2 mysql-connector-java-5.1.6-bin.jar
>>      2 mex-1.4.jar
>>      2 mail-1.4.jar
>>      2 lsid-client.jar
>>      2 log4j-1.3alpha-8.jar
>>      2 kepler-tasks.jar
>>      2 jts-1.4.0.jar
>>      2 jsch-0.1.31.jar
>>      2 jgss.jar
>>      2 jena.jar
>>      2 jaxrpc-spi.jar
>>      2 jaxrpc-impl.jar
>>      2 jaxb-impl.jar
>>      2 jaxb-api.jar
>>      2 jacorb.jar
>>      2 ImageJ.jar
>>      2 HelloWorld.jar
>>      2 gt1.jar
>>      2 gnu-regexp-1.0.8.jar
>>      2 GeoVista-PCPVis.jar
>>      2 forester.jar
>>      2 cryptix.jar
>>      2 commons-net-1.2.1.jar
>>      2 commons-logging-1.1.jar
>>      2 commons-httpclient-2.0-rc2.jar
>>      2 cog-jglobus.jar
>>      2 cog-axis.jar
>>      2 CipresKeplerRegistry.jar
>>      2 cipres_framework.jar
>>      2 castor-0.9.5.jar
>>      2 backport-util-concurrent-3.1.jar
>>      2 axis-wsdl4j-1.2-RC1.jar
>>      2 axis-saaj-1.4.jar
>>      2 axis-jaxrpc-1.2-RC1.jar
>>      2 axis2-kernel-1.4.jar
>>      2 axis2-adb-1.4.jar
>>      2 axis-1.4.jar
>>      2 axiom-impl-1.2.7.jar
>>      2 axiom-api-1.2.7.jar
>>      2 antelope.jar
>>      2 alltools.jar
>>      2 alltools2.jar
>>      2 activation.jar
>>      2 activation-1.1.jar
>>
>> _Christopher
>>
>> debi staggs wrote:
>>     
>>> Hi Christopher,
>>>
>>> I checked in copies of those particular files because for the reporting
>>> module we want to have a drop down box that is in the toolbar, that allows
>>> users to change between three different views.  One view is of the workflow,
>>> another is for the report designer, etc. Using the copies of these files is
>>> very temporary and for testing purposes only.  We are working on a more
>>> flexible and comprehensive way to adapt the GUI from extension points, but
>>> just needed to over-ride those classes temporarily.
>>>
>>> Thanks,
>>>
>>> - Debi
>>>
>>>
>>>
>>> Christopher Brooks wrote:
>>>       
>>>> Hi Debi,
>>>> Why are you checking in a copies of these file?
>>>> Can we add extension points to the original versions?
>>>>
>>>> _Christopher
>>>>
>>>> staggs at ecoinformatics.org wrote:
>>>>         
>>>>> Author: staggs
>>>>> Date: 2009-02-09 15:32:28 -0800 (Mon, 09 Feb 2009)
>>>>> New Revision: 16583
>>>>>
>>>>> Added:
>>>>>   trunk/modules/reporting/src/ptolemy/diva/
>>>>>   trunk/modules/reporting/src/ptolemy/diva/gui/
>>>>>   trunk/modules/reporting/src/ptolemy/diva/gui/GUIUtilities.java
>>>>>   trunk/modules/reporting/src/ptolemy/vergil/actor/
>>>>>
>>>>> trunk/modules/reporting/src/ptolemy/vergil/actor/ActorEditorGraphController.java
>>>>> Log:
>>>>> Added combo box to frame for use in navigating between views.
>>>>>
>>>>> Added: trunk/modules/reporting/src/ptolemy/diva/gui/GUIUtilities.java
>>>>> ===================================================================
>>>>> --- trunk/modules/reporting/src/ptolemy/diva/gui/GUIUtilities.java
>>>>>                      (rev 0)
>>>>> +++ trunk/modules/reporting/src/ptolemy/diva/gui/GUIUtilities.java
>>>>>  2009-02-09 23:32:28 UTC (rev 16583)
>>>>> @@ -0,0 +1,514 @@
>>>>> +/*
>>>>> + Copyright (c) 1998-2006 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  BASIS, AND THE UNIVERSITY OF
>>>>> + CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
>>>>> + ENHANCEMENTS, OR MODIFICATIONS.
>>>>> +
>>>>> + PT_COPYRIGHT_VERSION_2
>>>>> + COPYRIGHTENDKEY
>>>>> + */
>>>>> +package ptolemy.diva.gui;
>>>>> +
>>>>> +import java.awt.Component;
>>>>> +import java.awt.Dimension;
>>>>> +import java.awt.Event;
>>>>> +import java.awt.Insets;
>>>>> +import java.awt.event.ActionListener;
>>>>> +import java.awt.event.KeyEvent;
>>>>> +import java.io.File;
>>>>> +import java.io.PrintWriter;
>>>>> +import java.io.StringWriter;
>>>>> +import java.net.URL;
>>>>> +
>>>>> +import javax.swing.Action;
>>>>> +import javax.swing.Icon;
>>>>> +import javax.swing.ImageIcon;
>>>>> +import javax.swing.JButton;
>>>>> +import javax.swing.JComboBox;
>>>>> +import javax.swing.JComponent;
>>>>> +import javax.swing.JList;
>>>>> +import javax.swing.JMenu;
>>>>> +import javax.swing.JMenuItem;
>>>>> +import javax.swing.JOptionPane;
>>>>> +import javax.swing.JScrollPane;
>>>>> +import javax.swing.JTextArea;
>>>>> +import javax.swing.JToolBar;
>>>>> +import javax.swing.KeyStroke;
>>>>> +import javax.swing.ListSelectionModel;
>>>>> +import javax.swing.event.ListSelectionListener;
>>>>> +
>>>>> +/**
>>>>> + * A collection of utilities for the GUI.
>>>>> + *
>>>>> + * @author John Reekie
>>>>> + * @author Steve Neuendorffer
>>>>> + * @version $Id: GUIUtilities.java 47513 2007-12-07 06:32:21Z cxh $
>>>>> + */
>>>>> +public class GUIUtilities {
>>>>> +    /** JDK1.2 doesn't have this string defined in javax.swing.Action.
>>>>> +     *  This is the value that JDK1.3 uses.
>>>>> +     */
>>>>> +    public static final String ACCELERATOR_KEY = "AcceleratorKey";
>>>>> +
>>>>> +    /** JDK1.2 doesn't have this string defined in javax.swing.Action.
>>>>> +     *  This is the value that JDK1.3 uses.
>>>>> +     */
>>>>> +    public static final String MNEMONIC_KEY = "MnemonicKey";
>>>>> +
>>>>> +    /** This key is used in an action to specify an icon used in
>>>>> toolbars.
>>>>> +     */
>>>>> +    public static final String LARGE_ICON = "LargeIcon";
>>>>> +
>>>>> +    /** This key is used in an action to specify a rollover icon
>>>>> +     *  used in toolbars.
>>>>> +     */
>>>>> +    public static final String ROLLOVER_ICON = "rolloverIcon";
>>>>> +
>>>>> +    /** This key is used in an action to specify a rollover selected
>>>>> icon
>>>>> +     *  used in toolbars.
>>>>> +     */
>>>>> +    public static final String ROLLOVER_SELECTED_ICON =
>>>>> "rolloverSelectedIcon";
>>>>> +
>>>>> +    /** This key is used in an action to specify a selected icon
>>>>> +     *  used in toolbars.
>>>>> +     */
>>>>> +    public static final String SELECTED_ICON = "selectedIcon";
>>>>> +
>>>>> +    /** Add a quick keystroke on the given pane for the given action.
>>>>> +     *  The keystroke that is added is given in the ACCELERATOR_KEY
>>>>> +     *  property that has been set in the action.  If the
>>>>> ACCELERATOR_KEY
>>>>> +     *  property has not been set, then do not add a hotkey.
>>>>> +     */
>>>>> +    public static void addHotKey(JComponent pane, Action action) {
>>>>> +        addHotKey(pane, action, null);
>>>>> +    }
>>>>> +
>>>>> +    /** Add a quick keystroke on the given pane for the given action.
>>>>> +     *  If the given keystroke is null, then use the ACCELERATOR_KEY
>>>>> +     *  property that has been set in the action.  If the given
>>>>> keystroke
>>>>> +     *  is null, Otherwise, set the
>>>>> +     *  ACCELERATOR_KEY property to the given key stroke.
>>>>> +     */
>>>>> +    public static void addHotKey(JComponent pane, Action action,
>>>>> KeyStroke key) {
>>>>> +        String name = (String) action.getValue(Action.NAME);
>>>>> +
>>>>> +        if (key == null) {
>>>>> +            key = (KeyStroke) action.getValue(ACCELERATOR_KEY);
>>>>> +        } else {
>>>>> +            action.putValue(ACCELERATOR_KEY, key);
>>>>> +        }
>>>>> +
>>>>> +        if (key != null) {
>>>>> +            pane.registerKeyboardAction(action, name, key,
>>>>> +                    JComponent.WHEN_IN_FOCUSED_WINDOW);
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    /** Add icons to an action.  This method is used to associate
>>>>> +     *  icons with the different states: unselected, rollover,
>>>>> +     *  rollover selected, selected etc.
>>>>> +     *
>>>>> +     *  @param action The action to which the icons are added.
>>>>> +     *  @param iconRoles A matrix of Strings, where each element
>>>>> +     *  consists of two Strings, the absolute URL of the icon
>>>>> +     *  and the key that represents the role of the icon.  The keys
>>>>> +     *  are usually static fields from this class, such as
>>>>> +     *  {@link #LARGE_ICON}, {@link #ROLLOVER_ICON},
>>>>> +     *  {@link #ROLLOVER_SELECTED_ICON} or {@link #SELECTED_ICON}.
>>>>> +     */
>>>>> +    public static void addIcons(Action action, String[][] iconRoles) {
>>>>> +        for (int i = 0; i < iconRoles.length; i++) {
>>>>> +            URL img = action.getClass().getResource(iconRoles[i][0]);
>>>>> +            if (img != null) {
>>>>> +                ImageIcon icon = new ImageIcon(img);
>>>>> +                action.putValue(iconRoles[i][1], icon);
>>>>> +            }
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    /** Add an action to a menu and return the menu item created.  If
>>>>> +     * the tool tip is null, use the "tooltip" property already in the
>>>>> +     * action, otherwise add the property to the action. (The mnemonic
>>>>> +     * isn't added.)  The new menu item is added to the action as the
>>>>> +     * "menuItem" property.  The menu item's text is set using the
>>>>> +     * action's name, concatenated with a description of a keyboard
>>>>> +     * accelerator, if one has been set previously on the action.
>>>>> +     * The item will be enabled by default.
>>>>> +     */
>>>>> +    public static JMenuItem addMenuItem(JMenu menu, Action action) {
>>>>> +        String label = (String) action.getValue(Action.NAME);
>>>>> +        int mnemonic = 0;
>>>>> +        Integer i = (Integer) action.getValue(MNEMONIC_KEY);
>>>>> +
>>>>> +        if (i != null) {
>>>>> +            mnemonic = i.intValue();
>>>>> +        }
>>>>> +
>>>>> +        return addMenuItem(menu, label, action, mnemonic, null, true);
>>>>> +    }
>>>>> +
>>>>> +    /** Add an action to a menu and return the menu item created.  If
>>>>> +     * the tool tip is null, use the "tooltip" property already in the
>>>>> +     * action, otherwise add the property to the action. (The mnemonic
>>>>> +     * isn't added.)  The new menu item is added to the action as the
>>>>> +     * "menuItem" property.  The menu item's text is set using the
>>>>> +     * action's name, concatenated with a description of a keyboard
>>>>> +     * accelerator, if one has been set previously on the action.
>>>>> +     * The item will be enabled by default.
>>>>> +     */
>>>>> +    public static JMenuItem addMenuItem(JMenu menu, Action action,
>>>>> +            int mnemonic, String tooltip) {
>>>>> +        String label = (String) action.getValue(Action.NAME);
>>>>> +        return addMenuItem(menu, label, action, mnemonic, tooltip,
>>>>> true);
>>>>> +    }
>>>>> +
>>>>> +    /** Add an action to a menu and return the menu item created.  If
>>>>> +     * the tool tip is null, use the "tooltip" property already in the
>>>>> +     * action, otherwise add the property to the action. (The mnemonic
>>>>> +     * isn't added.)  The new menu item is added to the action as the
>>>>> +     * "menuItem" property.  The menu item's text is set to be "label",
>>>>> +     * and is disabled or enabled according to "isEnabled."
>>>>> +     */
>>>>> +    public static JMenuItem addMenuItem(JMenu menu, String label,
>>>>> +            Action action, int mnemonic, String tooltip, boolean
>>>>> isEnabled) {
>>>>> +        if (tooltip == null) {
>>>>> +            tooltip = (String) action.getValue("tooltip");
>>>>> +        } else {
>>>>> +            action.putValue("tooltip", tooltip);
>>>>> +        }
>>>>> +
>>>>> +        action.putValue("tooltip", tooltip);
>>>>> +
>>>>> +        JMenuItem item = menu.add(action);
>>>>> +        item.setText(label);
>>>>> +        item.setEnabled(isEnabled);
>>>>> +        item.setMnemonic(mnemonic);
>>>>> +        item.setToolTipText(tooltip);
>>>>> +
>>>>> +        KeyStroke key = (KeyStroke) action.getValue(ACCELERATOR_KEY);
>>>>> +        item.setAccelerator(key);
>>>>> +        action.putValue("menuItem", item);
>>>>> +        return item;
>>>>> +    }
>>>>> +
>>>>> +    /** Add the action to the given toolbar.
>>>>> +     *  If the LARGE_ICON property is specified in the Action, then use
>>>>> it
>>>>> +     *  for the button.  We use this instead of SMALL_ICON, because
>>>>> +     *  SMALL_ICON shows up when the action is added to a menu, and in
>>>>> +     *  most cases we don't actually want an icon there.
>>>>> +     *  If no icon is specified, then the button will just
>>>>> +     *  have the name of the action.  If the "tooltip" property is
>>>>> specified
>>>>> +     *  in the action, then create a tooltip for the button with the
>>>>> string.
>>>>> +     *  The new button is added to the action as the "toolButton"
>>>>> property.
>>>>> +     *  The button is enabled by default.
>>>>> +     */
>>>>> +    +   +    +       +    +    public static JButton
>>>>> addToolBarButton(JToolBar toolbar, Action action) {
>>>>> +        Icon icon = (Icon) action.getValue(LARGE_ICON);
>>>>> +        String label = null;
>>>>> +
>>>>> +        if (icon == null) {
>>>>> +            label = (String) action.getValue(Action.NAME);
>>>>> +        }
>>>>> +
>>>>> +        return addToolBarButton(toolbar, action, null, icon, label,
>>>>> true);
>>>>> +    }
>>>>> +
>>>>> +    /** Add an action to the toolbar.  If the tool tip is null, use
>>>>> +     * the "tooltip" property already in the action, otherwise add the
>>>>> +     * property to the action. The new button is added to the action
>>>>> +     * as the "toolButton" property.  The button represented by an icon
>>>>> +     * (no text) and is enabled by default.
>>>>> +     */
>>>>> +    public static JButton addToolBarButton(JToolBar toolbar, Action
>>>>> action,
>>>>> +            String tooltip, Icon icon) {
>>>>> +        return addToolBarButton(toolbar, action, tooltip, icon, null,
>>>>> true);
>>>>> +    }
>>>>> +
>>>>> +    /** Add an action to the toolbar.  If the tool tip is null, use
>>>>> +     * the "tooltip" property already in the action, otherwise add the
>>>>> +     * property to the action. The new button is added to the action
>>>>> +     * as the "toolButton" property.  The button represented by an icon
>>>>> +     * (no text) and is enabled by default.
>>>>> +     */
>>>>> +    public static JButton addToolBarButton(JToolBar toolbar, Action
>>>>> action,
>>>>> +            String tooltip, Icon icon, boolean isEnabled) {
>>>>> +        return addToolBarButton(toolbar, action, tooltip, icon, null,
>>>>> isEnabled);
>>>>> +    }
>>>>> +
>>>>> +    /** Add an action to the toolbar.  If the tool tip is null, use
>>>>> +     * the "tooltip" property already in the action, otherwise add the
>>>>> +     * property to the action. The new button is added to the action
>>>>> +     * as the "toolButton" property.  The button represented by text
>>>>> +     * (no icon) and is enabled by default.
>>>>> +     */
>>>>> +    public static JButton addToolBarButton(JToolBar toolbar, Action
>>>>> action,
>>>>> +            String tooltip, String lbl) {
>>>>> +        return addToolBarButton(toolbar, action, tooltip, null, lbl,
>>>>> true);
>>>>> +    }
>>>>> +
>>>>> +    /** Add an action to the toolbar.  If either an icon or a text
>>>>> string
>>>>> +     * are specified (non-null), they are added.  The button is enabled
>>>>> by
>>>>> +     * default.
>>>>> +     */
>>>>> +    public static JButton addToolBarButton(JToolBar toolbar, Action
>>>>> action,
>>>>> +            String tooltip, Icon icon, String lbl) {
>>>>> +        return addToolBarButton(toolbar, action, tooltip, icon, lbl,
>>>>> true);
>>>>> +    }
>>>>> +    +    /**Add a ComboBox drop down to the toolbar. */
>>>>> +   +    +
>>>>> +    public static JComboBox addComboBoxViewChanger(JToolBar toolbar,
>>>>> Action action, String tooltip, +            Icon icon, String lbl, boolean
>>>>> isEnabled) {
>>>>> +       +        if (tooltip == null) {
>>>>> +            tooltip = (String) action.getValue("tooltip");
>>>>> +        } else {
>>>>> +            action.putValue("tooltip", tooltip);
>>>>> +        }
>>>>> +       +        String[] viewsList = {"Edit", "Report", "View"};
>>>>> +        JComboBox comboViewList = new JComboBox(viewsList);
>>>>> +        //comboViewList.setSelectedIndex(2);
>>>>> +        comboViewList.addActionListener(comboViewList);
>>>>> +        comboViewList.setSize(new Dimension(1, 1));
>>>>> +        comboViewList.setPreferredSize(new
>>>>> Dimension(comboViewList.getPreferredSize().width,comboViewList.getPreferredSize().height));
>>>>> +        System.out.println(comboViewList.getSize());    +
>>>>>  toolbar.add(comboViewList);   +        return comboViewList;
>>>>> +    +    }
>>>>> +   +
>>>>> +   +    // public static JComboBox createComboBoxViewChanger(JToolBar
>>>>> toolbar){    +        //    String[] viewNames = {"Edit Workflow", "Design
>>>>> Report", "View Report" };
>>>>> +         //   JComboBox combo = new JComboBox(viewNames);
>>>>> +        //    return combo;
>>>>> +    //    }
>>>>> +     +   +   +    //public static JComboBox addViewsList(JToolBar
>>>>> toolbar, Action action) {
>>>>> +        //return addViewsList(toolbar, action);
>>>>> +    //}
>>>>> +   +
>>>>> +    /** Add an action to the toolbar.  If the tool tip is null, use
>>>>> +     * the "tooltip" property already in the action, otherwise add the
>>>>> +     * property to the action.  The new button is added to the action
>>>>> +     * as the "toolButton" property.  If either an icon or a text
>>>>> string
>>>>> +     * are specified (non-null), they are added.
>>>>> +     */
>>>>> +    public static JButton addToolBarButton(JToolBar toolbar, Action
>>>>> action,
>>>>> +            String tooltip, Icon icon, String lbl, boolean isEnabled) {
>>>>> +        if (tooltip == null) {
>>>>> +            tooltip = (String) action.getValue("tooltip");
>>>>> +        } else {
>>>>> +            action.putValue("tooltip", tooltip);
>>>>> +        }
>>>>> +
>>>>> +        JButton button = toolbar.add(action);
>>>>> +        button.setToolTipText(tooltip);
>>>>> +        button.setText(null);
>>>>> +        button.setRequestFocusEnabled(false);
>>>>> +
>>>>> +        if (icon != null) {
>>>>> +            button.setIcon(icon);
>>>>> +        }
>>>>> +
>>>>> +        if (lbl != null) {
>>>>> +            button.setText(lbl);
>>>>> +        }
>>>>> +
>>>>> +        Icon rolloverIcon = (Icon) action.getValue(ROLLOVER_ICON);
>>>>> +        if (rolloverIcon != null) {
>>>>> +            button.setRolloverIcon(rolloverIcon);
>>>>> +        }
>>>>> +        Icon rolloverSelectedIcon = (Icon) action
>>>>> +                .getValue(ROLLOVER_SELECTED_ICON);
>>>>> +        if (rolloverSelectedIcon != null) {
>>>>> +            button.setRolloverSelectedIcon(rolloverSelectedIcon);
>>>>> +        }
>>>>> +        Icon selectedIcon = (Icon) action.getValue(SELECTED_ICON);
>>>>> +        if (selectedIcon != null) {
>>>>> +            button.setSelectedIcon(selectedIcon);
>>>>> +        }
>>>>> +
>>>>> +        button.setMargin(new Insets(0, 0, 0, 0));
>>>>> +
>>>>> +        //        button.setBorderPainted(false);
>>>>> +        button.setBorderPainted(true);
>>>>> +        button.setEnabled(isEnabled);
>>>>> +        action.putValue("toolBarButton", button);
>>>>> +        return button;
>>>>> +    }
>>>>> +
>>>>> +    /**
>>>>> +     * Return a string that contains the original string, limited to
>>>>> the
>>>>> +     * given number of characters.  If the string is truncated,
>>>>> ellipses
>>>>> +     * will be appended to the end of the string
>>>>> +     */
>>>>> +    public static String ellipsis(String string, int length) {
>>>>> +        if (string.length() > length) {
>>>>> +            return string.substring(0, length - 3) + "...";
>>>>> +        }
>>>>> +
>>>>> +        return string;
>>>>> +    }
>>>>> +
>>>>> +    /** Get the extension of a file. Return a null string is there
>>>>> +     * is no extension.
>>>>> +     */
>>>>> +    public static String getFileExtension(File file) {
>>>>> +        String str = file.getName();
>>>>> +        int i = str.lastIndexOf('.');
>>>>> +
>>>>> +        if (i > 0) {
>>>>> +            return str.substring(i + 1);
>>>>> +        } else {
>>>>> +            return "";
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    /** Return a good string representation of the given keystroke,
>>>>> since
>>>>> +     *  the toString method returns more garbage than we want to see in
>>>>> a
>>>>> +     *  user interface.
>>>>> +     */
>>>>> +    public static String keyStrokeToString(KeyStroke key) {
>>>>> +        int modifiers = key.getModifiers();
>>>>> +        StringBuffer buffer = new StringBuffer();
>>>>> +
>>>>> +        if ((modifiers & Event.SHIFT_MASK) == Event.SHIFT_MASK) {
>>>>> +            buffer.append("(Shift-");
>>>>> +            buffer.append(KeyEvent.getKeyText(key.getKeyCode()));
>>>>> +            buffer.append(")");
>>>>> +        }
>>>>> +
>>>>> +        if ((modifiers & Event.CTRL_MASK) == Event.CTRL_MASK) {
>>>>> +            buffer.append("(Ctrl-");
>>>>> +            buffer.append(KeyEvent.getKeyText(key.getKeyCode()));
>>>>> +            buffer.append(")");
>>>>> +        }
>>>>> +
>>>>> +        if ((modifiers & Event.META_MASK) == Event.META_MASK) {
>>>>> +            buffer.append("(Meta-");
>>>>> +            buffer.append(KeyEvent.getKeyText(key.getKeyCode()));
>>>>> +            buffer.append(")");
>>>>> +        }
>>>>> +
>>>>> +        if ((modifiers & Event.ALT_MASK) == Event.ALT_MASK) {
>>>>> +            buffer.append("(Alt-");
>>>>> +            buffer.append(KeyEvent.getKeyText(key.getKeyCode()));
>>>>> +            buffer.append(")");
>>>>> +        }
>>>>> +
>>>>> +        if (modifiers == 0) {
>>>>> +            buffer.append("(");
>>>>> +            buffer.append(KeyEvent.getKeyText(key.getKeyCode()));
>>>>> +            buffer.append(")");
>>>>> +        }
>>>>> +
>>>>> +        return buffer.toString();
>>>>> +    }
>>>>> +
>>>>> +    /** Display an exception in a nice user-oriented way.  Instead of
>>>>> +     *  displaying the whole stack trace, just display the exception
>>>>> message
>>>>> +     *  and a button for displaying the whole stack trace.
>>>>> +     */
>>>>> +    public static void showException(Component parent, Exception e,
>>>>> String info) {
>>>>> +        Object[] message = new Object[1];
>>>>> +        String string;
>>>>> +
>>>>> +        if (info != null) {
>>>>> +            string = info + "\n" + e.getMessage();
>>>>> +        } else {
>>>>> +            string = e.getMessage();
>>>>> +        }
>>>>> +
>>>>> +        message[0] = ellipsis(string, 400);
>>>>> +
>>>>> +        Object[] options = { "Dismiss", "Display Stack Trace" };
>>>>> +
>>>>> +        // Show the MODAL dialog
>>>>> +        int selected = JOptionPane.showOptionDialog(parent, message,
>>>>> +                "Exception Caught", JOptionPane.YES_NO_OPTION,
>>>>> +                JOptionPane.WARNING_MESSAGE, null, options,
>>>>> options[0]);
>>>>> +
>>>>> +        if (selected == 1) {
>>>>> +            showStackTrace(parent, e, info);
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    /** Display a stack trace dialog. Eventually, the dialog should
>>>>> +     * be able to email us a bug report.
>>>>> +     */
>>>>> +    public static void showStackTrace(Component parent, Exception e) {
>>>>> +        showStackTrace(parent, e, null);
>>>>> +    }
>>>>> +
>>>>> +    /** Display a stack trace dialog. Eventually, the dialog should
>>>>> +     * be able to email us a bug report. The "info" argument is a
>>>>> +     * string printed at the top of the dialog instead of the Exception
>>>>> +     * message.
>>>>> +     */
>>>>> +    public static void showStackTrace(Component parent, Exception e,
>>>>> String info) {
>>>>> +        // Show the stack trace in a scrollable text area.
>>>>> +        StringWriter sw = new StringWriter();
>>>>> +        PrintWriter pw = new PrintWriter(sw);
>>>>> +        e.printStackTrace(pw);
>>>>> +
>>>>> +        JTextArea text = new JTextArea(sw.toString(), 60, 80);
>>>>> +        JScrollPane stext = new JScrollPane(text);
>>>>> +        stext.setPreferredSize(new Dimension(400, 200));
>>>>> +        text.setCaretPosition(0);
>>>>> +        text.setEditable(false);
>>>>> +
>>>>> +        // We want to stack the text area with another message
>>>>> +        Object[] message = new Object[2];
>>>>> +        String string;
>>>>> +
>>>>> +        if (info != null) {
>>>>> +            string = info + "\n" + e.getMessage();
>>>>> +        } else {
>>>>> +            string = e.getMessage();
>>>>> +        }
>>>>> +
>>>>> +        message[0] = ellipsis(string, 400);
>>>>> +        message[1] = stext;
>>>>> +
>>>>> +        // Show the MODAL dialog
>>>>> +        JOptionPane.showMessageDialog(parent, message, "Exception
>>>>> Caught",
>>>>> +                JOptionPane.WARNING_MESSAGE);
>>>>> +    }
>>>>> +
>>>>> +    public static void addComboBoxViewChanger(JToolBar toolbar,
>>>>> +            Action viewAction) {
>>>>> +        String[] ViewsList = {"Workflow Editor", "Report Designer",
>>>>> "Report Viewer" };
>>>>> +        JComboBox viewsCombo = new JComboBox(ViewsList);
>>>>> +        toolbar.add(viewsCombo);
>>>>> +       +    }
>>>>> +}
>>>>>
>>>>> Added:
>>>>> trunk/modules/reporting/src/ptolemy/vergil/actor/ActorEditorGraphController.java
>>>>> ===================================================================
>>>>> ---
>>>>> trunk/modules/reporting/src/ptolemy/vergil/actor/ActorEditorGraphController.java
>>>>>                            (rev 0)
>>>>> +++
>>>>> trunk/modules/reporting/src/ptolemy/vergil/actor/ActorEditorGraphController.java
>>>>>    2009-02-09 23:32:28 UTC (rev 16583)
>>>>> @@ -0,0 +1,766 @@
>>>>> +/* The graph controller for vergil.
>>>>> +
>>>>> + Copyright (c) 1998-2008 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
>>>>> +
>>>>> + */
>>>>> +package ptolemy.vergil.actor;
>>>>> +
>>>>> +import java.awt.Dimension;
>>>>> +import java.awt.Toolkit;
>>>>> +import java.awt.event.ActionEvent;
>>>>> +import java.awt.event.ActionListener;
>>>>> +import java.awt.event.InputEvent;
>>>>> +import java.awt.event.KeyEvent;
>>>>> +import java.awt.geom.AffineTransform;
>>>>> +import java.awt.geom.NoninvertibleTransformException;
>>>>> +import java.awt.geom.Point2D;
>>>>> +import java.awt.geom.Rectangle2D;
>>>>> +import java.lang.reflect.Constructor;
>>>>> +import java.util.Iterator;
>>>>> +
>>>>> +import javax.swing.Action;
>>>>> +import javax.swing.JComboBox;
>>>>> +import javax.swing.JMenu;
>>>>> +import javax.swing.JMenuItem;
>>>>> +import javax.swing.JToolBar;
>>>>> +
>>>>> +import ptolemy.actor.gui.Configuration;
>>>>> +import ptolemy.kernel.CompositeEntity;
>>>>> +import ptolemy.kernel.util.InternalErrorException;
>>>>> +import ptolemy.kernel.util.NamedObj;
>>>>> +import ptolemy.kernel.util.StringAttribute;
>>>>> +import ptolemy.moml.MoMLChangeRequest;
>>>>> +import ptolemy.util.MessageHandler;
>>>>> +import ptolemy.vergil.basic.BasicGraphFrame;
>>>>> +import ptolemy.vergil.basic.NamedObjController;
>>>>> +import ptolemy.vergil.kernel.AttributeController;
>>>>> +import ptolemy.vergil.kernel.Link;
>>>>> +import ptolemy.vergil.kernel.PortDialogAction;
>>>>> +import ptolemy.vergil.kernel.RelationController;
>>>>> +import ptolemy.vergil.toolbox.FigureAction;
>>>>> +import ptolemy.vergil.toolbox.MenuItemFactory;
>>>>> +import ptolemy.vergil.toolbox.SnapConstraint;
>>>>> +import ptolemy.vergil.unit.ConfigureUnitsAction;
>>>>> +import diva.canvas.CanvasComponent;
>>>>> +import diva.canvas.CanvasUtilities;
>>>>> +import diva.canvas.Figure;
>>>>> +import diva.canvas.FigureLayer;
>>>>> +import diva.canvas.Site;
>>>>> +import diva.canvas.connector.AutonomousSite;
>>>>> +import diva.canvas.connector.Connector;
>>>>> +import diva.canvas.connector.ConnectorManipulator;
>>>>> +import diva.canvas.event.LayerEvent;
>>>>> +import diva.canvas.event.MouseFilter;
>>>>> +import diva.canvas.interactor.AbstractInteractor;
>>>>> +import diva.canvas.interactor.ActionInteractor;
>>>>> +import diva.canvas.interactor.CompositeInteractor;
>>>>> +import diva.canvas.interactor.GrabHandle;
>>>>> +import diva.canvas.interactor.Interactor;
>>>>> +import diva.graph.GraphPane;
>>>>> +import diva.graph.JGraph;
>>>>> +import diva.graph.NodeRenderer;
>>>>> +import diva.gui.GUIUtilities;
>>>>> +import diva.gui.toolbox.FigureIcon;
>>>>> +import diva.gui.toolbox.JContextMenu;
>>>>> +import diva.util.UserObjectContainer;
>>>>> +
>>>>>
>>>>> +//////////////////////////////////////////////////////////////////////////
>>>>> +//// ActorEditorGraphController
>>>>> +
>>>>> +/**
>>>>> + A Graph Controller for the Ptolemy II schematic editor.  In addition
>>>>> to the
>>>>> + interaction allowed in the viewer, this controller allows nodes to be
>>>>> + dragged and dropped onto its graph.  Relations can be created by
>>>>> + control-clicking on the background.  Links can be created by
>>>>> control-clicking
>>>>> + and dragging on a port or a relation.  In addition links can be
>>>>> created by
>>>>> + clicking and dragging on the ports that are inside an entity.
>>>>> + Anything can be deleted by selecting it and pressing
>>>>> + the delete key on the keyboard.
>>>>> +
>>>>> + @author Steve Neuendorffer, Contributor: Edward A. Lee, Bert Rodiers
>>>>> + @version $Id: ActorEditorGraphController.java 52222 2009-01-28
>>>>> 01:55:29Z rodiers $
>>>>> + @since Ptolemy II 2.0
>>>>> + @Pt.ProposedRating Red (eal)
>>>>> + @Pt.AcceptedRating Red (johnr)
>>>>> + */
>>>>> +public class ActorEditorGraphController extends
>>>>> ActorViewerGraphController {
>>>>> +    /** Create a new basic controller with default
>>>>> +     *  terminal and edge interactors.
>>>>> +     */
>>>>> +    public ActorEditorGraphController() {
>>>>> +        super();
>>>>> +    }
>>>>> +
>>>>> +    ///////////////////////////////////////////////////////////////////
>>>>> +    ////                         public methods                    ////
>>>>> +
>>>>> +    /** Add commands to the specified menu and toolbar, as appropriate
>>>>> +     *  for this controller.  In this class, commands are added to
>>>>> create
>>>>> +     *  ports and relations.
>>>>> +     *  @param menu The menu to add to, or null if none.
>>>>> +     *  @param toolbar The toolbar to add to, or null if none.
>>>>> +     */
>>>>> +    public void addToMenuAndToolbar(JMenu menu, JToolBar toolbar) {
>>>>> +        super.addToMenuAndToolbar(menu, toolbar);
>>>>> +        diva.gui.GUIUtilities.addMenuItem(menu, _newInputPortAction);
>>>>> +        diva.gui.GUIUtilities.addToolBarButton(toolbar,
>>>>> _newInputPortAction);
>>>>> +        diva.gui.GUIUtilities.addMenuItem(menu, _newOutputPortAction);
>>>>> +        diva.gui.GUIUtilities.addToolBarButton(toolbar,
>>>>> _newOutputPortAction);
>>>>> +        diva.gui.GUIUtilities.addMenuItem(menu, _newInoutPortAction);
>>>>> +        diva.gui.GUIUtilities.addToolBarButton(toolbar,
>>>>> _newInoutPortAction);
>>>>> +        diva.gui.GUIUtilities.addMenuItem(menu,
>>>>> _newInputMultiportAction);
>>>>> +        diva.gui.GUIUtilities.addToolBarButton(toolbar,
>>>>> +                _newInputMultiportAction);
>>>>> +        diva.gui.GUIUtilities.addMenuItem(menu,
>>>>> _newOutputMultiportAction);
>>>>> +        diva.gui.GUIUtilities.addToolBarButton(toolbar,
>>>>> +                _newOutputMultiportAction);
>>>>> +        diva.gui.GUIUtilities.addMenuItem(menu,
>>>>> _newInoutMultiportAction);
>>>>> +        diva.gui.GUIUtilities.addToolBarButton(toolbar,
>>>>> +                _newInoutMultiportAction);
>>>>> +
>>>>> +        menu.addSeparator();
>>>>> +
>>>>> +        // Add an item that adds new relations.
>>>>> +        diva.gui.GUIUtilities.addMenuItem(menu, _newRelationAction);
>>>>> +        diva.gui.GUIUtilities.addToolBarButton(toolbar,
>>>>> _newRelationAction);
>>>>> +        //diva.gui.GUIUtilities.addComboBoxViewChanger(toolbar,
>>>>> _changeViewAction);
>>>>> +        +       String[] ViewsList = {"Workflow Editor", "Report
>>>>> Designer", "Report Viewer" };
>>>>> +        JComboBox viewsCombo = new JComboBox(ViewsList);
>>>>> +        viewsCombo.setSelectedIndex(0);
>>>>> +        Object selectedIndex = viewsCombo.getModel().getSelectedItem();
>>>>> +        String selectedView = viewsCombo.getName();
>>>>> +       +
>>>>>  viewsCombo.addActionListener(_changeViewAction(selectedView));
>>>>> +        //TODO add ActionEvents for each Name   +
>>>>>  toolbar.add(viewsCombo);
>>>>> +           +        }
>>>>> +       +
>>>>> +    /** Set the configuration.  The configuration is used when
>>>>> +     *  opening documentation files.
>>>>> +     *  @param configuration The configuration.
>>>>> +     */
>>>>> +    public void setConfiguration(Configuration configuration) {
>>>>> +        super.setConfiguration(configuration);
>>>>> +
>>>>> +        if (_portDialogAction != null) {
>>>>> +            _portDialogAction.setConfiguration(configuration);
>>>>> +        }
>>>>> +
>>>>> +        if (_configureUnitsAction != null) {
>>>>> +            _configureUnitsAction.setConfiguration(configuration);
>>>>> +        }
>>>>> +
>>>>> +        if (_listenToActorFactory != null) {
>>>>> +            _listenToActorFactory.setConfiguration(configuration);
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    ///////////////////////////////////////////////////////////////////
>>>>> +    ////                         protected methods                 ////
>>>>> +
>>>>> +    ///////////////////////////////////////////////////////////////////
>>>>> +    //// NewRelationAction
>>>>> +    /** An action to create a new relation. */
>>>>> +    public class NewRelationAction extends FigureAction {
>>>>> +        /** Create an action that creates a new relation.
>>>>> +         */
>>>>> +        public NewRelationAction() {
>>>>> +            this(null);
>>>>> +        }
>>>>> +
>>>>> +        /** Create an action that creates a new relation.
>>>>> +         *  @param iconRoles A matrix of Strings, where each element
>>>>> +         *  consists of two Strings, the absolute URL of the icon
>>>>> +         *  and the key that represents the role of the icon.  The keys
>>>>> +         *  are usually static fields from this class, such as
>>>>> +         *  {@link diva.gui.GUIUtilities#LARGE_ICON},
>>>>> +         *  {@link diva.gui.GUIUtilities#ROLLOVER_ICON},
>>>>> +         *  {@link diva.gui.GUIUtilities#ROLLOVER_SELECTED_ICON} or
>>>>> +         *  {@link diva.gui.GUIUtilities#SELECTED_ICON}.
>>>>> +         *  If this parameter is null, then the icon comes from
>>>>> +         *  the calling getNodeRenderer() on the {@link
>>>>> #_portController}.
>>>>> +         *  @see diva.gui.GUIUtilities#addIcons(Action, String[][])
>>>>> +         */
>>>>> +        public NewRelationAction(String[][] iconRoles) {
>>>>> +            super("New Relation");
>>>>> +
>>>>> +            if (iconRoles != null) {
>>>>> +                GUIUtilities.addIcons(this, iconRoles);
>>>>> +            } else {
>>>>> +                // Standard toolbar icons are 25x25 pixels.
>>>>> +                NodeRenderer renderer =
>>>>> _relationController.getNodeRenderer();
>>>>> +                Figure figure = renderer.render(null);
>>>>> +
>>>>> +                FigureIcon icon = new FigureIcon(figure, 25, 25, 1,
>>>>> true);
>>>>> +                putValue(diva.gui.GUIUtilities.LARGE_ICON, icon);
>>>>> +            }
>>>>> +            putValue("tooltip", "Control-click to create a new
>>>>> relation");
>>>>> +            putValue(diva.gui.GUIUtilities.MNEMONIC_KEY, Integer
>>>>> +                    .valueOf(KeyEvent.VK_R));
>>>>> +        }
>>>>> +
>>>>> +        public void actionPerformed(ActionEvent e) {
>>>>> +            super.actionPerformed(e);
>>>>> +
>>>>> +            double x;
>>>>> +            double y;
>>>>> +
>>>>> +            // If you add a vertex on top of an existing link the
>>>>> vertex will
>>>>> +            // be added to the link. If the link exists, link will be
>>>>> different
>>>>> +            // from null.
>>>>> +
>>>>> +            Link link = null;
>>>>> +
>>>>> +            if ((getSourceType() == TOOLBAR_TYPE)
>>>>> +                    || (getSourceType() == MENUBAR_TYPE)) {
>>>>> +                // No location in the action, so put it in the middle.
>>>>> +                BasicGraphFrame frame = ActorEditorGraphController.this
>>>>> +                        .getFrame();
>>>>> +                Point2D center;
>>>>> +
>>>>> +                if (frame != null) {
>>>>> +                    // Put in the middle of the visible part.
>>>>> +                    center = frame.getCenter();
>>>>> +                    x = center.getX();
>>>>> +                    y = center.getY();
>>>>> +                } else {
>>>>> +                    // Put in the middle of the pane.
>>>>> +                    GraphPane pane = getGraphPane();
>>>>> +                    center = pane.getSize();
>>>>> +                    x = center.getX() / 2;
>>>>> +                    y = center.getY() / 2;
>>>>> +                }
>>>>> +            } else {
>>>>> +                // Transform
>>>>> +                AffineTransform current =
>>>>> getGraphPane().getTransformContext()
>>>>> +                        .getTransform();
>>>>> +                AffineTransform inverse;
>>>>> +
>>>>> +                try {
>>>>> +                    inverse = current.createInverse();
>>>>> +                } catch (NoninvertibleTransformException ex) {
>>>>> +                    throw new RuntimeException(ex.toString());
>>>>> +                }
>>>>> +
>>>>> +                Point2D point = new Point2D.Double(getX(), getY());
>>>>> +
>>>>> +                inverse.transform(point, point);
>>>>> +                x = point.getX();
>>>>> +                y = point.getY();               +                +
>>>>>            // If you add a vertex on top of an existing link the vertex will
>>>>> +                // be added to the link. In this code fragment we will
>>>>> find
>>>>> +                // out whether the vertex is on top of a link.
>>>>> +                {
>>>>> +                    GraphPane pane = getGraphPane();
>>>>> +                    FigureLayer foregroundLayer =
>>>>> pane.getForegroundLayer();
>>>>> +        +                    double halo =
>>>>> foregroundLayer.getPickHalo();
>>>>> +                    double width = halo * 2;
>>>>> +
>>>>> +                    // The rectangle in which we search for a Figure.
>>>>> +                    Rectangle2D region = new Rectangle2D.Double(
>>>>> +                            x - halo, y - halo, width, width);
>>>>> +
>>>>> +                    // Iterate through figures within the region.
>>>>> +                    Iterator<?> foregroundFigures =
>>>>> foregroundLayer.getFigures().getIntersectedFigures(region).figuresFromFront();
>>>>> +                    Iterator<?> pickFigures =
>>>>> CanvasUtilities.pickIter(foregroundFigures,
>>>>> +                            region);
>>>>> +
>>>>> +                    while(link == null && pickFigures.hasNext()) {
>>>>> +                        CanvasComponent possibleFigure =
>>>>> (CanvasComponent)pickFigures.next();
>>>>> +                        if (possibleFigure == null) {
>>>>> +                            // Nothing to see here, move along - there
>>>>> is no Figure.
>>>>> +                        } else if (possibleFigure instanceof
>>>>> UserObjectContainer) {
>>>>> +                            // Work our way up the CanvasComponent
>>>>> parent tree
>>>>> +                            // See EditorDropTarget for similar code.
>>>>> +                           if (possibleFigure instanceof
>>>>> UserObjectContainer) {                            +
>>>>>     Object userObject = ((UserObjectContainer)
>>>>> possibleFigure).getUserObject();
>>>>> +                                if (userObject instanceof Link) {
>>>>> +                                    link = (Link) userObject;
>>>>> +                                }
>>>>> +                            }
>>>>> +                        }
>>>>> +                    }
>>>>> +                }                +            }
>>>>> +        +            ActorGraphModel graphModel = (ActorGraphModel)
>>>>> getGraphModel();
>>>>> +            double[] point =
>>>>> _offsetVertex(SnapConstraint.constrainPoint(x, y));
>>>>> +            final NamedObj toplevel = graphModel.getPtolemyModel();
>>>>> +
>>>>> +            if (!(toplevel instanceof CompositeEntity)) {
>>>>> +                throw new InternalErrorException(
>>>>> +                        "Cannot invoke NewRelationAction on an object "
>>>>> +                                + "that is not a CompositeEntity.");
>>>>> +            }
>>>>> +
>>>>> +            final String relationName =
>>>>> toplevel.uniqueName("relation");                +
>>>>> +            StringBuffer moml = new StringBuffer();
>>>>> +            if (link != null) {
>>>>> +                // Add the vertex to an existing link.
>>>>> +                moml.append("<group>\n");
>>>>> +                StringBuffer failmoml = new StringBuffer();
>>>>> +                graphModel.getLinkModel().addNewVertexToLink(moml,
>>>>> +                        failmoml, (CompositeEntity) toplevel, link,
>>>>> relationName, x, y);
>>>>> +                moml.append("</group>\n");
>>>>> +            } else {
>>>>> +                final String vertexName = "vertex1";
>>>>> +                +                // Create the relation.
>>>>>      +                moml.append("<relation name=\"" + relationName +
>>>>> "\">\n");
>>>>> +                moml.append("<vertex name=\"" + vertexName + "\"
>>>>> value=\"{");
>>>>> +                moml.append(point[0] + ", " + point[1]);
>>>>> +                moml.append("}\"/>\n");
>>>>> +                moml.append("</relation>");
>>>>> +            }    +            MoMLChangeRequest request = new
>>>>> MoMLChangeRequest(this, toplevel,
>>>>> +                    moml.toString());
>>>>> +            request.setUndoable(true);
>>>>> +            toplevel.requestChange(request);
>>>>> +        }
>>>>> +
>>>>> +        /** Offset a figure if another figure is already at that
>>>>> location.
>>>>> +         *  @param point An array of two doubles (x and y)
>>>>> +         *  @return An array of two doubles (x and y) that represents
>>>>> +         *  either the original location or an offset location that
>>>>> +         *  does not obscure an object of class <i>figure</i>.
>>>>> +         */
>>>>> +        protected double[] _offsetVertex(double[] point) {
>>>>> +
>>>>> +            GraphPane pane = getGraphPane();
>>>>> +            FigureLayer foregroundLayer = pane.getForegroundLayer();
>>>>> +
>>>>> +            Rectangle2D visibleRectangle;
>>>>> +            BasicGraphFrame frame =
>>>>> ActorEditorGraphController.this.getFrame();
>>>>> +            if (frame != null) {
>>>>> +                visibleRectangle = frame.getVisibleRectangle();
>>>>> +            } else {
>>>>> +                visibleRectangle = pane.getCanvas().getVisibleSize();
>>>>> +            }
>>>>> +            return _offsetFigure(point[0], point[1], _PASTE_OFFSET,
>>>>> +                    _PASTE_OFFSET, ptolemy.moml.Vertex.class,
>>>>> foregroundLayer,
>>>>> +                    visibleRectangle);
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    /** Add hot keys to the actions in the given JGraph.
>>>>> +     *
>>>>> +     *  @param jgraph The JGraph to which hot keys are to be added.
>>>>> +     */
>>>>> +    protected void _addHotKeys(JGraph jgraph) {
>>>>> +        super._addHotKeys(jgraph);
>>>>> +        +
>>>>>  _classDefinitionController.addHotKeys(getFrame().getJGraph());
>>>>> +
>>>>> +    }
>>>>> +
>>>>> +    /** Create the controllers for nodes in this graph.
>>>>> +     *  In this class, controllers with FULL access are created.
>>>>> +     *  This is called by the constructor, so derived classes that
>>>>> +     *  override this must be careful not to reference local variables
>>>>> +     *  defined in the derived classes, because the derived classes
>>>>> +     *  will not have been fully constructed by the time this is
>>>>> called.
>>>>> +     */
>>>>> +    protected void _createControllers() {
>>>>> +        Configuration _config =
>>>>> (Configuration)Configuration.configurations().iterator().next();
>>>>> +        String _alternateActorInstanceClassName = null;
>>>>> +        _attributeController = new AttributeController(this,
>>>>> +                AttributeController.FULL);
>>>>> +
>>>>> +        _classDefinitionController = new
>>>>> ClassDefinitionController(this);
>>>>> +
>>>>> +        if(_config != null) {
>>>>> +          /*
>>>>> +           * If _alternateActorInstanceController is set in the config,
>>>>> use that
>>>>> +           * class as the _entityController instead of the default +
>>>>>         * ActorInstanceController
>>>>> +          */
>>>>> +          StringAttribute _alternateActorInstanceAttribute =
>>>>> (StringAttribute)
>>>>> +            _config.getAttribute("_alternateActorInstanceController");
>>>>> +          if(_alternateActorInstanceAttribute != null) {
>>>>> +            _alternateActorInstanceClassName = +
>>>>>  _alternateActorInstanceAttribute.getExpression();
>>>>> +          }
>>>>> +        }
>>>>> +        +        if(_alternateActorInstanceClassName == null) {
>>>>> +          //System.out.println("Using standard
>>>>> ActorInstanceController");
>>>>> +          +          //default to the normal ActorInstanceController
>>>>> +          _entityController = new ActorInstanceController(this);
>>>>> +        } else {
>>>>> +          try {
>>>>> +            //try to load the alternate class
>>>>> +            +            //System.out.println("Using
>>>>> _alternateActorInstanceController: " + +            //
>>>>>  _alternateActorInstanceClassName);
>>>>> +            Class _alternateActorInstanceClass =
>>>>> Class.forName(_alternateActorInstanceClassName);
>>>>> +            Class[] argsClass = new Class[]
>>>>> {diva.graph.GraphController.class};
>>>>> +            Object[] args = new Object[] {this};
>>>>> +            Constructor alternateActorInstanceConstructor =
>>>>> _alternateActorInstanceClass.getConstructor(argsClass);
>>>>> +            _entityController = (ActorController)
>>>>> alternateActorInstanceConstructor.newInstance(args);
>>>>> +          } catch(Exception e) {
>>>>> +            System.out.println("The configuration has " +
>>>>> +              "_alternateActorInstanceController set, but the class " +
>>>>> +              _alternateActorInstanceClassName + " is not found.
>>>>>  Defaulting " +
>>>>> +              " to ActorInstanceController: " + e.getMessage());
>>>>> +              e.printStackTrace();
>>>>> +          }
>>>>> +        }
>>>>> +        _entityPortController = new IOPortController(this,
>>>>> +                AttributeController.FULL);
>>>>> +        _portController = new ExternalIOPortController(this,
>>>>> +                AttributeController.FULL);
>>>>> +        _relationController = new RelationController(this);
>>>>> +        _linkController = new LinkController(this);
>>>>> +    }
>>>>> +
>>>>> +    /** Initialize interactions for the specified controller.  This
>>>>> +     *  method is called when a new controller is constructed. In this
>>>>> +     *  class, this method attaches a link creator to the controller
>>>>> +     *  if the controller is an instance of ExternalIOPortController,
>>>>> +     *  IOPortController, or RelationController.
>>>>> +     *  @param controller The controller for which to initialize
>>>>> interaction.
>>>>> +     */
>>>>> +    protected void _initializeInteraction(NamedObjController
>>>>> controller) {
>>>>> +        super._initializeInteraction(controller);
>>>>> +
>>>>> +        if (controller instanceof ExternalIOPortController
>>>>> +                || controller instanceof IOPortController
>>>>> +                || controller instanceof RelationController) {
>>>>> +            Interactor interactor = controller.getNodeInteractor();
>>>>> +
>>>>> +            if (interactor instanceof CompositeInteractor) {
>>>>> +                ((CompositeInteractor)
>>>>> interactor).addInteractor(_linkCreator);
>>>>> +            }
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    ///////////////////////////////////////////////////////////////////
>>>>> +    ////                         protected methods                 ////
>>>>> +
>>>>> +    /** Initialize all interaction on the graph pane. This method
>>>>> +     *  is called by the setGraphPane() method of the superclass.
>>>>> +     *  This initialization cannot be done in the constructor because
>>>>> +     *  the controller does not yet have a reference to its pane
>>>>> +     *  at that time.
>>>>> +     */
>>>>> +    protected void initializeInteraction() {
>>>>> +        super.initializeInteraction();
>>>>> +
>>>>> +        GraphPane pane = getGraphPane();
>>>>> +
>>>>> +        // Add a menu command to configure the ports.
>>>>> +        _portDialogAction = new PortDialogAction("Ports");
>>>>> +        _portDialogAction.setConfiguration(getConfiguration());
>>>>> +
>>>>> +        _configureMenuFactory.addAction(_portDialogAction,
>>>>> "Customize");
>>>>> +        _configureUnitsAction = new ConfigureUnitsAction("Units
>>>>> Constraints");
>>>>> +        _configureMenuFactory.addAction(_configureUnitsAction,
>>>>> "Customize");
>>>>> +        _configureUnitsAction.setConfiguration(getConfiguration());
>>>>> +
>>>>> +        // Add a menu command to list to the actor.
>>>>> +        _listenToActorFactory = new ListenToActorFactory();
>>>>> +        _menuFactory.addMenuItemFactory(_listenToActorFactory);
>>>>> +        _listenToActorFactory.setConfiguration(getConfiguration());
>>>>> +
>>>>> +        // Create listeners that creates new relations.
>>>>> +        _relationCreator = new RelationCreator();
>>>>> +        _relationCreator.setMouseFilter(_shortcutFilter);
>>>>> +
>>>>> +        pane.getBackgroundEventLayer().addInteractor(_relationCreator);
>>>>> +
>>>>> +        // Note that shift-click is already bound to the dragSelection
>>>>> +        // interactor when adding things to a selection.
>>>>> +        // Create the interactor that drags new edges.
>>>>> +        _linkCreator = new LinkCreator();
>>>>> +        _linkCreator.setMouseFilter(_shortcutFilter);
>>>>> +
>>>>> +        // NOTE: Do not use _initializeInteraction() because we are
>>>>> +        // still in the constructor, and that method is overloaded in
>>>>> +        // derived classes.
>>>>> +        ((CompositeInteractor) _portController.getNodeInteractor())
>>>>> +                .addInteractor(_linkCreator);
>>>>> +        ((CompositeInteractor)
>>>>> _entityPortController.getNodeInteractor())
>>>>> +                .addInteractor(_linkCreator);
>>>>> +        ((CompositeInteractor) _relationController.getNodeInteractor())
>>>>> +                .addInteractor(_linkCreator);
>>>>> +
>>>>> +        LinkCreator linkCreator2 = new LinkCreator();
>>>>> +        linkCreator2
>>>>> +                .setMouseFilter(new
>>>>> MouseFilter(InputEvent.BUTTON1_MASK, 0));
>>>>> +        ((CompositeInteractor)
>>>>> _entityPortController.getNodeInteractor())
>>>>> +                .addInteractor(linkCreator2);
>>>>> +    }
>>>>> +    +   +    /** Action for creating a new relation. */
>>>>> +    protected Action _newRelationAction = new NewRelationAction(
>>>>> +            new String[][] {
>>>>> +                    { "/ptolemy/vergil/actor/img/relation.gif",
>>>>> +                            GUIUtilities.LARGE_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/relation_o.gif",
>>>>> +                            GUIUtilities.ROLLOVER_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/relation_ov.gif",
>>>>> +                            GUIUtilities.ROLLOVER_SELECTED_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/relation_on.gif",
>>>>> +                            GUIUtilities.SELECTED_ICON } });
>>>>> +
>>>>> +    //   private LinkCreator _linkCreator2;  // For shift-click
>>>>> +
>>>>> +    /** This class is an interactor that interactively drags edges from
>>>>> +     *  one terminal to another, creating a link to connect them.
>>>>> +     */
>>>>> +    protected class LinkCreator extends AbstractInteractor {
>>>>> +        /** Create a new edge when the mouse is pressed. */
>>>>> +        public void mousePressed(LayerEvent event) {
>>>>> +            Figure source = event.getFigureSource();
>>>>> +            NamedObj sourceObject = (NamedObj) source.getUserObject();
>>>>> +
>>>>> +            // Create the new edge.
>>>>> +            Link link = new Link();
>>>>> +
>>>>> +            // Set the tail, going through the model so the link is
>>>>> added
>>>>> +            // to the list of links.
>>>>> +            ActorGraphModel model = (ActorGraphModel) getGraphModel();
>>>>> +            model.getLinkModel().setTail(link, sourceObject);
>>>>> +
>>>>> +            try {
>>>>> +                // add it to the foreground layer.
>>>>> +                FigureLayer layer =
>>>>> getGraphPane().getForegroundLayer();
>>>>> +                Site headSite;
>>>>> +                Site tailSite;
>>>>> +
>>>>> +                // Temporary sites.  One of these will get blown away
>>>>> later.
>>>>> +                headSite = new AutonomousSite(layer, event.getLayerX(),
>>>>> event
>>>>> +                        .getLayerY());
>>>>> +                tailSite = new AutonomousSite(layer, event.getLayerX(),
>>>>> event
>>>>> +                        .getLayerY());
>>>>> +
>>>>> +                // Render the edge.
>>>>> +                Connector c = getEdgeController(link).render(link,
>>>>> layer,
>>>>> +                        tailSite, headSite);
>>>>> +
>>>>> +                // get the actual attach site.
>>>>> +                tailSite = getEdgeController(link).getConnectorTarget()
>>>>> +                        .getTailSite(c, source, event.getLayerX(),
>>>>> +                                event.getLayerY());
>>>>> +
>>>>> +                if (tailSite == null) {
>>>>> +                    throw new RuntimeException("Invalid connector
>>>>> target: "
>>>>> +                            + "no valid site found for tail of new
>>>>> connector.");
>>>>> +                }
>>>>> +
>>>>> +                // And reattach the connector.
>>>>> +                c.setTailSite(tailSite);
>>>>> +
>>>>> +                // Add it to the selection so it gets a manipulator,
>>>>> and
>>>>> +                // make events go to the grab-handle under the mouse
>>>>> +                getSelectionModel().addSelection(c);
>>>>> +
>>>>> +                ConnectorManipulator cm = (ConnectorManipulator)
>>>>> c.getParent();
>>>>> +                GrabHandle gh = cm.getHeadHandle();
>>>>> +                layer.grabPointer(event, gh);
>>>>> +            } catch (Exception ex) {
>>>>> +                MessageHandler.error("Drag connection failed:", ex);
>>>>> +            }
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    /** An interactor for creating relations upon control clicking.
>>>>> +     */
>>>>> +    protected class RelationCreator extends ActionInteractor {
>>>>> +        public RelationCreator() {
>>>>> +            super();
>>>>> +            setAction(_newRelationAction);
>>>>> +        }
>>>>> +    }
>>>>> +
>>>>> +    ///////////////////////////////////////////////////////////////////
>>>>> +    ////                         private variables                 ////
>>>>> +
>>>>> +    private ConfigureUnitsAction _configureUnitsAction;
>>>>> +
>>>>> +    /** The interactors that interactively creates edges. */
>>>>> +    private LinkCreator _linkCreator; // For control-click
>>>>> +
>>>>> +    /** Factory for listen to actor menu item. */
>>>>> +    private ListenToActorFactory _listenToActorFactory;
>>>>> +
>>>>> +    /** Action for creating a new inout multiport. */
>>>>> +    private Action _newInoutMultiportAction = new NewPortAction(
>>>>> +            ExternalIOPortController._GENERIC_INOUT_MULTIPORT,
>>>>> +            "New input/output multiport", KeyEvent.VK_T, new String[][]
>>>>> {
>>>>> +                    { "/ptolemy/vergil/actor/img/multi_inout.gif",
>>>>> +                            GUIUtilities.LARGE_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/multi_inout_o.gif",
>>>>> +                            GUIUtilities.ROLLOVER_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/multi_inout_ov.gif",
>>>>> +                            GUIUtilities.ROLLOVER_SELECTED_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/multi_inout_on.gif",
>>>>> +                            GUIUtilities.SELECTED_ICON } });
>>>>> +
>>>>> +    /** Action for creating a new input/output port. */
>>>>> +    private Action _newInoutPortAction = new NewPortAction(
>>>>> +            ExternalIOPortController._GENERIC_INOUT, "New input/output
>>>>> port",
>>>>> +            KeyEvent.VK_P, new String[][] {
>>>>> +                    { "/ptolemy/vergil/actor/img/single_inout.gif",
>>>>> +                            GUIUtilities.LARGE_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/single_inout_o.gif",
>>>>> +                            GUIUtilities.ROLLOVER_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/single_inout_ov.gif",
>>>>> +                            GUIUtilities.ROLLOVER_SELECTED_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/single_inout_on.gif",
>>>>> +                            GUIUtilities.SELECTED_ICON } });
>>>>> +
>>>>> +    /** Action for creating a new input multiport. */
>>>>> +    private Action _newInputMultiportAction = new NewPortAction(
>>>>> +            ExternalIOPortController._GENERIC_INPUT_MULTIPORT,
>>>>> +            "New input multiport", KeyEvent.VK_N, new String[][] {
>>>>> +                    { "/ptolemy/vergil/actor/img/multi_in.gif",
>>>>> +                            GUIUtilities.LARGE_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/multi_in_o.gif",
>>>>> +                            GUIUtilities.ROLLOVER_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/multi_in_ov.gif",
>>>>> +                            GUIUtilities.ROLLOVER_SELECTED_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/multi_in_on.gif",
>>>>> +                            GUIUtilities.SELECTED_ICON } });
>>>>> +
>>>>> +    /** Action for creating a new input port. */
>>>>> +    private Action _newInputPortAction = new NewPortAction(
>>>>> +            ExternalIOPortController._GENERIC_INPUT, "New input port",
>>>>> +            KeyEvent.VK_I, new String[][] {
>>>>> +                    { "/ptolemy/vergil/actor/img/single_in.gif",
>>>>> +                            GUIUtilities.LARGE_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/single_in_o.gif",
>>>>> +                            GUIUtilities.ROLLOVER_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/single_in_ov.gif",
>>>>> +                            GUIUtilities.ROLLOVER_SELECTED_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/single_in_on.gif",
>>>>> +                            GUIUtilities.SELECTED_ICON } });
>>>>> +
>>>>> +    /** Action for creating a new output multiport. */
>>>>> +    private Action _newOutputMultiportAction = new NewPortAction(
>>>>> +            ExternalIOPortController._GENERIC_OUTPUT_MULTIPORT,
>>>>> +            "New output multiport", KeyEvent.VK_U, new String[][] {
>>>>> +                    { "/ptolemy/vergil/actor/img/multi_out.gif",
>>>>> +                            GUIUtilities.LARGE_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/multi_out_o.gif",
>>>>> +                            GUIUtilities.ROLLOVER_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/multi_out_ov.gif",
>>>>> +                            GUIUtilities.ROLLOVER_SELECTED_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/multi_out_on.gif",
>>>>> +                            GUIUtilities.SELECTED_ICON } });
>>>>> +
>>>>> +    +    +    /** Action for creating a new output port. */
>>>>> +    private Action _newOutputPortAction = new NewPortAction(
>>>>> +            ExternalIOPortController._GENERIC_OUTPUT, "New output
>>>>> port",
>>>>> +            KeyEvent.VK_O, new String[][] {
>>>>> +                    { "/ptolemy/vergil/actor/img/single_out.gif",
>>>>> +                            GUIUtilities.LARGE_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/single_out_o.gif",
>>>>> +                            GUIUtilities.ROLLOVER_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/single_out_ov.gif",
>>>>> +                            GUIUtilities.ROLLOVER_SELECTED_ICON },
>>>>> +                    { "/ptolemy/vergil/actor/img/single_out_on.gif",
>>>>> +                            GUIUtilities.SELECTED_ICON } });
>>>>> +    +    /** Action for changing the view. */
>>>>> +    private Action _changeViewAction(String strView) {
>>>>> +    String view = strView;
>>>>> +    System.out.println("The View is:" + view);
>>>>> +    return null;
>>>>> +        }    {
>>>>> +       +    }
>>>>> +
>>>>> +    ///////////////////////////////////////////////////////////////////
>>>>> +    ////                         inner classes                     ////
>>>>> +    ///////////////////////////////////////////////////////////////////
>>>>> +    //// LinkCreator
>>>>> +
>>>>> +    /** The port dialog factory. */
>>>>> +    private PortDialogAction _portDialogAction;
>>>>> +
>>>>> +    /** The interactor for creating new relations. */
>>>>> +    private RelationCreator _relationCreator;
>>>>> +
>>>>> +    /** The filter for shortcut operations.  This is used for creation
>>>>> +     *  of relations and creation of links from relations. Under PC,
>>>>> +     *  this is a control-1 click.  Under Mac OS X, the control key is
>>>>> +     *  used for context menus and this corresponds to the command-1
>>>>> +     *  click.  For details, see the Apple java archive
>>>>> +     *  http://lists.apple.com/archives/java-dev User: archives,
>>>>> +     *  passwd: archives
>>>>> +     */
>>>>> +    private MouseFilter _shortcutFilter = new MouseFilter(
>>>>> +            InputEvent.BUTTON1_MASK, Toolkit.getDefaultToolkit()
>>>>> +                    .getMenuShortcutKeyMask(),
>>>>> Toolkit.getDefaultToolkit()
>>>>> +                    .getMenuShortcutKeyMask());
>>>>> +
>>>>> +    ///////////////////////////////////////////////////////////////////
>>>>> +    //// RelationCreator
>>>>> +
>>>>> +    ///////////////////////////////////////////////////////////////////
>>>>> +    //// ListenToActorFactory
>>>>> +    private class ListenToActorFactory implements MenuItemFactory {
>>>>> +        /** Add an item to the given context menu that will open a
>>>>> listen
>>>>> +         *  to actor window.
>>>>> +         *  @param menu The context menu.
>>>>> +         *  @param object The object whose ports are being manipulated.
>>>>> +         */
>>>>> +        public JMenuItem create(final JContextMenu menu, NamedObj
>>>>> object) {
>>>>> +            String name = "Listen to Actor";
>>>>> +            final NamedObj target = object;
>>>>> +
>>>>> +            _action = new ActorController.ListenToActorAction(target,
>>>>> +                    ActorEditorGraphController.this);
>>>>> +            _action.setConfiguration(_configuration);
>>>>> +            return menu.add(_action, name);
>>>>> +        }
>>>>> +
>>>>> +        /** Set the configuration for use by the help screen.
>>>>> +         *  @param configuration The configuration.
>>>>> +         */
>>>>> +        public void setConfiguration(Configuration configuration) {
>>>>> +            _configuration = configuration;
>>>>> +
>>>>> +            if (_action != null) {
>>>>> +                _action.setConfiguration(_configuration);
>>>>> +            }
>>>>> +        }
>>>>> +
>>>>> +        private ActorController.ListenToActorAction _action;
>>>>> +
>>>>> +        private Configuration _configuration;
>>>>> +    }
>>>>> +}
>>>>>
>>>>> _______________________________________________
>>>>> Kepler-cvs mailing list
>>>>> Kepler-cvs at kepler-project.org
>>>>> http://mercury.nceas.ucsb.edu/kepler/mailman/listinfo/kepler-cvs
>>>>>           
>> --
>> Christopher Brooks (cxh at eecs berkeley edu) University of California
>> CHESS Executive Director                      US Mail: 337 Cory Hall
>> Programmer/Analyst CHESS/Ptolemy/Trust        Berkeley, CA 94720-1774
>> ph: 510.643.9841 fax:510.642.2718             (Office: 545Q Cory)
>> home: (F-Tu) 707.665.0131 (W-F) 510.655.5480
>> _______________________________________________
>> Kepler-dev mailing list
>> Kepler-dev at kepler-project.org
>> http://mercury.nceas.ucsb.edu/k
>>     
>
>
>
>   



More information about the Kepler-dev mailing list