Package com.acelet.s.workflow

Source Code of com.acelet.s.workflow.JGraphpad

/*
* $Id: JGraphpad.java,v 1.24 2007/07/28 09:41:33 gaudenz Exp $
* Copyright (c) 2001-2005, Gaudenz Alder
*
* All rights reserved.
*
* See LICENSE file for license details. If you are unable to locate
* this file please contact info (at) jgraph (dot) com.
*
* Modified by Wei Jiang from com.jgraph.JGraphpad
*/
package com.acelet.s.workflow;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.KeyboardFocusManager;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.beans.DefaultPersistenceDelegate;
import java.beans.Encoder;
import java.beans.Expression;
import java.beans.PersistenceDelegate;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Authenticator;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JWindow;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.tree.MutableTreeNode;
import javax.xml.parsers.ParserConfigurationException;

import org.jgraph.JGraph;
import org.jgraph.event.GraphSelectionEvent;
import org.jgraph.event.GraphSelectionListener;
import org.jgraph.graph.AttributeMap;
import org.jgraph.graph.ConnectionSet;
import org.jgraph.graph.DefaultEdge;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.DefaultPort;
import org.jgraph.graph.Edge;
import org.jgraph.graph.GraphCell;
import org.jgraph.graph.GraphConstants;
import org.jgraph.graph.GraphLayoutCache;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import com.jgraph.JGraphEditor;
import com.jgraph.editor.JGraphEditorAction;
import com.jgraph.editor.JGraphEditorFactory;
import com.jgraph.editor.JGraphEditorKit;
import com.jgraph.editor.JGraphEditorModel;
import com.jgraph.editor.JGraphEditorPlugin;
import com.jgraph.editor.JGraphEditorResources;
import com.jgraph.editor.JGraphEditorSettings;
import com.jgraph.editor.JGraphEditorTool;
import com.jgraph.editor.factory.JGraphEditorComboBox;
import com.jgraph.editor.factory.JGraphEditorNavigator;
import com.jgraph.pad.JGraphpadDiagram;
import com.jgraph.pad.JGraphpadFile;
import com.jgraph.pad.JGraphpadLibrary;
import com.jgraph.pad.action.JGraphpadCellAction;
import com.jgraph.pad.action.JGraphpadEditAction;
import com.jgraph.pad.action.JGraphpadFileAction;
import com.jgraph.pad.action.JGraphpadFormatAction;
import com.jgraph.pad.action.JGraphpadHelpAction;
import com.jgraph.pad.action.JGraphpadViewAction;
import com.jgraph.pad.dialog.JGraphpadAuthenticator;
import com.jgraph.pad.factory.JGraphpadComboBox;
import com.jgraph.pad.factory.JGraphpadConsole;
import com.jgraph.pad.factory.JGraphpadLibraryPane;
import com.jgraph.pad.factory.JGraphpadOpenRecentMenu;
import com.jgraph.pad.factory.JGraphpadPane;
import com.jgraph.pad.factory.JGraphpadStatusBar;
import com.jgraph.pad.factory.JGraphpadWindowMenu;
import com.jgraph.pad.graph.JGraphpadBusinessObject;
import com.jgraph.pad.graph.JGraphpadEdgeView;
import com.jgraph.pad.graph.JGraphpadGraph;
import com.jgraph.pad.graph.JGraphpadGraphConstants;
import com.jgraph.pad.graph.JGraphpadGraphLayoutCache;
import com.jgraph.pad.graph.JGraphpadGraphModel;
import com.jgraph.pad.graph.JGraphpadHeavyweightRenderer;
import com.jgraph.pad.graph.JGraphpadMarqueeHandler;
import com.jgraph.pad.graph.JGraphpadPortView;
import com.jgraph.pad.graph.JGraphpadRichTextValue;
import com.jgraph.pad.graph.JGraphpadTransferHandler;
import com.jgraph.pad.graph.JGraphpadVertexRenderer;
import com.jgraph.pad.graph.JGraphpadVertexView;
import com.jgraph.pad.tool.JGraphpadEdgeTool;
import com.jgraph.pad.tool.JGraphpadVertexTool;
import com.jgraph.pad.util.JGraphpadFocusManager;
import com.jgraph.pad.util.JGraphpadImageIcon;
import com.jgraph.pad.util.JGraphpadParallelEdgeRouter;
import com.jgraph.pad.util.JGraphpadParallelSplineRouter;
import com.jgraph.pad.util.JGraphpadShadowBorder;

/**
* Class that constructs a new editor by creating a custom document model, kit
* and factory. The document model defines the persistence delegates for xml
* encoding, the kit and factory contain tools, actions and factory methods
* respectively. The class also constructs all plugins and provides the methods
* for creating the custom graph, graph cells and user objects to be used in
* this editor and to exit the application. For this purpose it provides two
* inner anonymous classes which override the respective methods, namely
* {@link JGraphEditor#exit(int)} and
* {@link JGraphEditorFactory#createGraph(GraphLayoutCache)} editor's exit
* method and the factory's createGraph method.
*/
public class JGraphpad {
  JGraphEditor editor;
  JGraphpad jgraphpad;
  /**
   * Global static product identifier.
   */
  public static final String VERSION_NUMBER = "6.0.4.1";

  /**
   * Holds the application title for dialogs.
   */
  public static String APPTITLE = "JGraphpad Pro";

  /**
   * Global static product identifier.
   */
  public static final String VERSION = APPTITLE + " (v" + VERSION_NUMBER
      + ")";

  /**
   * Specifies if libraries should reside inside documents. If this flag is true, then
   * the navigator and libraries are inside the internal frames for documents. The
   * libraries will be treated as part of their enclosing files. Default is false.
   */
  public static boolean INNER_LIBRARIES = false;

  /**
   * Defines the look and feel argument name.
   */
  public static String ARG_SYSTEMLOOKANDFEEL = "S";

  /**
   * Defines the look and feel argument name.
   */
  public static String ARG_JGOODIESLOOKANDFEEL = "J";

  /**
   * Defines the look and feel argument name.
   */
  public static String ARG_VERSION = "V";

  /**
   * Defines the path to the UI config file.
   */
  public static String PATH_UICONFIG = "/com/jgraph/pad/resources/ui.xml";

  /**
   * Defines the path to the splash image file.
   */
  public static String PATH_SPLASHIMAGE = "/com/jgraph/pad/images/splash.jpg";

  /**
   * Defines the path to the UI config file.
   */
  public static String PATH_DEFAULTLIBRARY = "/com/jgraph/pad/resources/default.xml";

  /**
   * Defines the path the the user settings file. This should also work with
   * URLs (untested).
   */
  public static String PATH_DEFAULTSETTINGS = "/com/jgraph/pad/resources/default.ini";

  /**
   * Defines the path the the user settings file. This should also work with
   * URLs (untested).
   */
  public static String PATH_USERSETTINGS;

  /**
   * Defines the filename for the settings file. Default is .jgraphpad.ini
   */
  public static String NAME_SETTINGSFILE = ".jgraphpad.ini";

  /**
   * Defines the name for the ui XML document in the editor settings.
   */
  public static String NAME_UICONFIG = "ui";

  /**
   * Defines the name for the user properties in the editor settings.
   */
  public static String NAME_USERSETTINGS = "user";

  /**
   * Defines the key used to identify the main window settings.
   */
  public static String KEY_MAINWINDOW = "mainWindow";

  /**
   * Defines the key used to identify the recent files settings.
   */
  public static String KEY_RECENTFILES = "recentFiles";

  /**
   * Defines the key used to identify the group prototype settings.
   */
  public static String KEY_GROUPPROTOTYPE = "groupPrototype";

  /**
   * Defines the key used to identify the vertex prototype settings.
   */
  public static String KEY_VERTEXPROTOTYPE = "vertexPrototype";

  /**
   * Defines the key used to identify the edge prototype settings.
   */
  public static String KEY_EDGEPROTOTYPE = "edgePrototype";

  /**
   * Defines the name for the selectTool.
   */
  public static final String NAME_SELECTTOOL = "selectTool";

  /**
   * Defines the name for the textTool.
   */
  public static final String NAME_TEXTTOOL = "textTool";

  /**
   * Defines the name for the vertexTool.
   */
  public static final String NAME_VERTEXTOOL = JGraphpadVertexTool.NAME_VERTEXTOOL;

  /**
   * Defines the name for the roundedTool.
   */
  public static final String NAME_ROUNDEDTOOL = "roundedTool";

  /**
   * Defines the name for the circleTool.
   */
  public static final String NAME_CIRCLETOOL = "circleTool";

  /**
   * Defines the name for the diamondTool.
   */
  public static final String NAME_DIAMONDTOOL = "diamondTool";

  /**
   * Defines the name for the triangleTool.
   */
  public static final String NAME_TRIANGLETOOL = "triangleTool";

  /**
   * Defines the name for the diamondTool.
   */
  public static final String NAME_CYLINDERTOOL = "cylinderTool";

  /**
   * Defines the name for the imageTool.
   */
  public static final String NAME_IMAGETOOL = "imageTool";

  /**
   * Defines the name for the imageTool.
   */
  public static final String NAME_HEAVYTOOL = "heavyTool";

  /**
   * Defines the name for the edgeTool.
   */
  public static final String NAME_EDGETOOL = JGraphpadEdgeTool.NAME_EDGETOOL;

  /**
   * Defines the name for the orthogonalEdgeTool.
   */
  public static final String NAME_ORTHOGONALEDGETOOL = "orthogonalEdgeTool";

  /**
   * Defines the name of the createShapeCombo factory method.
   */
  public static final String METHOD_CREATESHAPECOMBO = "createShapeCombo";

  /**
   * Defines the name of the createGradientCombo factory method.
   */
  public static final String METHOD_CREATEGRADIENTCOMBO = "createGradientCombo";

  /**
   * Defines the name of the createGradientCombo factory method.
   */
  public static final String METHOD_CREATELINECOLORCOMBO = "createLineColorCombo";

  /**
   * Adds resources bundles and prepares classes for xml encoding.
   *
   * @see JGraphEditorResources#addBundles
   * @see JGraphEditorModel#makeCellViewFieldsTransient(Class)
   * @see JGraphEditorModel#makeTransient
   */
  static {

   
    JGraphEditorResources.addBundles(new String[] {
        "com.jgraph.pad.resources.actions",
        "com.jgraph.pad.resources.menus",
        "com.jgraph.pad.resources.strings",
        "com.jgraph.pad.resources.tools" });

   
    JGraphEditorModel
        .makeCellViewFieldsTransient(JGraphpadVertexView.class);
    JGraphEditorModel.makeCellViewFieldsTransient(JGraphpadPortView.class);
    JGraphEditorModel.makeCellViewFieldsTransient(JGraphpadEdgeView.class);

   
    JGraphEditorModel.makeTransient(DefaultPort.class, "edges");
    JGraphEditorModel.makeTransient(DefaultEdge.class, "source");
    JGraphEditorModel.makeTransient(DefaultEdge.class, "target");
    JGraphEditorModel.makeTransient(GraphLayoutCache.class, "visibleSet");
    JGraphEditorModel.makeTransient(JGraphpadFile.class, "modified");
    JGraphEditorModel.makeTransient(JGraphpadFile.class, "userObject");
    JGraphEditorModel.makeTransient(JGraphpadFile.class, "filename");
    JGraphEditorModel.makeTransient(JGraphpadFile.class, "new");
    JGraphEditorModel.makeTransient(JGraphpadLibrary.class, "modified");
    JGraphEditorModel.makeTransient(JGraphpadLibrary.class, "userObject");
    JGraphEditorModel.makeTransient(JGraphpadLibrary.class, "filename");
    JGraphEditorModel.makeTransient(JGraphpadLibrary.class, "new");
    JGraphEditorModel.makeTransient(ConnectionSet.class, "edges");

   
    JGraphEditorComboBox.defaultBorders = new Border[] {
        BorderFactory.createRaisedBevelBorder(),
        BorderFactory.createLoweredBevelBorder(),
        BorderFactory.createEtchedBorder(),
        BorderFactory.createLineBorder(Color.black),
        JGraphpadShadowBorder.sharedInstance };

   
    try {
      Authenticator.setDefault(new JGraphpadAuthenticator());
    } catch (Exception e) {
     
    }
  }

  /**
   * The class names for the defaut plugins.
   */
  public String[] defaultPlugins = new String[] {
      "com.jgraph.l2fplugin.JGraphpadL2FPlugin",
      "com.jgraph.layoutplugin.JGraphpadLayoutPlugin",
      "com.jgraph.svgplugin.JGraphpadSVGPlugin",
      "com.jgraph.bshplugin.JGraphpadBshPlugin",
      "com.jgraph.jgxplugin.JGraphpadJGXPlugin",
      "com.jgraph.codecplugin.JGraphpadCodecPlugin",
      "com.jgraph.epsplugin.JGraphpadEPSPlugin",
      "com.jgraph.pdfplugin.JGraphpadPDFPlugin",
      "com.jgraph.browserplugin.JGraphpadBrowserPlugin",
      "com.jgraph.twikiplugin.JGraphpadTWikiPlugin" };

  /**
   * Defines the default port locations.
   */
  public Point2D[] defaultPortLocations = new Point2D[] { null };

  /**
   * Defines the default vertex bounds.
   */
  public Rectangle2D defaultBounds = new Rectangle2D.Double(0, 0, 20, 20);

  /**
   * Defines the default border color.
   */
  public Color defaultBorderColor = Color.BLACK;

  /**
   * Defines the default edge font.
   */
  public Font defaultEdgeFont = GraphConstants.DEFAULTFONT.deriveFont(10);

  /**
   * Defines the default end and begin decorations for edges.
   */
  public int defaultEndDecoration = GraphConstants.ARROW_TECHNICAL,
      defaultBeginDecoration = GraphConstants.ARROW_NONE;

  /**
   * Constructs JGraphpad as an applet.
   */
  public JGraphpad() {
          jgraphpad = this;

   
   
   
    try {
      PATH_USERSETTINGS = System.getProperty("user.home")
          + File.separator + NAME_SETTINGSFILE;
    } catch (SecurityException e) {
     
    }
  }

  /**
   * Hook for subclassers to implement the application exit method. This
   * implementation calls System.exit with the specified code.
   */
  protected void exit(int code) {
    System.exit(code);
  }

  /**
   * Constructs a new editor application and returns its main window. Shows a
   * splash window while the application is being constructed and returns the
   * main window in visible state. <br>
   * The parameters are obtained by parsing the arguments passed to the main
   * method as follows. For all arguments -A B the value B is stored in the
   * arguments under the A, for other arguments, eg. C D E the values C, D and
   * E and passed in as elements of the list.
   *
   * @param files
   *            The list of filenames passed to the Java command.
   * @param args
   *            The arguments to use for constructing the editor settings.
   * @return Returns a new application main window.
   */
  public Window createApplication(List files, Map args)
      throws ParserConfigurationException, SAXException, IOException {
          /*
   
    if (args != null && args.remove(ARG_SYSTEMLOOKANDFEEL) != null) {
      try {
        UIManager.setLookAndFeel(UIManager
            .getSystemLookAndFeelClassName());
      } catch (Exception e) {
        e.printStackTrace();
      }
    } else if (args != null && args.remove(ARG_JGOODIESLOOKANDFEEL) != null) {
      try {
        UIManager
            .setLookAndFeel("com.jgoodies.looks.plastic.Plastic3DLookAndFeel");
      } catch (Exception e) {
        e.printStackTrace();
      }
    }

   
   
   
    Window splashWindow = createSplashWindow();
    splashWindow.setVisible(true);

    boolean firstTime = (PATH_USERSETTINGS != null) ? !(new File(
        PATH_USERSETTINGS).exists()) : false;
          */

   
    editor = createEditor(args);

   
   
    //createPlugins(editor);

   
   
    Window mainWindow = createMainWindow(editor,
        JGraphpadPane.FactoryMethod.NAME);

   

   
   
    editor.getSettings().putObject(KEY_MAINWINDOW, mainWindow);
    editor.getSettings().restoreWindow(NAME_USERSETTINGS, KEY_MAINWINDOW);

                /*
   
   
   
    editor.getSettings().addShutdownHook(
        new JGraphEditorSettings.ShutdownHook() {

         
         
          public void shutdown() {
            editor.getSettings().storeWindow(NAME_USERSETTINGS,
                KEY_MAINWINDOW);
          }
        });
                */
   
   
   
   
   
   
   
    JDesktopPane desktopPane = (JDesktopPane) editor.getSettings()
        .getObject(JGraphpadPane.KEY_DESKTOPPANE);
    JGraphpadWindowMenu windowMenu = (JGraphpadWindowMenu) editor
        .getSettings().getObject(JGraphpadWindowMenu.KEY_WINDOWMENU);
   
    if (desktopPane != null && windowMenu != null) {
      windowMenu.setDesktopPane(desktopPane);
    }

   
   
   
    try {
      JGraphpadLibrary library = (JGraphpadLibrary) editor.getModel()
          .addFile(PATH_DEFAULTLIBRARY);
      if (library != null) {
        editor.getModel().setFilename(library,
            JGraphEditorResources.getString("DefaultLibrary"));
        library.setNew(true);
      }
    } catch (Exception e) {
     
    }

   
    //splashWindow.dispose();

   
   
   
   
    //mainWindow.setVisible(true);
    editor.getSettings().restoreSplitPane(NAME_USERSETTINGS,
        JGraphpadPane.KEY_NAVIGATORSPLIT);
    editor.getSettings().restoreSplitPane(NAME_USERSETTINGS,
        JGraphpadPane.KEY_LEFTSPLIT);
    editor.getSettings().restoreSplitPane(NAME_USERSETTINGS,
        JGraphpadPane.KEY_RIGHTSPLIT);

                /*
   

   
    if (files != null && !files.isEmpty()) {
      JGraphEditorModel model = editor.getModel();
      Iterator it = files.iterator();
      while (it.hasNext()) {
        String filename = String.valueOf(it.next());
        try {
          editor.getModel().addFile(filename);
        } catch (Exception e) {
          JGraphpadFile file = new JGraphpadFile(filename);
          JGraphpadDiagram newDiagram = new JGraphpadDiagram(
              JGraphEditorResources.getString("Diagram") + "1");
          model.addRoot(file);
          model.addChild(newDiagram, file);
        }
      }
    }
                */
                /*
   
    else if (firstTime)
      editor.getKit().getAction(JGraphpadFileAction.NAME_NEWDOCUMENT)
          .actionPerformed(null);
                */
    return mainWindow;
  }

  /**
   * Helper method that invokes the specified factory method and configures
   * the main window by setting its bounds and installing window listeners.
   * This implementation invokes the exit action in the editor kit if the
   * window is closed by the user.
   *
   * @param editor
   *            The editor to create the main window for.
   * @param factoryMethod
   *            The name of the factory method to invoke.
   * @return Returns a new main window for the specified editor.
   *
   * @see JGraphEditorFactory#executeMethod(String, Node)
   * @see JGraphEditorKit#getAction(String)
   * @see #center(Window)
   */
  protected Window createMainWindow(final JGraphEditor editor,
      String factoryMethod) {

   
   
    Window wnd = (Window) editor.getFactory().executeMethod(
        factoryMethod,
        editor.getSettings().getDocument(NAME_UICONFIG)
            .getDocumentElement());

   
   
    wnd.setSize(800, 640);
    center(wnd);

   
   
    if (wnd instanceof JFrame)
      ((JFrame) wnd).setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    wnd.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        editor.getKit().getAction("exit").actionPerformed(null);
      }
    });
    return wnd;
  }

  /**
   * Constructs a splash window to be displayed during the construction of the
   * application.
   *
   * @return Returns a reference to the displaying splash window.
   */
  protected Window createSplashWindow() {
    JWindow splashWindow = new JWindow();

   
   
   
    JLabel image = new JLabel(JGraphEditorResources
        .getImage(PATH_SPLASHIMAGE));
    image.setBorder(BorderFactory.createRaisedBevelBorder());
    splashWindow.getContentPane().add(image, BorderLayout.CENTER);
    JLabel label = new JLabel("v" + VERSION_NUMBER);
    image.setLayout(null);
    image.add(label);
    label.setFont(label.getFont().deriveFont(Font.BOLD));
    label.setForeground(Color.GRAY);
    label.setBounds(202, 118, 200, 30);

   
    splashWindow.pack();
    center(splashWindow);

    return splashWindow;
  }

  /**
   * Constructs a new {@link JGraphEditor} using the specified settings and
   * document model model and calls
   * {@link #configureEditor(JGraphEditor, Map)} on the new instance. The
   * returned instance has an overridden exit hook which disposes the main
   * window and terminates the VM in the proper way for how the application
   * was started.
   *
   * @param args
   *            The arguments passed to createApplication.
   *
   * @return Returns a new configured editor.
   * @throws IOException
   * @throws SAXException
   * @throws ParserConfigurationException
   */
  protected JGraphEditor createEditor(Map args)
      throws ParserConfigurationException, SAXException, IOException {

          JGraphEditor editor = new JGraphEditor();
          configureEditor(editor, args);
          return editor;
  }

  /**
   * Hook for subclassers to configure new editors. This implementation
   * configures the editor kit and -factory and invokes
   * {@link #createPlugins(JGraphEditor)}for the editor.
   *
   * @param editor
   *            The editor to be configured.
   * @param args
   *            The arguments passed to createApplication.
   * @throws IOException
   * @throws SAXException
   * @throws ParserConfigurationException
   *
   * @see #createKit(JGraphEditor)
   * @see #createFactory(JGraphEditor)
   */
  protected void configureEditor(JGraphEditor editor, Map args)
      throws ParserConfigurationException, SAXException, IOException {
    editor.setSettings(createSettings(args));
    editor.setModel(createModel());
    editor.setKit(createKit(editor));
    editor.setFactory(createFactory(editor));
  }

  /**
   * Constructs the editor settings. This implementation constructs a new
   * instance of JGraphEditorSettings using args as the initial object map and
   * passes it to the {@link #configureSettings(JGraphEditorSettings)}method.
   *
   * @param args
   *            The arguments passed to the command line.
   * @return Returns a configured editor settings object.
   */
  protected JGraphEditorSettings createSettings(Map args)
      throws ParserConfigurationException, SAXException, IOException {
    JGraphEditorSettings settings = new JGraphEditorSettings(args);
    configureSettings(settings);
    return settings;
  }

  /**
   * Hook for subclassers to configure new editor settings. This
   * implementation adds the ui configuration ({@link #PATH_UICONFIG}) to
   * the
   *
   * {@link #NAME_UICONFIG}and user settings ({@link #PATH_USERSETTINGS})
   * to the {@link #NAME_USERSETTINGS}.
   *
   * @param settings
   *            The editor settings to be configured.
   * @throws IOException
   * @throws SAXException
   * @throws ParserConfigurationException
   * @throws FileNotFoundException
   * @throws MalformedURLException
   *
   * @see JGraphEditorSettings#parse(InputStream)
   * @see JGraphEditorSettings#add(String, InputStream)
   */
  protected void configureSettings(JGraphEditorSettings settings)
      throws MalformedURLException, FileNotFoundException,
      ParserConfigurationException, SAXException, IOException {

   
   
   
    settings.add(NAME_UICONFIG, JGraphEditorSettings
        .parse(JGraphEditorResources.getInputStream(PATH_UICONFIG)));

   
   
   
    if (PATH_USERSETTINGS != null && new File(PATH_USERSETTINGS).canRead())
      settings.add(NAME_USERSETTINGS, JGraphEditorResources
          .getInputStream(PATH_USERSETTINGS));
    else
      settings.add(NAME_USERSETTINGS, JGraphEditorResources
          .getInputStream(PATH_DEFAULTSETTINGS));

   
   
   
   
    final Properties userSettings = settings
        .getProperties(JGraphpad.NAME_USERSETTINGS);
    settings.addShutdownHook(new JGraphEditorSettings.ShutdownHook() {
      public void shutdown() {
        if (userSettings != null && PATH_USERSETTINGS != null) {
          try {
            OutputStream out = JGraphEditorResources
                .getOutputStream(JGraphpad.PATH_USERSETTINGS);
            userSettings.store(out, "");
            out.flush();
            out.close();

           
            if (JGraphEditor.isURL(JGraphpad.PATH_USERSETTINGS)) {
              URL url = new URL(JGraphpad.PATH_USERSETTINGS);
              JGraphpadFileAction.postPlain(url, url.getFile(),
                  out);
            }
          } catch (Exception e) {
           
          }
        }
      }
    });

   
   
   
    settings.putObject(KEY_GROUPPROTOTYPE, createGroup());
    settings.putObject(KEY_VERTEXPROTOTYPE, createVertex());
    settings.putObject(KEY_EDGEPROTOTYPE, createEdge());
  }

  /**
   * Constructs a document model for new editors. This implementation
   * constructs a new instance of {@link JGraphEditorModel}and passes it to
   * the {@link #configureModel(JGraphEditorModel)}method.
   *
   * @return Returns a configured document model for an editor.
   */
  protected JGraphEditorModel createModel() {
    JGraphEditorModel model = new JGraphEditorModel();
    configureModel(model);
    return model;
  }

  /**
   * Hook for subclassers to configure new document models. This
   * implementation adds persistence delegates for the following classes:
   * {@link JGraphpadDiagram},{@link JGraphpadGraphModel},
   * com.jgraph.graph.ConnectionSet, {@link JGraphpadGraphLayoutCache},
   * com.jgraph.graph.DefaultGraphCell, com.jgraph.graph.DefaultEdge,
   * com.jgraph.graph.DefaultPort,{@link JGraphpadBusinessObject},
   * {@link JGraphpadRichTextValue}and {@link JGraphpadShadowBorder}.<br>
   * <b>JGraphpadDiagram </b> <br>
   * Constructs a persistence delegate for the diagram class. This uses the
   * fact that all information is stored in the model, not the layout cache by
   * ignoring the layout cache and accessing the model stored in the layout
   * cache directly through the model bean property. Note: To allow this kind
   * of encoding the diagram class offers a special constructor that takes a
   * model and constructs a new graph layout cache for it. <br>
   * <b>JGraphpadGraphModel </b> <br>
   * To encode graph models we do not want the files to contain redundant
   * connectivity information in the ports.edges and edges.source and target
   * fields, so we add a method to the graph model that returns a connection
   * set which describes the connections without redundancy. (Note: In the
   * static initializer of this class we make sure that the edges, source and
   * target of the respective classes or not encoded.) <br>
   * <b>ConnectionSet </b> <br>
   * The complete information of a connection set is stored in the actual
   * connections, thus we only store the connections and use special
   * constructor to restore the state of the complete object when de- coding.
   * (Note: For connection sets this will update the edges field.) <br>
   * <b>JGraphpadGraphLayoutCache </b> <br>
   * The graph layout cache is encoded by encoding the various member fields,
   * using a special constructor to restore the state of the layout cache upon
   * decoding. Note that this is currently not used. <br>
   * <b>DefaultGraphCell, DefaultEdge, DefaultPort </b> <br>
   * Makes sure the cells are only encoded along with their user objects, the
   * attributes, connections and tree-structure is stored in other objects and
   * does not need to be encoded here. <br>
   * <b>JGraphpadBusinessObject, JGraphpadRichTextData </b> <br>
   * Allows to encode custom business objects used in JGraphpad. Since this
   * object implements the bean interface we do only require a default
   * persistence delegates with no special constructor calls to decode the
   * object. Same holds for the rich text data object, which is a special
   * value that can hold text formatting information. <br>
   * <b>JGraphShadowBorder </b> <br>
   * Since the shadow border is a singleton we must tell the decoder which
   * method to use in order to find the shared instance of the class.
   *
   * @param model
   *            The document model to be configured.
   */
  protected void configureModel(JGraphEditorModel model) {
    model.addPersistenceDelegate(JGraphpadDiagram.class,
        new DefaultPersistenceDelegate(new String[] { "name",
            "graphLayoutCache", "properties" }));
    model.addPersistenceDelegate(JGraphpadLibrary.class,
        new DefaultPersistenceDelegate(new String[] { "filename",
            "graphLayoutCache" }));
    model.addPersistenceDelegate(JGraphpadGraphModel.class,
        new DefaultPersistenceDelegate(new String[] { "roots",
            "attributes", "connectionSet" }));
    model.addPersistenceDelegate(ConnectionSet.class,
        new DefaultPersistenceDelegate(new String[] { "connections" }));

    model.addPersistenceDelegate(JGraphpadGraphLayoutCache.class,
        new DefaultPersistenceDelegate(new String[] { "model",
            "visibleSet", "partial" }));

    model.addPersistenceDelegate(DefaultGraphCell.class,
        new DefaultPersistenceDelegate(new String[] { "userObject" }));
    model.addPersistenceDelegate(DefaultEdge.class,
        new DefaultPersistenceDelegate(new String[] { "userObject" }));
    model.addPersistenceDelegate(DefaultPort.class,
        new DefaultPersistenceDelegate(new String[] { "userObject" }));

    model.addPersistenceDelegate(JGraphpadBusinessObject.class,
        new DefaultPersistenceDelegate());
    model.addPersistenceDelegate(JGraphpadRichTextValue.class,
        new DefaultPersistenceDelegate());

   
    model.addPersistenceDelegate(JGraphpadShadowBorder.class,
        new PersistenceDelegate() {
          protected Expression instantiate(Object oldInstance,
              Encoder out) {
            return new Expression(oldInstance,
                JGraphpadShadowBorder.class,
                "getSharedInstance", null);
          }
        });

   
    model.addPersistenceDelegate(JGraphpadParallelEdgeRouter.class,
        new PersistenceDelegate() {
          protected Expression instantiate(Object oldInstance,
              Encoder out) {
            return new Expression(oldInstance,
                JGraphpadGraphConstants.class,
                "getParallelEdgeRouting", null);
          }
        });
    model.addPersistenceDelegate(JGraphpadParallelSplineRouter.class,
        new PersistenceDelegate() {
          protected Expression instantiate(Object oldInstance,
              Encoder out) {
            return new Expression(oldInstance,
                JGraphpadGraphConstants.class,
                "getParallelSplineRouting", null);
          }
        });
  }

  /**
   * Constructs a default kit for new editors. This implementation constructs
   * a new instance of {@link JGraphEditorKit}and passes it to
   * {@link #configureKit(JGraphEditor, JGraphEditorKit)}.
   *
   * @param editor
   *            The editor for which to create an editor kit.
   * @return Returns a configured editor kit for the specified editor.
   */
  protected JGraphEditorKit createKit(JGraphEditor editor) {
    JGraphEditorKit kit = new JGraphEditorKit();
    configureKit(editor, kit);
    return kit;
  }

  /**
   * Boilerplate method for configuring new editor kits. This implementation
   * calls {@link #addActions(JGraphEditor, JGraphEditorKit)},
   * {@link #addTools(JGraphEditor, JGraphEditorKit)}and registers the kit
   * with the listeners required to update the state. This method is called
   * from {@link #createKit(JGraphEditor)}.
   *
   * @param editor
   *            The editor for which to configure the editor kit.
   * @param kit
   *            The new editor kit to be configured.
   */
  protected void configureKit(JGraphEditor editor, final JGraphEditorKit kit) {
    addActions(editor, kit);
    addTools(editor, kit);

   
   
    final GraphSelectionListener selectionListener = new GraphSelectionListener() {

      /**
       * Updates the actions in the factory kit when the selection of a
       * library pane (ie of its backing graph) changes.
       */
      public void valueChanged(GraphSelectionEvent e) {
        kit.update();
      }

    };

    KeyboardFocusManager focusManager = KeyboardFocusManager
        .getCurrentKeyboardFocusManager();
    focusManager.addPropertyChangeListener(new PropertyChangeListener() {

      /*
       * (non-Javadoc)
       */
      public void propertyChange(PropertyChangeEvent e) {
        if (e.getPropertyName().equals("permanentFocusOwner"))
          kit.update();

       
       
        if (e.getOldValue() instanceof JGraphpadLibraryPane)
          ((JGraphpadLibraryPane) e.getOldValue()).getBackingGraph()
              .getSelectionModel().removeGraphSelectionListener(
                  selectionListener);
        if (e.getNewValue() instanceof JGraphpadLibraryPane)
          ((JGraphpadLibraryPane) e.getNewValue()).getBackingGraph()
              .getSelectionModel().addGraphSelectionListener(
                  selectionListener);
      }
    });

    JGraphpadFocusManager.getCurrentGraphFocusManager()
        .addPropertyChangeListener(new PropertyChangeListener() {

          /*
           * (non-Javadoc)
           */
          public void propertyChange(PropertyChangeEvent e) {
            kit.update();
          }
        });
    kit.update();
  }

  //
 
  //

  /**
   * Adds the action bundles for {@link JGraphpadEditAction},
   * {@link JGraphpadFileAction},{@link JGraphpadViewAction},
   * {@link JGraphpadFormatAction}and {@link JGraphpadCellAction}. Uses the
   * createVertex and createEdge method to construct prototypes for
   * {@link JGraphpadCellAction#NAME_GROUP}and
   * {@link JGraphpadCellAction#NAME_CONNECT}. This method is called from
   * configureEditorKit.
   *
   * @param editor
   *            The editor for which to create the actions.
   * @param kit
   *            The editor kit to add the actions to.
   *
   * @see #configureKit(JGraphEditor, JGraphEditorKit)
   * @see JGraphEditorKit#addBundle(JGraphEditorAction.Bundle)
   * @see #createVertex()
   * @see #createEdge()
   */
  protected void addActions(JGraphEditor editor, JGraphEditorKit kit) {

   
   
   
    kit.addBundle(new JGraphpadEditAction.AllActions());
    kit.addBundle(new JGraphpadViewAction.AllActions());
    kit.addBundle(new JGraphpadFormatAction.AllActions());
    kit.addBundle(new JGraphpadHelpAction.AllActions());

   
    kit.addBundle(new JGraphpadFileAction.AllActions(editor));
    kit.addBundle(new JGraphpadCellAction.AllActions(editor));
  }

  //
 
  //

  /**
   * Adds the following tools to <code>kit</code>:{@link #NAME_SELECTTOOL},
   * {@link #NAME_VERTEXTOOL},{@link #NAME_ROUNDEDTOOL},
   * {@link #NAME_CIRCLETOOL},{@link #NAME_DIAMONDTOOL},{@link #NAME_TRIANGLETOOL},
   * {@link #NAME_IMAGETOOL},{@link #NAME_HEAVYTOOL},{@link #NAME_EDGETOOL}and
   * {@link #NAME_ORTHOGONALEDGETOOL}. This method is called from
   * configureEditorKit.
   *
   * @param editor
   *            The editor for which to create the tools.
   * @param kit
   *            The editor kit to add the tools to.
   *
   * @see #configureKit(JGraphEditor, JGraphEditorKit)
   * @see JGraphEditorKit#addTool(JGraphEditorTool)
   * @see #createVertexTool(String, Object, int, ImageIcon)
   * @see #createEdgeTool(String, String, Edge.Routing)
   */
  protected void addTools(JGraphEditor editor, JGraphEditorKit kit) {
    kit.addTool(new JGraphEditorTool(NAME_SELECTTOOL, false));
    JGraphpadVertexTool tool = createVertexTool(NAME_TEXTTOOL,
        new JGraphpadRichTextValue(""), -1, null, true);
    tool.setPreviewEnabled(false);
    kit.addTool(tool);
    kit.addTool(createVertexTool(NAME_VERTEXTOOL,
        new JGraphpadRichTextValue(""),
        JGraphpadVertexRenderer.SHAPE_RECTANGLE, null));
    JComponent c = new JGraphpadHeavyweightRenderer();
    kit.addTool(createVertexTool(NAME_HEAVYTOOL, c,
        JGraphpadVertexRenderer.SHAPE_RECTANGLE, null));
    kit.addTool(createVertexTool(NAME_ROUNDEDTOOL,
        new JGraphpadRichTextValue(""),
        JGraphpadVertexRenderer.SHAPE_ROUNDED, null));
    kit.addTool(createVertexTool(NAME_CIRCLETOOL,
        new JGraphpadRichTextValue(""),
        JGraphpadVertexRenderer.SHAPE_CIRCLE, null));
    kit.addTool(createVertexTool(NAME_DIAMONDTOOL,
        new JGraphpadRichTextValue(""),
        JGraphpadVertexRenderer.SHAPE_DIAMOND, null));
    kit.addTool(createVertexTool(NAME_TRIANGLETOOL,
        new JGraphpadRichTextValue(""),
        JGraphpadVertexRenderer.SHAPE_TRIANGLE, null));
    kit.addTool(createVertexTool(NAME_CYLINDERTOOL,
        new JGraphpadRichTextValue(""),
        JGraphpadVertexRenderer.SHAPE_CYLINDER, null));
   
    JGraphpadImageIcon icon = new JGraphpadImageIcon(
        "/com/jgraph/pad/images/noimage.gif");
    kit.addTool(createVertexTool(NAME_IMAGETOOL, "",
        JGraphpadVertexRenderer.SHAPE_RECTANGLE, icon));
    kit.addTool(createEdgeTool(NAME_EDGETOOL, new JGraphpadRichTextValue(""), null));
    kit.addTool(createEdgeTool(NAME_ORTHOGONALEDGETOOL, new JGraphpadRichTextValue(""),
        GraphConstants.ROUTING_SIMPLE));
  }

  /**
   * Invokes
   * {@link #createVertexTool(String, Object, int, ImageIcon, boolean)} with
   * post editing set to false.
   */
  protected JGraphpadVertexTool createVertexTool(String name,
      Object defaultValue, int shape, ImageIcon icon) {
    return createVertexTool(name, defaultValue, shape, icon, false);
  }

  /**
   * Helper method to create and return a new vertex tool. This uses the
   * createVertexUserObject or creates a new {@link JGraphpadRichTextValue}
   * object based on <code>isRichText</code> as the user object, which it
   * passes to createVertex to create the graph cell. The method sets the
   * shape on the created graph cell, and returns a new JGraphpadVertexTool
   * with the specified name.
   *
   * @param name
   *            The name of the tool to be created.
   * @param defaultValue
   *            The defaultValue for the vertices that this tool creates.
   * @param shape
   *            The shape for the vertices that this tool creates. Use -1 for
   *            no border.
   * @param icon
   *            The icon for the vertices that this tool creates.
   * @param postEdit
   *            If in-place editing should be triggered after inserting the
   *            cell.
   * @return Returns a new vertex tool.
   *
   * @see JGraphpadRichTextValue
   * @see #createVertexUserObject(Object)
   * @see #createVertex(Object)
   * @see JGraphpadGraphConstants#setVertexShape(Map, int)
   * @see JGraphpadVertexTool
   */
  protected JGraphpadVertexTool createVertexTool(String name, Object defaultValue,
  int shape, ImageIcon icon, boolean postEdit) {
    JGraphpadVertexTool vertextTool = null

    Object userObject = createVertexUserObject(defaultValue);
    GraphCell vertex = createVertex(userObject);
    if (shape >= 0) {
      JGraphpadGraphConstants.setVertexShape(vertex.getAttributes(),
                                             shape);
    } else {
      vertex.getAttributes().remove(GraphConstants.BORDERCOLOR);
      vertex.getAttributes().remove(GraphConstants.BORDER);
    }
    if (icon != null) {
      GraphConstants.setIcon(vertex.getAttributes(), icon);
    }
    if (postEdit) {
      vertextTool = new JGraphpadVertexTool(name, vertex) {
        protected void execute(JGraph graph, Object cell) {
          super.execute(graph, cell);
          graph.startEditingAtCell(cell);
        }
      };
    } else {
      vertextTool = new JGraphpadVertexTool(name, vertex);
    }
    Dimension dimension =
      new Dimension(WorkflowProperties.cellHeight, WorkflowProperties.cellWidth);
    vertextTool.setSingleClickSize(dimension);
    return vertextTool; 
  }

  /**
   * Helper method to create and return a new edge tool. This passes the
   * return value of createEdgeUserObject to createEdge to create the graph
   * cell. The method sets the routing on the created graph cell if it is not
   * <code>null</code>, and returns a new JGraphpadEdgeTool with the
   * specified name.
   *
   * @param name
   *            The name of the tool to be created.
   * @param defaultValue
   *            The defaultValue for the edges that this tool creates.
   * @param routing
   *            The routing for the edges that this tool creates.
   * @return Returns a new edge tool.
   *
   * @see #createEdgeUserObject(Object)
   * @see #createEdge(Object)
   * @see GraphConstants#setRouting(Map, Edge.Routing)
   * @see JGraphpadEdgeTool
   */
  protected JGraphpadEdgeTool createEdgeTool(String name,
      Object defaultValue, Edge.Routing routing) {
    DefaultEdge edge = createEdge(createEdgeUserObject(defaultValue));
    if (routing != null)
      GraphConstants.setRouting(edge.getAttributes(), routing);
    return new JGraphpadEdgeTool(name, edge);
  }

  /**
   * Constructs a default factory for new editors. This implementation
   * constructs a new instance of JGraphEditorFactory and overrides
   * {@link JGraphEditorFactory#createGraph(GraphLayoutCache)} to call
   * {@link #createGraph(JGraphEditor, GraphLayoutCache)} and configures the
   * factory using
   * {@link #configureFactory(JGraphEditor, JGraphEditorFactory)}.
   *
   * @param editor
   *            The editor for which to create an editor factory.
   * @return Returns a configured editor factory for the specified editor.
   */
  protected JGraphEditorFactory createFactory(final JGraphEditor editor) {
    JGraphEditorFactory factory = new JGraphEditorFactoryEx(editor.getKit()) {
      public JGraph createGraph(GraphLayoutCache graphLayoutCache) {
        return jgraphpad.createGraph(editor, graphLayoutCache);
      }
    };
    configureFactory(editor, factory);
    return factory;
  }

  /**
   * Hook for subclassers to configure new editor factories. This
   * implementation adds various following factory methods.
   *
   * @param editor
   *            The editor to create the factory methods for.
   * @param factory
   *            The factory to be configured.
   */
  protected void configureFactory(JGraphEditor editor,
      JGraphEditorFactory factory) {

   
    factory.addMethod(new JGraphEditorNavigator.FactoryMethod(editor));
    factory.addMethod(new JGraphEditorComboBox.BorderComboFactoryMethod());
    factory
        .addMethod(new JGraphEditorComboBox.LineDecorationComboFactoryMethod());
    factory
        .addMethod(new JGraphEditorComboBox.LineWidthComboFactoryMethod());
    factory
        .addMethod(new JGraphEditorComboBox.DashPatternComboFactoryMethod());

   
    factory.addMethod(new JGraphpadPane.FactoryMethod(editor));
    factory.addMethod(new JGraphpadPane.LeftTabFactoryMethod(editor));
    factory.addMethod(new JGraphpadPane.BottomTabFactoryMethod(editor));
    factory
        .addMethod(new JGraphpadComboBox.VertexShapeComboFactoryMethod());
    factory.addMethod(new JGraphpadComboBox.ColorComboFactoryMethod());
    factory.addMethod(new JGraphpadComboBox.ColorComboFactoryMethod(
        METHOD_CREATELINECOLORCOMBO, JGraphpadComboBox.TYPE_LINECOLOR));
    factory.addMethod(new JGraphpadComboBox.ColorComboFactoryMethod(
        METHOD_CREATEGRADIENTCOMBO, JGraphpadComboBox.TYPE_GRADIENT));
    factory.addMethod(new JGraphpadLibraryPane.FactoryMethod(editor));
    factory.addMethod(new JGraphpadWindowMenu.FactoryMethod(editor));
    factory.addMethod(new JGraphpadOpenRecentMenu(editor));
    factory.addMethod(new JGraphpadConsole.FactoryMethod());
    factory.addMethod(new JGraphpadStatusBar.FactoryMethod(editor));
  }

  /**
   * Hook for subclassers to create plugins for a new editor. This
   * implementation creates the {@link #defaultPlugins}. This method is
   * called from {@link #configureEditor(JGraphEditor, Map)}.
   *
   * @param editor
   *            The editor for which to create the plugins.
   */
  protected void createPlugins(JGraphEditor editor) {
    if (defaultPlugins != null) {
      for (int i = 0; i < defaultPlugins.length; i++) {
        try {
          System.out.print("Loading " + defaultPlugins[i] + "... ");
          JGraphEditorPlugin plugin = (JGraphEditorPlugin) Class
              .forName(defaultPlugins[i]).newInstance();
          plugin.initialize(editor, null);
          System.out.println("Done");
        } catch (Throwable e) {
          System.out.println("Not Available");
        }
      }
    }
  }

  //
 
  //

  /**
   * Hook for subclassers to provide a custom graph for the user interface.
   * This method is invoked by the default custom factory returned by the
   * createEditorFactory method. It invokes
   * {@link #configureGraph(JGraphEditor, JGraph)} to configure the new graph
   * instance.
   *
   * @see #createFactory(JGraphEditor)
   */
  protected JGraph createGraph(JGraphEditor editor,
      GraphLayoutCache graphLayoutCache) {
    JGraph graph = new JGraphpadGraph(graphLayoutCache);
    configureGraph(editor, graph);
    return graph;
  }

  /**
   * Hook for subclassers to configure a new graph. This implementation adds a
   * {@link JGraphpadTransferHandler} and {@link JGraphpadMarqueeHandler} to
   * the instance. (Note: {@link #createVertex()} is used to create the
   * prototype cell for the transfer handler.)
   *
   * @param graph
   *            The graph to be configured
   */
  protected void configureGraph(JGraphEditor editor, JGraph graph) {
    ToolTipManager.sharedInstance().registerComponent(graph);
    graph.setTransferHandler(new JGraphpadTransferHandler(createVertex()));
    graph.setMarqueeHandler(new JGraphpadMarqueeHandler(editor));
    graph.setInvokesStopCellEditing(true);
    graph.setJumpToDefaultPort(true);
    graph.setMoveOutOfGroups(true);
    graph.setMoveIntoGroups(true);
    graph.setDragEnabled(true);
    graph.setCloneable(true);
    graph.setOpaque(false);
  }

  //
 
  //

  /**
   * Hook for subclassers to construct vertices with default user objects.
   * This implementation invokes {@link #createVertexUserObject(Object)}and
   * passes the return value to {@link #createVertex(Object)}.
   *
   * @return Returns a new vertex with a default user object.
   */
  public GraphCell createVertex() {
    return createVertex(createVertexUserObject(null));
  }

  /**
   * Returns a new DefaultGraphCell containing the specified user object. This
   * implementation uses {@link #createAttributeMap()}to create the map that
   * holds the attributes for the new vertex, and
   * {@link #configureVertex(GraphCell)}to configure the vertex.
   *
   * @param userObj
   *            The user object that the vertex should contain.
   * @return Returns a new vertex.
   */
  public GraphCell createVertex(Object userObj) {
    DefaultGraphCell vertex = new DefaultGraphCell(userObj,
        createAttributeMap());
    configureVertex(vertex);
    return vertex;
  }

  /**
   * Hook for subclassers to configure the specified vertex. This
   * implementation sets the {@link #defaultBorderColor}and adds ports if the
   * vertex implements the {@link MutableTreeNode}interface.
   *
   * @param vertex
   *            The vertex to be configured.
   *
   * @see #addPorts(MutableTreeNode, Point2D[])
   */
  protected void configureVertex(GraphCell vertex) {
    AttributeMap attributes = vertex.getAttributes();
    if (defaultBorderColor != null) {
      GraphConstants.setOpaque(attributes, false);
      GraphConstants.setBorderColor(attributes, defaultBorderColor);
      GraphConstants.setGroupOpaque(attributes, false);
      JGraphpadGraphConstants.setGroupResize(attributes, true);
      JGraphpadGraphConstants.setInset(attributes, 4);
    }
    if (vertex instanceof MutableTreeNode)
      addPorts((MutableTreeNode) vertex, defaultPortLocations);
  }

  /**
   * Hook for subclassers to construct groups with default user objects. This
   * implementation invokes {@link #createVertexUserObject(Object)}and passes
   * the return value to {@link #createGroup(Object)}.
   *
   * @return Returns a new group with a default user object.
   */
  public GraphCell createGroup() {
    return createVertex(createVertexUserObject(null));
  }

  /**
   * Returns a new DefaultGraphCell containing the specified user object. This
   * implementation uses {@link #createAttributeMap()}to create the map that
   * holds the attributes for the new vertex, and
   * {@link #configureVertex(GraphCell)}to configure the vertex.
   *
   * @param userObj
   *            The user object that the group should contain.
   * @return Returns a new group.
   */
  public GraphCell createGroup(Object userObj) {
    DefaultGraphCell vertex = new DefaultGraphCell(userObj,
        createAttributeMap());
    configureVertex(vertex);
    return vertex;
  }

  /**
   * Adds ports to <code>parent</code> using <code>offsets</code> as the
   * port relative offsets. The method uses
   * {@link #createPortUserObject(Object)},
   * {@link #createPort(MutableTreeNode, Object)}and
   * {@link #configurePort(GraphCell, Point2D)}to create the ports and their
   * user objects, configure them and add them to the parent.
   *
   * @param parent
   *            The parent to add the ports to.
   * @param offsets
   *            The points defining the port locations.
   */
  protected void addPorts(MutableTreeNode parent, Point2D[] offsets) {
    for (int i = 0; i < offsets.length; i++) {
      GraphCell port = createPort(parent, createPortUserObject(null));
      configurePort(port, offsets[i]);
    }
  }

  /**
   * Creates a port containing the specified user object and adds it to
   * <code>parent</code>.
   *
   * @param userObject
   *            The user object that the port should contain.
   * @return Returns a new port.
   */
  public GraphCell createPort(MutableTreeNode parent, Object userObject) {
    DefaultGraphCell port = new DefaultPort(userObject);
    parent.insert(port, parent.getChildCount());
    port.setParent(parent);
    return port;
  }

  /**
   * Hook for subclassers to configure the specified port using the
   * <code>offset</code> as the relative location.
   *
   * @param port
   *            The port to be configured.
   * @param offset
   *            The relative offset of the port.
   */
  public void configurePort(GraphCell port, Point2D offset) {
    AttributeMap map = port.getAttributes();
    if (offset != null)
      GraphConstants.setOffset(map, offset);
  }

  /**
   * Hook for subclassers to construct edgges with default user objects. This
   * implementation invokes {@link #createEdgeUserObject(Object)}and passes
   * the return value to {@link #createEdge(Object)}.
   *
   * @return Returns a new edge with a default user object.
   */
  public DefaultEdge createEdge() {
    return createEdge(createEdgeUserObject(null));
  }

  /**
   * Returns a new DefaultEdge containing the specified user object. This
   * implementation uses {@link #createAttributeMap()}to create the map that
   * holds the attributes for the new edge and
   * {@link #configureEdge(GraphCell)}to configure the edge.
   *
   * @param userObj
   *            The user object that the edge should contain.
   * @return Returns a new edge.
   */
  public DefaultEdge createEdge(Object userObj) {
    DefaultEdge edge = new DefaultEdge(userObj, createAttributeMap());
    configureEdge(edge);
    return edge;
  }

  /**
   * Hook for subclassers to configure the specified edge. This implementation
   * sets the {@link #defaultEdgeFont},{@link #defaultEndDecoration}and
   * {@link #defaultBeginDecoration}.
   *
   * @param edge
   *            The edge to be configured.
   */
  protected void configureEdge(GraphCell edge) {
    AttributeMap attributes = edge.getAttributes();
    if (defaultEdgeFont != null)
      GraphConstants.setFont(attributes, defaultEdgeFont);
    if (defaultEndDecoration != GraphConstants.ARROW_NONE)
      GraphConstants.setLineEnd(attributes, defaultEndDecoration);
    if (defaultBeginDecoration != GraphConstants.ARROW_NONE)
      GraphConstants.setLineBegin(attributes, defaultBeginDecoration);
    if (edge instanceof MutableTreeNode)
      addPorts((MutableTreeNode) edge, defaultPortLocations);
  }

  /**
   * Hook for subclassers to create a user object for edges that contains the
   * specified value. This implementation calls
   * {@link #createVertexUserObject(Object)}.
   *
   * @param value
   *            The value that the user object should contain.
   * @return Returns a new user object containing <code>value</code>.
   */
  protected Object createEdgeUserObject(Object value) {
    return createVertexUserObject(value);
  }

  /**
   * Hook for subclassers to create a user object for ports that contains the
   * specified value. This implementation calls
   * {@link #createVertexUserObject(Object)}.
   *
   * @param value
   *            The value that the user object should contain.
   * @return Returns a new user object containing <code>value</code>.
   */
  protected Object createPortUserObject(Object value) {
    return createVertexUserObject(value);
  }

  /**
   * Returns a new {@link JGraphpadBusinessObject}for the specified value.
   * This implementation replaces all <code>null</code> values with an empty
   * {@link JGraphpadRichTextValue}.
   *
   * @param value
   *            The value that the user object should contain.
   * @return Returns a new user object containing <code>value</code>.
   *
   * @see JGraphpadBusinessObject
   */
  protected Object createVertexUserObject(Object value) {
    return new JGraphpadBusinessObject((value != null) ? value
        : new JGraphpadRichTextValue(""));
  }

  /**
   * Hook for subclassers to construct attribute map for cells. This
   * implementation returns a new instance of {@link AttributeMap}.
   *
   * @return Returns a new attribute map.
   */
  protected AttributeMap createAttributeMap() {
    return new AttributeMap();
  }

  /**
   * Returns true if the specified filename has an image extension, namely one
   * in {@link javax.imageio.ImageIO#getReaderFormatNames()}.
   *
   * @param filename
   *            The filename to be checked.
   * @return Returns true if the filename is an image file.
   */
  public static boolean isImage(String filename) {
    String[] formats = ImageIO.getReaderFormatNames();
    filename = filename.toLowerCase();
    for (int j = 0; j < formats.length; j++) {
      if (filename.endsWith(formats[j].toLowerCase()))
        return true;
    }
    return false;
  }

  /**
   * Centers the specified window on the screen, taking into account the
   * current size of the window.
   *
   * @param wnd
   *            The window to be centered.
   */
  public static void center(Window wnd) {
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = wnd.getSize();
    wnd.setLocation(screenSize.width / 2 - (frameSize.width / 2),
        screenSize.height / 2 - (frameSize.height / 2));
  }

  //
 
  //

  /**
   * Constructs and displays a new application window.
   *
   * @param args
   *            The command line arguments to pass to the application.
   */
  public static void main(String[] args) {
    try {
      Map arguments = new Hashtable();
      List files = new LinkedList();
      if (args != null) {

        String key = null;
        String arg = null;
        for (int i = 0; i < args.length; i++) {
          arg = args[i];
          if (arg.startsWith("-")) {
            key = arg.substring(1);
            arguments.put(key, "");
            if (key.equals(ARG_VERSION))
              key = null;
          } else if (key != null) {
            arguments.put(key, arg);
            key = null;
          } else if (arg.length() > 0) {
            files.add(arg);
          }
        }
      }
      if (arguments.containsKey("?") || arguments.containsKey("help")
          || arguments.containsKey("-?")
          || arguments.containsKey("-help")) {
        System.out.println(USAGE);
      } else if (arguments.containsKey(ARG_VERSION)) {
        System.out.println(JGraphpad.VERSION + "\n" + JGraph.VERSION);
      } else {
       
        new JGraphpad().createApplication(files, arguments);
      }
    } catch (Exception e) {
      e.printStackTrace();

     
      System.exit(1);
    }
  }

  /**
   * Defines the usage information (use --help), see
   * http://java.sun.com/docs/books/tutorial/uiswing/misc/plaf.html#programmatic
   * on setting the look and feel.
   */
  public static final String USAGE = "Usage: java com.jgraph.JGraphpad [OPTION]...\n"
      + "  -"
      + ARG_SYSTEMLOOKANDFEEL
      + "                               use system look and feel\n"
      + ARG_JGOODIESLOOKANDFEEL
      + "                               jgoodies look and feel\n"
      + "  -"
      + ARG_VERSION
      + "                               print version\n"
      + "\nTip: java -Dswing.defaultlaf=com.jgoodies.looks.plastic.Plastic3DLookAndFeel\n"
      + "Exit status is 0 if OK, 1 if minor problems, 2 if serious trouble.\n"
      + "\nReport bugs via http://www.jgraph.com/tracker\n\n";

}
TOP

Related Classes of com.acelet.s.workflow.JGraphpad

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.