http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/toolbar/GraphEditToolbarSection.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/toolbar/GraphEditToolbarSection.java
 
b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/toolbar/GraphEditToolbarSection.java
deleted file mode 100644
index 7a06acc..0000000
--- 
a/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/toolbar/GraphEditToolbarSection.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester   
- * 
- *  Modifications to the initial code base are copyright of their
- *  respective authors, or their employers as appropriate.
- * 
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public License
- *  as published by the Free Software Foundation; either version 2.1 of
- *  the License, or (at your option) any later version.
- *    
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *    
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- 
******************************************************************************/
-package net.sf.taverna.t2.workbench.views.graph.toolbar;
-
-import static org.apache.taverna.ui.menu.DefaultToolBar.DEFAULT_TOOL_BAR;
-
-import java.net.URI;
-
-import org.apache.taverna.ui.menu.AbstractMenuSection;
-
-/**
- * @author Alex Nenadic
- */
-public class GraphEditToolbarSection extends AbstractMenuSection {
-       public static final URI GRAPH_EDIT_TOOLBAR_SECTION = URI
-                       
.create("http://taverna.sf.net/2008/t2workbench/menu#graphEditToolbarSection";);
-
-       public GraphEditToolbarSection() {
-               super(DEFAULT_TOOL_BAR, 30, GRAPH_EDIT_TOOLBAR_SECTION);
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/toolbar/RenameWFInputOutputProcessorToolbarAction.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/toolbar/RenameWFInputOutputProcessorToolbarAction.java
 
b/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/toolbar/RenameWFInputOutputProcessorToolbarAction.java
deleted file mode 100644
index 4a55db8..0000000
--- 
a/taverna-graph-view/src/main/java/net/sf/taverna/t2/workbench/views/graph/toolbar/RenameWFInputOutputProcessorToolbarAction.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*******************************************************************************
- * Copyright (C) 2007 The University of Manchester
- *
- *  Modifications to the initial code base are copyright of their
- *  respective authors, or their employers as appropriate.
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public License
- *  as published by the Free Software Foundation; either version 2.1 of
- *  the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- 
******************************************************************************/
-package net.sf.taverna.t2.workbench.views.graph.toolbar;
-
-import static 
net.sf.taverna.t2.workbench.views.graph.toolbar.GraphEditToolbarSection.GRAPH_EDIT_TOOLBAR_SECTION;
-
-import java.net.URI;
-
-import javax.swing.Action;
-
-import org.apache.taverna.ui.menu.AbstractMenuAction;
-import org.apache.taverna.workbench.edits.EditManager;
-import org.apache.taverna.workbench.selection.SelectionManager;
-import 
net.sf.taverna.t2.workbench.views.graph.actions.RenameWFInputOutputProcessorAction;
-
-/**
- * @author Alex Nenadic
- */
-public class RenameWFInputOutputProcessorToolbarAction extends
-               AbstractMenuAction {
-       private static final URI RENAME_WF_INPUT_OUTPUT_PROCESSOR_URI = URI
-                       
.create("http://taverna.sf.net/2008/t2workbench/menu#graphToolbarRenameWFInputOutputProcessor";);
-
-       private EditManager editManager;
-       private SelectionManager selectionManager;
-
-       public RenameWFInputOutputProcessorToolbarAction() {
-               super(GRAPH_EDIT_TOOLBAR_SECTION, 30,
-                               RENAME_WF_INPUT_OUTPUT_PROCESSOR_URI);
-       }
-
-       @Override
-       protected Action createAction() {
-               return new RenameWFInputOutputProcessorAction(editManager,
-                               selectionManager);
-       }
-
-       public void setEditManager(EditManager editManager) {
-               this.editManager = editManager;
-       }
-
-       public void setSelectionManager(SelectionManager selectionManager) {
-               this.selectionManager = selectionManager;
-       }
-}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/AutoScrollInteractor.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/AutoScrollInteractor.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/AutoScrollInteractor.java
new file mode 100644
index 0000000..50237ea
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/AutoScrollInteractor.java
@@ -0,0 +1,200 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph;
+
+import static java.awt.event.InputEvent.BUTTON1_DOWN_MASK;
+import static java.awt.event.InputEvent.BUTTON1_MASK;
+import static java.awt.event.MouseEvent.BUTTON1;
+import static java.awt.event.MouseEvent.MOUSE_DRAGGED;
+import static java.awt.event.MouseEvent.MOUSE_PRESSED;
+import static java.lang.System.currentTimeMillis;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.awt.geom.AffineTransform;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.apache.batik.swing.JSVGCanvas;
+import org.apache.batik.swing.gvt.InteractorAdapter;
+import org.apache.batik.swing.gvt.JGVTComponent;
+
+/**
+ * An interactor that scrolls the canvas view if the mouse is dragged to the
+ * edge of the canvas.
+ * 
+ * @author David Withers
+ */
+public class AutoScrollInteractor extends InteractorAdapter {
+       /**
+        * Defines the border around the canvas in which the auto scroll will 
become
+        * active.
+        */
+       private static final int BORDER = 25;
+       /**
+        * The interval, in milliseconds, between scroll events.
+        */
+       private static final long SCROLL_INTERVAL = 100;
+
+       private JSVGCanvas svgCanvas;
+       private Dimension canvasSize;
+       private int scrollX;
+       private int scrollY;
+       private int mouseX;
+       private int mouseY;
+
+       /**
+        * Component used to identify mouse events generated by this class
+        */
+       private Component eventIdentifier = new Component() {
+               private static final long serialVersionUID = 
-295542754718804222L;
+       };
+
+       private static Timer timer = new Timer("GraphAutoScrollTimer", true);
+
+       private TimerTask task;
+
+       /**
+        * Whether the interactor has finished.
+        */
+       protected boolean finished = true;
+
+       public AutoScrollInteractor(JSVGCanvas svgCanvas) {
+               this.svgCanvas = svgCanvas;
+       }
+
+       @Override
+       public boolean startInteraction(InputEvent ie) {
+               int mods = ie.getModifiers();
+               if (ie.getID() == MOUSE_PRESSED && (mods & BUTTON1_MASK) != 0) {
+                       AffineTransform transform = 
svgCanvas.getRenderingTransform();
+                       // check if we're zoomed in
+                       if (transform.getScaleX() > 1d || transform.getScaleY() 
> 1d) {
+                               canvasSize = svgCanvas.getSize();
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       @Override
+       public boolean endInteraction() {
+               return finished;
+       }
+
+       @Override
+       public void mousePressed(final MouseEvent e) {
+               if (startInteraction(e)) {
+                       finished = false;
+                       task = new TimerTask() {
+                               @Override
+                               public void run() {
+                                       scrollTimerCallback(e);
+                               }
+                       };
+                       timer.schedule(task, 0, SCROLL_INTERVAL);
+               }
+       }
+
+       /**
+        * Dispatches a mouse drag event that updates the mouse location by the
+        * amount that the canvas has been scrolled.
+        * 
+        * @param dragX
+        * @param dragY
+        */
+       private void dispatchDragEvent(double dragX, double dragY) {
+               int x = (int) (mouseX + dragX);
+               int y = (int) (mouseY + dragY);
+               MouseEvent mouseDragEvent = new MouseEvent(eventIdentifier,
+                               MOUSE_DRAGGED, currentTimeMillis(), 
BUTTON1_DOWN_MASK, x, y, 1,
+                               false, BUTTON1);
+               svgCanvas.dispatchEvent(mouseDragEvent);
+       }
+
+       @Override
+       public void mouseReleased(MouseEvent e) {
+               if (!finished) {
+                       finished = true;
+                       scrollX = 0;
+                       scrollY = 0;
+                       if (task != null)
+                               task.cancel();
+               }
+       }
+
+       @Override
+       public void mouseDragged(MouseEvent e) {
+               // ignore events generated by this class
+               if (!finished && e.getSource() != eventIdentifier) {
+                       mouseX = e.getX();
+                       mouseY = e.getY();
+                       int minX = BORDER;
+                       int maxX = canvasSize.width - BORDER;
+                       int minY = BORDER;
+                       int maxY = canvasSize.height - BORDER;
+
+                       scrollX = (mouseX < minX) ? (minX - mouseX)
+                                       : (mouseX > maxX) ? (maxX - mouseX) : 0;
+                       scrollY = (mouseY < minY) ? (minY - mouseY)
+                                       : (mouseY > maxY) ? (maxY - mouseY) : 0;
+               }
+       }
+
+       private void scrollTimerCallback(MouseEvent e) {
+               double x = scrollX;
+               double y = scrollY;
+               if (x == 0 && y == 0)
+                       return;
+
+               JGVTComponent c = (JGVTComponent) e.getSource();
+               AffineTransform rt = (AffineTransform) c.getRenderingTransform()
+                               .clone();
+               double currentTranslateX = rt.getTranslateX();
+               double currentTranslateY = rt.getTranslateY();
+               // the tranlation that will show the east edge
+               double maxTranslateX = -((canvasSize.width * rt.getScaleX()) - 
canvasSize.width);
+               // the translation that will show the south
+               double maxTranslateY = -((canvasSize.height * rt.getScaleY()) - 
canvasSize.height);
+
+               if (x > 0 && currentTranslateX + x > 0)
+                       // scroll left && not at west edge
+                       x = -currentTranslateX;
+               else if (x < 0 && currentTranslateX + x < maxTranslateX)
+                       // scroll right && not at east edge
+                       x = maxTranslateX - currentTranslateX;
+
+               if (y > 0 && currentTranslateY + y > 0)
+                       // scroll up && not at north edge
+                       y = -currentTranslateY;
+               else if (y < 0 && currentTranslateY + y < maxTranslateY)
+                       // scroll down && not at south edge
+                       y = maxTranslateY - currentTranslateY;
+
+               if (x != 0d || y != 0d) {
+                       AffineTransform at = 
AffineTransform.getTranslateInstance(x, y);
+                       rt.preConcatenate(at);
+                       c.setRenderingTransform(rt);
+                       dispatchDragEvent(x, y);
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/GraphViewComponent.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/GraphViewComponent.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/GraphViewComponent.java
new file mode 100644
index 0000000..4ec1a28
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/GraphViewComponent.java
@@ -0,0 +1,547 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph;
+
+import static java.awt.BorderLayout.CENTER;
+import static java.awt.BorderLayout.NORTH;
+import static javax.swing.Action.SHORT_DESCRIPTION;
+import static javax.swing.Action.SMALL_ICON;
+import static javax.swing.BoxLayout.PAGE_AXIS;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.allportIcon;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.blobIcon;
+import static 
org.apache.taverna.workbench.icons.WorkbenchIcons.expandNestedIcon;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.horizontalIcon;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.noportIcon;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.refreshIcon;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.verticalIcon;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.zoomInIcon;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.zoomOutIcon;
+import static 
org.apache.taverna.workbench.views.graph.config.GraphViewConfiguration.ALIGNMENT;
+import static 
org.apache.taverna.workbench.views.graph.config.GraphViewConfiguration.ANIMATION_ENABLED;
+import static 
org.apache.taverna.workbench.views.graph.config.GraphViewConfiguration.ANIMATION_SPEED;
+import static 
org.apache.taverna.workbench.views.graph.config.GraphViewConfiguration.PORT_STYLE;
+import static org.apache.batik.swing.svg.AbstractJSVGComponent.ALWAYS_DYNAMIC;
+
+import java.awt.BorderLayout;
+import java.awt.CardLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.BoxLayout;
+import javax.swing.ButtonGroup;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JToggleButton;
+import javax.swing.JToolBar;
+import javax.swing.Timer;
+import javax.swing.border.EmptyBorder;
+
+import org.apache.taverna.lang.observer.Observable;
+import org.apache.taverna.lang.observer.SwingAwareObserver;
+import org.apache.taverna.ui.menu.MenuManager;
+import org.apache.taverna.workbench.configuration.colour.ColourManager;
+import 
org.apache.taverna.workbench.configuration.workbench.WorkbenchConfiguration;
+import org.apache.taverna.workbench.edits.EditManager;
+import 
org.apache.taverna.workbench.edits.EditManager.AbstractDataflowEditEvent;
+import org.apache.taverna.workbench.edits.EditManager.EditManagerEvent;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.file.events.ClosedDataflowEvent;
+import org.apache.taverna.workbench.file.events.FileManagerEvent;
+import org.apache.taverna.workbench.models.graph.Graph.Alignment;
+import org.apache.taverna.workbench.models.graph.GraphController;
+import org.apache.taverna.workbench.models.graph.GraphController.PortStyle;
+import org.apache.taverna.workbench.models.graph.svg.SVGGraphController;
+import org.apache.taverna.workbench.selection.SelectionManager;
+import org.apache.taverna.workbench.selection.events.SelectionManagerEvent;
+import 
org.apache.taverna.workbench.selection.events.WorkflowBundleSelectionEvent;
+import org.apache.taverna.workbench.selection.events.WorkflowSelectionEvent;
+import org.apache.taverna.workbench.ui.dndhandler.ServiceTransferHandler;
+import org.apache.taverna.workbench.ui.zaria.UIComponentSPI;
+import org.apache.taverna.workbench.views.graph.config.GraphViewConfiguration;
+import org.apache.taverna.workbench.views.graph.menu.ResetDiagramAction;
+import org.apache.taverna.workbench.views.graph.menu.ZoomInAction;
+import org.apache.taverna.workbench.views.graph.menu.ZoomOutAction;
+
+import org.apache.batik.swing.JSVGCanvas;
+import org.apache.batik.swing.JSVGScrollPane;
+import org.apache.batik.swing.gvt.GVTTreeRendererAdapter;
+import org.apache.batik.swing.gvt.GVTTreeRendererEvent;
+import org.apache.log4j.Logger;
+
+import org.apache.taverna.commons.services.ServiceRegistry;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.scufl2.api.core.Workflow;
+
+/**
+ * @author David Withers
+ * @author Alex Nenadic
+ * @author Tom Oinn
+ */
+public class GraphViewComponent extends JPanel implements UIComponentSPI {
+       private static final long serialVersionUID = 7404937056378331528L;
+       private static final Logger logger = 
Logger.getLogger(GraphViewComponent.class);
+
+       private Workflow workflow;
+       private SVGGraphController graphController;
+       private JPanel diagramPanel;
+
+       private Map<WorkflowBundle, Set<Workflow>> workflowsMap = new 
IdentityHashMap<>();
+
+       private Map<Workflow, SVGGraphController> graphControllerMap = new 
IdentityHashMap<>();
+       private Map<Workflow, JPanel> diagramPanelMap = new IdentityHashMap<>();
+       private Map<Workflow, Action[]> diagramActionsMap = new 
IdentityHashMap<>();
+
+       private Timer timer;
+
+       private CardLayout cardLayout;
+
+       private final ColourManager colourManager;
+       private final EditManager editManager;
+       private final MenuManager menuManager;
+       private final GraphViewConfiguration graphViewConfiguration;
+       private final WorkbenchConfiguration workbenchConfiguration;
+       private final SelectionManager selectionManager;
+       private final ServiceRegistry serviceRegistry;
+
+       public GraphViewComponent(ColourManager colourManager,
+                       EditManager editManager, FileManager fileManager,
+                       MenuManager menuManager,
+                       GraphViewConfiguration graphViewConfiguration,
+                       WorkbenchConfiguration workbenchConfiguration,
+                       SelectionManager selectionManager, ServiceRegistry 
serviceRegistry) {
+               this.colourManager = colourManager;
+               this.editManager = editManager;
+               this.menuManager = menuManager;
+               this.graphViewConfiguration = graphViewConfiguration;
+               this.workbenchConfiguration = workbenchConfiguration;
+               this.selectionManager = selectionManager;
+               this.serviceRegistry = serviceRegistry;
+
+               cardLayout = new CardLayout();
+               setLayout(cardLayout);
+
+               ActionListener taskPerformer = new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent evt) {
+                               if (graphController != null)
+                                       graphController.redraw();
+                               timer.stop();
+                       }
+               };
+               timer = new Timer(100, taskPerformer);
+
+               addComponentListener(new ComponentAdapter() {
+                       @Override
+                       public void componentResized(ComponentEvent e) {
+                               if (timer.isRunning())
+                                       timer.restart();
+                               else
+                                       timer.start();
+                       }
+               });
+
+               editManager.addObserver(new EditManagerObserver());
+               selectionManager.addObserver(new SelectionManagerObserver());
+               fileManager.addObserver(new FileManagerObserver());
+       }
+
+       @Override
+       protected void finalize() throws Throwable {
+               if (timer != null)
+                       timer.stop();
+       }
+
+       @Override
+       public String getName() {
+               return "Graph View Component";
+       }
+
+       @Override
+       public ImageIcon getIcon() {
+               return null;
+       }
+
+       @Override
+       public void onDisplay() {
+       }
+
+       @Override
+       public void onDispose() {
+               if (timer != null)
+                       timer.stop();
+       }
+
+       private JPanel createDiagramPanel(Workflow workflow) {
+               final JPanel diagramPanel = new JPanel(new BorderLayout());
+
+               // get the default diagram settings
+               Alignment alignment = Alignment.valueOf(graphViewConfiguration
+                               .getProperty(ALIGNMENT));
+               PortStyle portStyle = PortStyle.valueOf(graphViewConfiguration
+                               .getProperty(PORT_STYLE));
+               boolean animationEnabled = 
Boolean.parseBoolean(graphViewConfiguration
+                               .getProperty(ANIMATION_ENABLED));
+               int animationSpeed = Integer.parseInt(graphViewConfiguration
+                               .getProperty(ANIMATION_SPEED));
+
+               // create an SVG canvas
+               final JSVGCanvas svgCanvas = new JSVGCanvas(null, true, false);
+               svgCanvas.setEnableZoomInteractor(false);
+               svgCanvas.setEnableRotateInteractor(false);
+               svgCanvas.setDocumentState(ALWAYS_DYNAMIC);
+               svgCanvas.setTransferHandler(new 
ServiceTransferHandler(editManager,
+                               menuManager, selectionManager, 
serviceRegistry));
+
+               AutoScrollInteractor asi = new AutoScrollInteractor(svgCanvas);
+               svgCanvas.addMouseListener(asi);
+               svgCanvas.addMouseMotionListener(asi);
+
+               final JSVGScrollPane svgScrollPane = new 
MySvgScrollPane(svgCanvas);
+
+               GVTTreeRendererAdapter gvtTreeRendererAdapter = new 
GVTTreeRendererAdapter() {
+                       @Override
+                       public void gvtRenderingCompleted(GVTTreeRendererEvent 
e) {
+                               logger.info("Rendered svg");
+                               svgScrollPane.reset();
+                               diagramPanel.revalidate();
+                       }
+               };
+               svgCanvas.addGVTTreeRendererListener(gvtTreeRendererAdapter);
+
+               // create a graph controller
+               SVGGraphController svgGraphController = new SVGGraphController(
+                               workflow, 
selectionManager.getSelectedProfile(), false,
+                               svgCanvas, alignment, portStyle, editManager, 
menuManager,
+                               colourManager, workbenchConfiguration);
+               svgGraphController.setDataflowSelectionModel(selectionManager
+                               
.getDataflowSelectionModel(workflow.getParent()));
+               svgGraphController.setAnimationSpeed(animationEnabled ? 
animationSpeed
+                               : 0);
+
+               graphControllerMap.put(workflow, svgGraphController);
+
+               // Toolbar with actions related to graph
+               JToolBar graphActionsToolbar = graphActionsToolbar(workflow,
+                               svgGraphController, svgCanvas, alignment, 
portStyle);
+               graphActionsToolbar.setAlignmentX(LEFT_ALIGNMENT);
+               graphActionsToolbar.setFloatable(false);
+
+               // Panel to hold the toolbars
+               JPanel toolbarPanel = new JPanel();
+               toolbarPanel.setLayout(new BoxLayout(toolbarPanel, PAGE_AXIS));
+               toolbarPanel.add(graphActionsToolbar);
+
+               diagramPanel.add(toolbarPanel, NORTH);
+               diagramPanel.add(svgScrollPane, CENTER);
+
+               // JTextField workflowHierarchy = new 
JTextField(workflow.getName());
+               // diagramPanel.add(workflowHierarchy, BorderLayout.SOUTH);
+
+               return diagramPanel;
+       }
+
+       @SuppressWarnings("serial")
+       private JToolBar graphActionsToolbar(Workflow workflow,
+                       final SVGGraphController graphController, JSVGCanvas 
svgCanvas,
+                       Alignment alignment, PortStyle portStyle) {
+               JToolBar toolBar = new JToolBar();
+
+               JButton resetDiagramButton = new JButton();
+               resetDiagramButton.setBorder(new EmptyBorder(0, 2, 0, 2));
+               JButton zoomInButton = new JButton();
+               zoomInButton.setBorder(new EmptyBorder(0, 2, 0, 2));
+               JButton zoomOutButton = new JButton();
+               zoomOutButton.setBorder(new EmptyBorder(0, 2, 0, 2));
+
+               Action resetDiagramAction = svgCanvas.new 
ResetTransformAction();
+               ResetDiagramAction.setDesignAction(resetDiagramAction);
+               resetDiagramAction.putValue(SHORT_DESCRIPTION, "Reset Diagram");
+               resetDiagramAction.putValue(SMALL_ICON, refreshIcon);
+               resetDiagramButton.setAction(resetDiagramAction);
+
+               Action zoomInAction = svgCanvas.new ZoomAction(1.2);
+               ZoomInAction.setDesignAction(zoomInAction);
+               zoomInAction.putValue(SHORT_DESCRIPTION, "Zoom In");
+               zoomInAction.putValue(SMALL_ICON, zoomInIcon);
+               zoomInButton.setAction(zoomInAction);
+
+               Action zoomOutAction = svgCanvas.new ZoomAction(1 / 1.2);
+               ZoomOutAction.setDesignAction(zoomOutAction);
+               zoomOutAction.putValue(SHORT_DESCRIPTION, "Zoom Out");
+               zoomOutAction.putValue(SMALL_ICON, zoomOutIcon);
+               zoomOutButton.setAction(zoomOutAction);
+
+               diagramActionsMap.put(workflow, new Action[] { 
resetDiagramAction,
+                               zoomInAction, zoomOutAction });
+
+               toolBar.add(resetDiagramButton);
+               toolBar.add(zoomInButton);
+               toolBar.add(zoomOutButton);
+
+               toolBar.addSeparator();
+
+               ButtonGroup nodeTypeGroup = new ButtonGroup();
+
+               JToggleButton noPorts = new JToggleButton();
+               JToggleButton allPorts = new JToggleButton();
+               JToggleButton blobs = new JToggleButton();
+               nodeTypeGroup.add(noPorts);
+               nodeTypeGroup.add(allPorts);
+               nodeTypeGroup.add(blobs);
+
+               if (portStyle.equals(PortStyle.NONE))
+                       noPorts.setSelected(true);
+               else if (portStyle.equals(PortStyle.ALL))
+                       allPorts.setSelected(true);
+               else
+                       blobs.setSelected(true);
+
+               noPorts.setAction(new AbstractAction() {
+                       @Override
+                       public void actionPerformed(ActionEvent arg0) {
+                               graphController.setPortStyle(PortStyle.NONE);
+                               graphController.redraw();
+                       }
+               });
+               noPorts.getAction().putValue(SHORT_DESCRIPTION,
+                               "Display no service ports");
+               noPorts.getAction().putValue(SMALL_ICON, noportIcon);
+               noPorts.setFocusPainted(false);
+
+               allPorts.setAction(new AbstractAction() {
+                       @Override
+                       public void actionPerformed(ActionEvent arg0) {
+                               graphController.setPortStyle(PortStyle.ALL);
+                               graphController.redraw();
+                       }
+               });
+               allPorts.getAction().putValue(SHORT_DESCRIPTION,
+                               "Display all service ports");
+               allPorts.getAction().putValue(SMALL_ICON, allportIcon);
+               allPorts.setFocusPainted(false);
+
+               blobs.setAction(new AbstractAction() {
+                       @Override
+                       public void actionPerformed(ActionEvent arg0) {
+                               graphController.setPortStyle(PortStyle.BLOB);
+                               graphController.redraw();
+                       }
+               });
+               blobs.getAction().putValue(SHORT_DESCRIPTION,
+                               "Display services as circles");
+               blobs.getAction().putValue(SMALL_ICON, blobIcon);
+               blobs.setFocusPainted(false);
+
+               toolBar.add(noPorts);
+               toolBar.add(allPorts);
+               toolBar.add(blobs);
+
+               toolBar.addSeparator();
+
+               ButtonGroup alignmentGroup = new ButtonGroup();
+
+               JToggleButton vertical = new JToggleButton();
+               JToggleButton horizontal = new JToggleButton();
+               alignmentGroup.add(vertical);
+               alignmentGroup.add(horizontal);
+
+               if (alignment.equals(Alignment.VERTICAL)) {
+                       vertical.setSelected(true);
+               } else {
+                       horizontal.setSelected(true);
+               }
+
+               vertical.setAction(new AbstractAction() {
+                       @Override
+                       public void actionPerformed(ActionEvent arg0) {
+                               
graphController.setAlignment(Alignment.VERTICAL);
+                               graphController.redraw();
+                       }
+               });
+               vertical.getAction().putValue(SHORT_DESCRIPTION,
+                               "Align services vertically");
+               vertical.getAction().putValue(SMALL_ICON, verticalIcon);
+               vertical.setFocusPainted(false);
+
+               horizontal.setAction(new AbstractAction() {
+                       @Override
+                       public void actionPerformed(ActionEvent arg0) {
+                               
graphController.setAlignment(Alignment.HORIZONTAL);
+                               graphController.redraw();
+                       }
+
+               });
+               horizontal.getAction().putValue(SHORT_DESCRIPTION,
+                               "Align services horizontally");
+               horizontal.getAction().putValue(SMALL_ICON, horizontalIcon);
+               horizontal.setFocusPainted(false);
+
+               toolBar.add(vertical);
+               toolBar.add(horizontal);
+
+               toolBar.addSeparator();
+
+               JToggleButton expandNested = new JToggleButton();
+               expandNested.setSelected(true);
+
+               expandNested.setAction(new AbstractAction() {
+                       @Override
+                       public void actionPerformed(ActionEvent arg0) {
+                               
graphController.setExpandNestedDataflows(!graphController
+                                               .expandNestedDataflows());
+                               graphController.redraw();
+                       }
+               });
+               expandNested.getAction().putValue(SHORT_DESCRIPTION,
+                               "Expand Nested Workflows");
+               expandNested.getAction().putValue(SMALL_ICON, expandNestedIcon);
+               expandNested.setFocusPainted(false);
+               toolBar.add(expandNested);
+
+               return toolBar;
+       }
+
+       /**
+        * Sets the Workflow to display in the graph view.
+        *
+        * @param workflow
+        */
+       private void setWorkflow(Workflow workflow) {
+               this.workflow = workflow;
+               if (!diagramPanelMap.containsKey(workflow))
+                       addWorkflow(workflow);
+               graphController = graphControllerMap.get(workflow);
+               diagramPanel = diagramPanelMap.get(workflow);
+               Action[] actions = diagramActionsMap.get(workflow);
+               if (actions != null && actions.length == 3) {
+                       ResetDiagramAction.setDesignAction(actions[0]);
+                       ZoomInAction.setDesignAction(actions[1]);
+                       ZoomOutAction.setDesignAction(actions[2]);
+               }
+               cardLayout.show(this, String.valueOf(diagramPanel.hashCode()));
+               graphController.redraw();
+       }
+
+       private void addWorkflow(Workflow workflow) {
+               JPanel newDiagramPanel = createDiagramPanel(workflow);
+               add(newDiagramPanel, 
String.valueOf(newDiagramPanel.hashCode()));
+               diagramPanelMap.put(workflow, newDiagramPanel);
+               if (!workflowsMap.containsKey(workflow.getParent()))
+                       workflowsMap.put(workflow.getParent(), new 
HashSet<Workflow>());
+               workflowsMap.get(workflow.getParent()).add(workflow);
+       }
+
+       private void removeWorkflow(Workflow workflow) {
+               JPanel panel = diagramPanelMap.remove(workflow);
+               if (panel != null)
+                       remove(panel);
+               SVGGraphController removedController = 
graphControllerMap.remove(workflow);
+               if (removedController != null)
+                       removedController.shutdown();
+               diagramActionsMap.remove(workflow);
+               Set<Workflow> workflows = 
workflowsMap.get(workflow.getParent());
+               if (workflows != null)
+                       workflows.remove(workflow);
+       }
+
+       public GraphController getGraphController(Workflow workflow) {
+               return graphControllerMap.get(workflow);
+       }
+
+       private class EditManagerObserver extends
+                       SwingAwareObserver<EditManagerEvent> {
+               @Override
+               public void notifySwing(Observable<EditManagerEvent> sender,
+                               EditManagerEvent message) {
+                       if (!(message instanceof AbstractDataflowEditEvent))
+                               return;
+                       AbstractDataflowEditEvent dataflowEditEvent = 
(AbstractDataflowEditEvent) message;
+                       if (dataflowEditEvent.getDataFlow() != 
workflow.getParent())
+                               return;
+                       
+                       boolean animationEnabled = Boolean
+                                       .parseBoolean(graphViewConfiguration
+                                                       
.getProperty(ANIMATION_ENABLED));
+                       int animationSpeed = (animationEnabled ? Integer
+                                       .parseInt(graphViewConfiguration
+                                                       
.getProperty(ANIMATION_SPEED)) : 0);
+                       boolean animationSettingChanged = (animationEnabled != 
(graphController
+                                       .getAnimationSpeed() != 0));
+
+                       if (graphController.isDotMissing() || 
animationSettingChanged) {
+                               removeWorkflow(workflow);
+                               setWorkflow(workflow);
+                       } else {
+                               if (animationSpeed != 
graphController.getAnimationSpeed())
+                                       
graphController.setAnimationSpeed(animationSpeed);
+                               graphController.redraw();
+                       }
+               }
+       }
+
+       private class FileManagerObserver extends 
SwingAwareObserver<FileManagerEvent> {
+               @Override
+               public void notifySwing(Observable<FileManagerEvent> sender, 
final FileManagerEvent message) {
+                       if (!(message instanceof ClosedDataflowEvent))
+                               return;
+                       ClosedDataflowEvent closedDataflowEvent = 
(ClosedDataflowEvent) message;
+
+                       WorkflowBundle workflowBundle = 
closedDataflowEvent.getDataflow();
+                       if (workflowsMap.containsKey(workflowBundle))
+                               for (Workflow workflow : 
workflowsMap.remove(workflowBundle))
+                                       removeWorkflow(workflow);
+               }
+       }
+
+       private class SelectionManagerObserver extends
+                       SwingAwareObserver<SelectionManagerEvent> {
+               @Override
+               public void notifySwing(Observable<SelectionManagerEvent> 
sender,
+                               SelectionManagerEvent message) {
+                       if (message instanceof WorkflowSelectionEvent)
+                               
setWorkflow(selectionManager.getSelectedWorkflow());
+                       else if (message instanceof 
WorkflowBundleSelectionEvent)
+                               
setWorkflow(selectionManager.getSelectedWorkflow());
+               }
+       }
+
+       private class MySvgScrollPane extends JSVGScrollPane {
+               private static final long serialVersionUID = 
-1539947450704269879L;
+
+               public MySvgScrollPane(JSVGCanvas canvas) {
+                       super(canvas);
+               }
+
+               @Override
+               public void reset() {
+                       super.resizeScrollBars();
+                       super.reset();
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/GraphViewComponentFactory.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/GraphViewComponentFactory.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/GraphViewComponentFactory.java
new file mode 100644
index 0000000..3b0cff4
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/GraphViewComponentFactory.java
@@ -0,0 +1,99 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph;
+
+import javax.swing.ImageIcon;
+
+import org.apache.taverna.commons.services.ServiceRegistry;
+
+import org.apache.taverna.ui.menu.MenuManager;
+import org.apache.taverna.workbench.configuration.colour.ColourManager;
+import 
org.apache.taverna.workbench.configuration.workbench.WorkbenchConfiguration;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.file.FileManager;
+import org.apache.taverna.workbench.selection.SelectionManager;
+import org.apache.taverna.workbench.ui.zaria.UIComponentFactorySPI;
+import org.apache.taverna.workbench.ui.zaria.UIComponentSPI;
+import org.apache.taverna.workbench.views.graph.config.GraphViewConfiguration;
+
+/**
+ * @author David Withers
+ */
+public class GraphViewComponentFactory implements UIComponentFactorySPI {
+       private EditManager editManager;
+       private FileManager fileManager;
+       private MenuManager menuManager;
+       private SelectionManager selectionManager;
+       private ColourManager colourManager;
+       private WorkbenchConfiguration workbenchConfiguration;
+       private GraphViewConfiguration graphViewConfiguration;
+       private ServiceRegistry serviceRegistry;
+
+       @Override
+       public UIComponentSPI getComponent() {
+               return new GraphViewComponent(colourManager, editManager, 
fileManager,
+                               menuManager, graphViewConfiguration, 
workbenchConfiguration,
+                               selectionManager, serviceRegistry);
+       }
+
+       @Override
+       public ImageIcon getIcon() {
+               return null;
+       }
+
+       @Override
+       public String getName() {
+               return "Graph View";
+       }
+
+       public void setEditManager(EditManager editManager) {
+               this.editManager = editManager;
+       }
+
+       public void setFileManager(FileManager fileManager) {
+               this.fileManager = fileManager;
+       }
+
+       public void setMenuManager(MenuManager menuManager) {
+               this.menuManager = menuManager;
+       }
+
+       public void setSelectionManager(SelectionManager selectionManager) {
+               this.selectionManager = selectionManager;
+       }
+
+       public void setColourManager(ColourManager colourManager) {
+               this.colourManager = colourManager;
+       }
+
+       public void setWorkbenchConfiguration(
+                       WorkbenchConfiguration workbenchConfiguration) {
+               this.workbenchConfiguration = workbenchConfiguration;
+       }
+
+       public void setGraphViewConfiguration(
+                       GraphViewConfiguration graphViewConfiguration) {
+               this.graphViewConfiguration = graphViewConfiguration;
+       }
+
+       public void setServiceRegistry(ServiceRegistry serviceRegistry) {
+               this.serviceRegistry = serviceRegistry;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/AddWFInputAction.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/AddWFInputAction.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/AddWFInputAction.java
new file mode 100644
index 0000000..b702393
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/AddWFInputAction.java
@@ -0,0 +1,68 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph.actions;
+
+import static java.awt.event.InputEvent.ALT_DOWN_MASK;
+import static java.awt.event.InputEvent.SHIFT_DOWN_MASK;
+import static java.awt.event.KeyEvent.VK_I;
+import static javax.swing.KeyStroke.getKeyStroke;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.inputIcon;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+
+import org.apache.taverna.ui.menu.DesignOnlyAction;
+import org.apache.taverna.workbench.design.actions.AddDataflowInputAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.selection.SelectionManager;
+import org.apache.taverna.scufl2.api.core.Workflow;
+
+/**
+ * An action that adds a workflow input.
+ * 
+ * @author Alex Nenadic
+ * @author Alan R Williams
+ */
+@SuppressWarnings("serial")
+public class AddWFInputAction extends AbstractAction implements
+               DesignOnlyAction {
+       private final EditManager editManager;
+       private final SelectionManager selectionManager;
+
+       public AddWFInputAction(EditManager editManager,
+                       SelectionManager selectionManager) {
+               super();
+               this.editManager = editManager;
+               this.selectionManager = selectionManager;
+               putValue(SMALL_ICON, inputIcon);
+               putValue(NAME, "Workflow input port");
+               putValue(SHORT_DESCRIPTION, "Workflow input port");
+               putValue(ACCELERATOR_KEY,
+                               getKeyStroke(VK_I, SHIFT_DOWN_MASK | 
ALT_DOWN_MASK));
+       }
+
+       @Override
+       public void actionPerformed(ActionEvent e) {
+               Workflow workflow = selectionManager.getSelectedWorkflow();
+               new AddDataflowInputAction(workflow, null, editManager,
+                               selectionManager).actionPerformed(e);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/AddWFOutputAction.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/AddWFOutputAction.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/AddWFOutputAction.java
new file mode 100644
index 0000000..8f8eaeb
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/AddWFOutputAction.java
@@ -0,0 +1,68 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph.actions;
+
+import static java.awt.event.InputEvent.ALT_DOWN_MASK;
+import static java.awt.event.InputEvent.SHIFT_DOWN_MASK;
+import static java.awt.event.KeyEvent.VK_O;
+import static javax.swing.KeyStroke.getKeyStroke;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+
+import org.apache.taverna.ui.menu.DesignOnlyAction;
+import org.apache.taverna.workbench.design.actions.AddDataflowOutputAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.icons.WorkbenchIcons;
+import org.apache.taverna.workbench.selection.SelectionManager;
+import org.apache.taverna.scufl2.api.core.Workflow;
+
+/**
+ * An action that adds a workflow output.
+ * 
+ * @author Alex Nenadic
+ * @author Alan R Williams
+ */
+@SuppressWarnings("serial")
+public class AddWFOutputAction extends AbstractAction implements
+               DesignOnlyAction {
+       private final EditManager editManager;
+       private final SelectionManager selectionManager;
+
+       public AddWFOutputAction(EditManager editManager,
+                       SelectionManager selectionManager) {
+               super();
+               this.editManager = editManager;
+               this.selectionManager = selectionManager;
+               putValue(SMALL_ICON, WorkbenchIcons.outputIcon);
+               putValue(NAME, "Workflow output port");
+               putValue(SHORT_DESCRIPTION, "Workflow output port");
+               putValue(ACCELERATOR_KEY,
+                               getKeyStroke(VK_O, SHIFT_DOWN_MASK | 
ALT_DOWN_MASK));
+       }
+
+       @Override
+       public void actionPerformed(ActionEvent e) {
+               Workflow workflow = selectionManager.getSelectedWorkflow();
+               new AddDataflowOutputAction(workflow, null, editManager,
+                               selectionManager).actionPerformed(e);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/DeleteGraphComponentAction.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/DeleteGraphComponentAction.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/DeleteGraphComponentAction.java
new file mode 100644
index 0000000..a25b4bc
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/DeleteGraphComponentAction.java
@@ -0,0 +1,179 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph.actions;
+
+import static java.awt.event.KeyEvent.VK_DELETE;
+import static javax.swing.KeyStroke.getKeyStroke;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.deleteIcon;
+
+import java.awt.event.ActionEvent;
+import java.util.Set;
+
+import javax.swing.AbstractAction;
+
+import org.apache.taverna.lang.observer.Observable;
+import org.apache.taverna.lang.observer.Observer;
+import org.apache.taverna.lang.observer.SwingAwareObserver;
+import org.apache.taverna.ui.menu.DesignOnlyAction;
+import org.apache.taverna.workbench.design.actions.RemoveConditionAction;
+import 
org.apache.taverna.workbench.design.actions.RemoveDataflowInputPortAction;
+import 
org.apache.taverna.workbench.design.actions.RemoveDataflowOutputPortAction;
+import org.apache.taverna.workbench.design.actions.RemoveDatalinkAction;
+import org.apache.taverna.workbench.design.actions.RemoveProcessorAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.selection.DataflowSelectionModel;
+import org.apache.taverna.workbench.selection.SelectionManager;
+import org.apache.taverna.workbench.selection.events.DataflowSelectionMessage;
+import org.apache.taverna.workbench.selection.events.SelectionManagerEvent;
+import 
org.apache.taverna.workbench.selection.events.WorkflowBundleSelectionEvent;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.scufl2.api.core.ControlLink;
+import org.apache.taverna.scufl2.api.core.DataLink;
+import org.apache.taverna.scufl2.api.core.Processor;
+import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
+import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
+
+/**
+ * An action that deletes the selected graph component.
+ *
+ * @author Alex Nenadic
+ */
+@SuppressWarnings("serial")
+public class DeleteGraphComponentAction extends AbstractAction implements 
DesignOnlyAction {
+       /** Current workflow's selection model event observer.*/
+       private Observer<DataflowSelectionMessage> workflowSelectionObserver = 
new DataflowSelectionObserver();
+
+       private final EditManager editManager;
+       private final SelectionManager selectionManager;
+
+       public DeleteGraphComponentAction(EditManager editManager, final 
SelectionManager selectionManager) {
+               super();
+               this.editManager = editManager;
+               this.selectionManager = selectionManager;
+               putValue(SMALL_ICON, deleteIcon);
+               putValue(NAME, "Delete");
+               putValue(SHORT_DESCRIPTION, "Delete selected component");
+               putValue(ACCELERATOR_KEY, getKeyStroke(VK_DELETE, 0));
+               setEnabled(false);
+
+               selectionManager.addObserver(new SelectionManagerObserver());
+       }
+
+       @Override
+       public void actionPerformed(ActionEvent e) {
+               WorkflowBundle workflowBundle = selectionManager
+                               .getSelectedWorkflowBundle();
+               DataflowSelectionModel dataFlowSelectionModel = selectionManager
+                               .getDataflowSelectionModel(workflowBundle);
+               // Get all selected components
+               Set<Object> selectedWFComponents = 
dataFlowSelectionModel.getSelection();
+               for (Object selectedWFComponent : selectedWFComponents)
+                       if (selectedWFComponent instanceof Processor) {
+                               Processor processor = (Processor) 
selectedWFComponent;
+                               new 
RemoveProcessorAction(processor.getParent(), processor,
+                                               null, editManager, 
selectionManager).actionPerformed(e);
+                       } else if (selectedWFComponent instanceof DataLink) {
+                               DataLink dataLink = (DataLink) 
selectedWFComponent;
+                               new RemoveDatalinkAction(dataLink.getParent(), 
dataLink, null,
+                                               editManager, 
selectionManager).actionPerformed(e);
+                       } else if (selectedWFComponent instanceof 
InputWorkflowPort) {
+                               InputWorkflowPort port = (InputWorkflowPort) 
selectedWFComponent;
+                               new 
RemoveDataflowInputPortAction(port.getParent(), port, null,
+                                               editManager, 
selectionManager).actionPerformed(e);
+                       } else if (selectedWFComponent instanceof 
OutputWorkflowPort) {
+                               OutputWorkflowPort port = (OutputWorkflowPort) 
selectedWFComponent;
+                               new 
RemoveDataflowOutputPortAction(port.getParent(), port,
+                                               null, editManager, 
selectionManager).actionPerformed(e);
+                       } else if (selectedWFComponent instanceof ControlLink) {
+                               ControlLink controlLink = (ControlLink) 
selectedWFComponent;
+                               new 
RemoveConditionAction(controlLink.getParent(), controlLink,
+                                               null, editManager, 
selectionManager).actionPerformed(e);
+                       }
+       }
+
+       /**
+        * Check if action should be enabled or disabled and update its status.
+        */
+       public void updateStatus(WorkflowBundle selectionWorkflowBundle) {
+               if (selectionWorkflowBundle != null) {
+                       DataflowSelectionModel selectionModel = selectionManager
+                                       
.getDataflowSelectionModel(selectionWorkflowBundle);
+                       Set<Object> selection = selectionModel.getSelection();
+                       if (!selection.isEmpty()) {
+                               // Take the first selected item - we only 
support single selections anyway
+                               Object selected = selection.toArray()[0];
+                               if ((selected instanceof Processor)
+                                               || (selected instanceof 
InputWorkflowPort)
+                                               || (selected instanceof 
OutputWorkflowPort)
+                                               || (selected instanceof 
DataLink)
+                                               || (selected instanceof 
ControlLink)) {
+                                       setEnabled(true);
+                                       return;
+                               }
+                       }
+               }
+               setEnabled(false);
+       }
+
+       /**
+        * Observes events on workflow Selection Manager, i.e. when a workflow 
node
+        * is selected in the graph view, and enables/disables this action
+        * accordingly.
+        */
+       private final class DataflowSelectionObserver extends
+                       SwingAwareObserver<DataflowSelectionMessage> {
+               @Override
+               public void notifySwing(Observable<DataflowSelectionMessage> 
sender,
+                               DataflowSelectionMessage message) {
+                       
updateStatus(selectionManager.getSelectedWorkflowBundle());
+               }
+       }
+
+       private final class SelectionManagerObserver extends
+                       SwingAwareObserver<SelectionManagerEvent> {
+               @Override
+               public void notifySwing(Observable<SelectionManagerEvent> 
sender,
+                               SelectionManagerEvent message) {
+                       if (!(message instanceof WorkflowBundleSelectionEvent))
+                               return;
+                       WorkflowBundleSelectionEvent 
workflowBundleSelectionEvent = (WorkflowBundleSelectionEvent) message;
+                       WorkflowBundle oldFlow = workflowBundleSelectionEvent
+                                       .getPreviouslySelectedWorkflowBundle();
+                       WorkflowBundle newFlow = workflowBundleSelectionEvent
+                                       .getSelectedWorkflowBundle();
+
+                       /*
+                        * Remove the workflow selection model listener from 
the previous
+                        * (if any) and add to the new workflow (if any)
+                        */
+                       if (oldFlow != null)
+                               
selectionManager.getDataflowSelectionModel(oldFlow)
+                                               
.removeObserver(workflowSelectionObserver);
+
+                       // Update the buttons status as current dataflow has 
changed
+                       updateStatus(newFlow);
+
+                       if (newFlow != null)
+                               
selectionManager.getDataflowSelectionModel(newFlow)
+                                               
.addObserver(workflowSelectionObserver);
+               }
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/RenameWFInputOutputProcessorAction.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/RenameWFInputOutputProcessorAction.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/RenameWFInputOutputProcessorAction.java
new file mode 100644
index 0000000..5c01a0b
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/actions/RenameWFInputOutputProcessorAction.java
@@ -0,0 +1,183 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph.actions;
+
+import static java.awt.event.KeyEvent.VK_F2;
+import static javax.swing.JOptionPane.WARNING_MESSAGE;
+import static javax.swing.JOptionPane.showMessageDialog;
+import static javax.swing.KeyStroke.getKeyStroke;
+
+import java.awt.event.ActionEvent;
+import java.util.Set;
+
+import javax.swing.AbstractAction;
+
+import org.apache.taverna.lang.observer.Observable;
+import org.apache.taverna.lang.observer.Observer;
+import org.apache.taverna.lang.observer.SwingAwareObserver;
+import org.apache.taverna.ui.menu.DesignOnlyAction;
+import org.apache.taverna.workbench.design.actions.EditDataflowInputPortAction;
+import 
org.apache.taverna.workbench.design.actions.EditDataflowOutputPortAction;
+import org.apache.taverna.workbench.design.actions.RenameProcessorAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.icons.WorkbenchIcons;
+import org.apache.taverna.workbench.selection.DataflowSelectionModel;
+import org.apache.taverna.workbench.selection.SelectionManager;
+import org.apache.taverna.workbench.selection.events.DataflowSelectionMessage;
+import org.apache.taverna.workbench.selection.events.SelectionManagerEvent;
+import 
org.apache.taverna.workbench.selection.events.WorkflowBundleSelectionEvent;
+import org.apache.taverna.scufl2.api.container.WorkflowBundle;
+import org.apache.taverna.scufl2.api.core.Processor;
+import org.apache.taverna.scufl2.api.port.InputWorkflowPort;
+import org.apache.taverna.scufl2.api.port.OutputWorkflowPort;
+
+/**
+ * An action that allows user to rename workflow input, output or
+ * processor, in case one of these is currently selected in the Graph View.
+ *
+ * @author Alex Nenadic
+ */
+@SuppressWarnings("serial")
+public class RenameWFInputOutputProcessorAction extends AbstractAction 
implements DesignOnlyAction {
+       /** Current workflow's selection model event observer.*/
+       private Observer<DataflowSelectionMessage> workflowSelectionObserver = 
new DataflowSelectionObserver();
+
+       private final EditManager editManager;
+       private final SelectionManager selectionManager;
+
+       public RenameWFInputOutputProcessorAction(EditManager editManager,
+                       final SelectionManager selectionManager) {
+               super();
+               this.editManager = editManager;
+               this.selectionManager = selectionManager;
+               putValue(SMALL_ICON, WorkbenchIcons.renameIcon);
+               putValue(NAME, "Rename");
+               putValue(SHORT_DESCRIPTION, "Rename inputs, outputs or 
services");
+               putValue(ACCELERATOR_KEY, getKeyStroke(VK_F2, 0));
+               setEnabled(false);
+
+               selectionManager.addObserver(new SelectionManagerObserver());
+       }
+
+       @Override
+       public void actionPerformed(ActionEvent e) {
+               WorkflowBundle workflowBundle = selectionManager
+                               .getSelectedWorkflowBundle();
+               DataflowSelectionModel dataFlowSelectionModel = selectionManager
+                               .getDataflowSelectionModel(workflowBundle);
+               // Get selected port
+               Set<Object> selectedWFComponents = dataFlowSelectionModel
+                               .getSelection();
+               if (selectedWFComponents.size() > 1) {
+                       showMessageDialog(
+                                       null,
+                                       "Only one workflow component should be 
selected for this action.",
+                                       "Warning", WARNING_MESSAGE);
+               } else {
+                       Object selectedWFComponent = 
selectedWFComponents.toArray()[0];
+                       if (selectedWFComponent instanceof InputWorkflowPort) {
+                               InputWorkflowPort port = (InputWorkflowPort) 
selectedWFComponent;
+                               new 
EditDataflowInputPortAction(port.getParent(), port, null,
+                                               editManager, 
selectionManager).actionPerformed(e);
+                       } else if (selectedWFComponent instanceof 
OutputWorkflowPort) {
+                               OutputWorkflowPort port = (OutputWorkflowPort) 
selectedWFComponent;
+                               new 
EditDataflowOutputPortAction(port.getParent(), port, null,
+                                               editManager, 
selectionManager).actionPerformed(e);
+                       } else if (selectedWFComponent instanceof Processor) {
+                               Processor processor = (Processor) 
selectedWFComponent;
+                               new 
RenameProcessorAction(processor.getParent(), processor,
+                                               null, editManager, 
selectionManager).actionPerformed(e);
+                       } else { // should not happen as the button will be 
disabled otherwise, but ...
+                               showMessageDialog(
+                                               null,
+                                               "This action does not apply for 
the selected component.",
+                                               "Warning", WARNING_MESSAGE);
+                       }
+               }
+       }
+
+       /**
+        * Check if action should be enabled or disabled and update its status.
+        */
+       public void updateStatus() {
+               WorkflowBundle workflowBundle = selectionManager
+                               .getSelectedWorkflowBundle();
+               DataflowSelectionModel selectionModel = selectionManager
+                               .getDataflowSelectionModel(workflowBundle);
+
+               // List of all selected objects in the graph view
+               Set<Object> selection = selectionModel.getSelection();
+
+               if (!selection.isEmpty()) {
+                       // Take the first selected item - we only support 
single selections anyway
+                       Object selected = selection.toArray()[0];
+                       if ((selected instanceof Processor)
+                                       || (selected instanceof 
InputWorkflowPort)
+                                       || (selected instanceof 
OutputWorkflowPort)) {
+                               setEnabled(true);
+                               return;
+                       }
+               }
+               setEnabled(false);
+       }
+
+       /**
+        * Observes events on workflow Selection Manager, i.e. when a workflow 
node
+        * is selected in the graph view, and enables/disables this action
+        * accordingly.
+        */
+       private final class DataflowSelectionObserver extends
+                       SwingAwareObserver<DataflowSelectionMessage> {
+               @Override
+               public void notifySwing(Observable<DataflowSelectionMessage> 
sender,
+                               DataflowSelectionMessage message) {
+                       updateStatus();
+               }
+       }
+
+       private final class SelectionManagerObserver extends
+                       SwingAwareObserver<SelectionManagerEvent> {
+               @Override
+               public void notifySwing(Observable<SelectionManagerEvent> 
sender,
+                               SelectionManagerEvent message) {
+                       if (!(message instanceof WorkflowBundleSelectionEvent))
+                               return;
+                       WorkflowBundleSelectionEvent 
workflowBundleSelectionEvent = (WorkflowBundleSelectionEvent) message;
+                       WorkflowBundle oldFlow = workflowBundleSelectionEvent
+                                       .getPreviouslySelectedWorkflowBundle();
+                       WorkflowBundle newFlow = workflowBundleSelectionEvent
+                                       .getSelectedWorkflowBundle();
+                       // Update the buttons status as current dataflow has 
changed
+                       updateStatus();
+
+                       /*
+                        * Remove the workflow selection model listener from 
the previous
+                        * (if any) and add to the new workflow (if any)
+                        */
+                       if (oldFlow != null)
+                               
selectionManager.getDataflowSelectionModel(oldFlow)
+                                               
.removeObserver(workflowSelectionObserver);
+
+                       if (newFlow != null)
+                               
selectionManager.getDataflowSelectionModel(newFlow)
+                                               
.addObserver(workflowSelectionObserver);
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/config/GraphViewConfiguration.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/config/GraphViewConfiguration.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/config/GraphViewConfiguration.java
new file mode 100644
index 0000000..1b03c58
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/config/GraphViewConfiguration.java
@@ -0,0 +1,79 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph.config;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import uk.org.taverna.configuration.AbstractConfigurable;
+import uk.org.taverna.configuration.ConfigurationManager;
+
+import org.apache.taverna.workbench.models.graph.Graph.Alignment;
+import org.apache.taverna.workbench.models.graph.GraphController.PortStyle;
+
+/**
+ * Configuration for the GraphViewComponent.
+ * 
+ * @author David Withers
+ */
+public class GraphViewConfiguration extends AbstractConfigurable {
+       public static final String PORT_STYLE = "portStyle";
+       public static final String ALIGNMENT = "alignment";
+       public static final String ANIMATION_ENABLED = "animationEnabled";
+       public static final String ANIMATION_SPEED = "animationSpeed";
+
+       private Map<String, String> defaultPropertyMap;
+
+       public GraphViewConfiguration(ConfigurationManager 
configurationManager) {
+               super(configurationManager);
+       }
+
+       @Override
+       public String getCategory() {
+               return "general";
+       }
+
+       @Override
+       public Map<String, String> getDefaultPropertyMap() {
+               if (defaultPropertyMap == null) {
+                       defaultPropertyMap = new HashMap<>();
+                       defaultPropertyMap.put(PORT_STYLE, 
PortStyle.NONE.toString());
+                       defaultPropertyMap.put(ALIGNMENT, 
Alignment.VERTICAL.toString());
+                       defaultPropertyMap.put(ANIMATION_ENABLED, "false");
+                       defaultPropertyMap.put(ANIMATION_SPEED, "800");
+               }
+               return defaultPropertyMap;
+       }
+
+       @Override
+       public String getDisplayName() {
+               return "Diagram";
+       }
+
+       @Override
+       public String getFilePrefix() {
+               return "Diagram";
+       }
+
+       @Override
+       public String getUUID() {
+               return "3686BA31-449F-4147-A8AC-0C3F63AFC68F";
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/config/GraphViewConfigurationPanel.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/config/GraphViewConfigurationPanel.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/config/GraphViewConfigurationPanel.java
new file mode 100644
index 0000000..3e24645
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/config/GraphViewConfigurationPanel.java
@@ -0,0 +1,359 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph.config;
+
+import static java.awt.GridBagConstraints.HORIZONTAL;
+import static java.awt.GridBagConstraints.NORTHWEST;
+import static java.awt.GridBagConstraints.RELATIVE;
+import static java.awt.GridBagConstraints.REMAINDER;
+import static java.awt.GridBagConstraints.WEST;
+import static javax.swing.SwingConstants.LEFT;
+import static org.apache.taverna.workbench.helper.Helper.showHelp;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.allportIcon;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.blobIcon;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.horizontalIcon;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.noportIcon;
+import static org.apache.taverna.workbench.icons.WorkbenchIcons.verticalIcon;
+import static 
org.apache.taverna.workbench.views.graph.config.GraphViewConfiguration.ALIGNMENT;
+import static 
org.apache.taverna.workbench.views.graph.config.GraphViewConfiguration.ANIMATION_ENABLED;
+import static 
org.apache.taverna.workbench.views.graph.config.GraphViewConfiguration.ANIMATION_SPEED;
+import static 
org.apache.taverna.workbench.views.graph.config.GraphViewConfiguration.PORT_STYLE;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.Hashtable;
+
+import javax.swing.AbstractAction;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JSlider;
+import javax.swing.JTextArea;
+import javax.swing.border.EmptyBorder;
+
+import org.apache.taverna.workbench.models.graph.Graph.Alignment;
+import org.apache.taverna.workbench.models.graph.GraphController.PortStyle;
+
+/**
+ * UI for GraphViewConfiguration.
+ * 
+ * @author David Withers
+ */
+public class GraphViewConfigurationPanel extends JPanel {
+       private static final long serialVersionUID = 3779779432230124131L;
+       private static final int ANIMATION_SPEED_MIN = 100;
+       private static final int ANIMATION_SPEED_MAX = 3100;
+
+       private GraphViewConfiguration configuration;
+       private JRadioButton noPorts;
+       private JRadioButton allPorts;
+       private JRadioButton blobs;
+       private JRadioButton vertical;
+       private JRadioButton horizontal;
+       private JCheckBox animation;
+       private JLabel animationSpeedLabel;
+       private JSlider animationSpeedSlider;
+
+       public GraphViewConfigurationPanel(GraphViewConfiguration 
configuration) {
+               this.configuration = configuration;
+               GridBagLayout gridbag = new GridBagLayout();
+               GridBagConstraints c = new GridBagConstraints();
+               setLayout(gridbag);
+
+               // Title describing what kind of settings we are configuring 
here
+               JTextArea descriptionText = new JTextArea(
+                               "Default settings for the workflow diagram");
+               descriptionText.setLineWrap(true);
+               descriptionText.setWrapStyleWord(true);
+               descriptionText.setEditable(false);
+               descriptionText.setFocusable(false);
+               descriptionText.setBorder(new EmptyBorder(10, 10, 10, 10));
+
+               JLabel defaultLayoutLabel = new JLabel("Service display");
+
+               noPorts = new JRadioButton();
+               allPorts = new JRadioButton();
+               blobs = new JRadioButton();
+
+               JLabel noPortsLabel = new JLabel("Name only", noportIcon, LEFT);
+               JLabel allPortsLabel = new JLabel("Name and ports", 
allportIcon, LEFT);
+               JLabel blobsLabel = new JLabel("No text", blobIcon, LEFT);
+
+               ButtonGroup buttonGroup = new ButtonGroup();
+               buttonGroup.add(noPorts);
+               buttonGroup.add(allPorts);
+               buttonGroup.add(blobs);
+
+               JLabel defaultAlignmentLabel = new JLabel("Diagram alignment");
+
+               vertical = new JRadioButton();
+               horizontal = new JRadioButton();
+
+               JLabel verticalLabel = new JLabel("Vertical", verticalIcon, 
LEFT);
+               JLabel horizontalLabel = new JLabel("Horizontal", 
horizontalIcon, LEFT);
+
+               ButtonGroup alignmentButtonGroup = new ButtonGroup();
+               alignmentButtonGroup.add(horizontal);
+               alignmentButtonGroup.add(vertical);
+
+               animation = new JCheckBox("Enable animation");
+
+               animationSpeedLabel = new JLabel("Animation speed");
+
+               animationSpeedSlider = new JSlider(ANIMATION_SPEED_MIN,
+                               ANIMATION_SPEED_MAX);
+               animationSpeedSlider.setMajorTickSpacing(500);
+               animationSpeedSlider.setMinorTickSpacing(100);
+               animationSpeedSlider.setPaintTicks(true);
+               animationSpeedSlider.setPaintLabels(true);
+               animationSpeedSlider.setInverted(true);
+               animationSpeedSlider.setSnapToTicks(true);
+
+               Hashtable<Integer, JLabel> labelTable = new Hashtable<>();
+               labelTable.put(new Integer(ANIMATION_SPEED_MIN), new 
JLabel("Fast"));
+               labelTable.put(new Integer(
+                               ((ANIMATION_SPEED_MAX - ANIMATION_SPEED_MIN) / 
2)
+                                               + ANIMATION_SPEED_MIN), new 
JLabel("Medium"));
+               labelTable.put(new Integer(ANIMATION_SPEED_MAX), new 
JLabel("Slow"));
+               animationSpeedSlider.setLabelTable(labelTable);
+
+               animation.addItemListener(new ItemListener() {
+                       @Override
+                       public void itemStateChanged(ItemEvent e) {
+                               boolean animationEnabled = 
animation.isSelected();
+                               
animationSpeedLabel.setEnabled(animationEnabled);
+                               
animationSpeedSlider.setEnabled(animationEnabled);
+                       }
+               });
+
+               // Set current configuration values
+               setFields(configuration);
+
+               c.anchor = WEST;
+               c.gridx = 0;
+               c.gridwidth = REMAINDER;
+               c.weightx = 1d;
+               c.weighty = 0d;
+               c.fill = HORIZONTAL;
+
+               add(descriptionText, c);
+
+               c.insets = new Insets(10, 0, 10, 0);
+               add(defaultLayoutLabel, c);
+
+               c.insets = new Insets(0, 20, 0, 0);
+               c.gridwidth = 1;
+               c.weightx = 0d;
+               add(noPorts, c);
+               c.insets = new Insets(0, 5, 0, 0);
+               c.gridx = RELATIVE;
+               add(noPortsLabel, c);
+
+               c.insets = new Insets(0, 10, 0, 0);
+               add(allPorts, c);
+               c.insets = new Insets(0, 5, 0, 0);
+               add(allPortsLabel, c);
+
+               c.insets = new Insets(0, 10, 0, 0);
+               add(blobs, c);
+               c.insets = new Insets(0, 5, 0, 0);
+               c.gridwidth = REMAINDER;
+               c.weightx = 1d;
+               add(blobsLabel, c);
+
+               // alignment
+               c.insets = new Insets(20, 0, 10, 0);
+               c.gridx = 0;
+               add(defaultAlignmentLabel, c);
+
+               c.insets = new Insets(0, 20, 0, 0);
+               c.gridx = 0;
+               c.gridwidth = 1;
+               c.weightx = 0d;
+               add(vertical, c);
+               c.insets = new Insets(0, 5, 0, 0);
+               c.gridx = RELATIVE;
+               add(verticalLabel, c);
+
+               c.insets = new Insets(0, 10, 0, 0);
+               add(horizontal, c);
+               c.insets = new Insets(0, 5, 0, 0);
+               c.gridwidth = REMAINDER;
+               c.weightx = 1d;
+               add(horizontalLabel, c);
+
+               // animation
+               c.gridx = 0;
+               c.gridwidth = REMAINDER;
+               c.insets = new Insets(20, 0, 10, 0);
+               add(animation, c);
+
+               c.insets = new Insets(0, 20, 0, 0);
+               add(animationSpeedLabel, c);
+
+               c.insets = new Insets(0, 20, 10, 30);
+               c.anchor = NORTHWEST;
+               c.weighty = 0d;
+               add(animationSpeedSlider, c);
+
+               // Buttons
+               c.gridx = 0;
+               c.insets = new Insets(0, 20, 10, 30);
+               c.anchor = NORTHWEST;
+               c.weighty = 1d;
+               add(createButtonPanel(), c);
+       }
+
+       /**
+        * Create the panel with the buttons.
+        */
+       @SuppressWarnings("serial")
+       private JPanel createButtonPanel() {
+               final JPanel panel = new JPanel();
+
+               /**
+                * The helpButton shows help about the current component
+                */
+               JButton helpButton = new JButton(new AbstractAction("Help") {
+                       @Override
+                       public void actionPerformed(ActionEvent arg0) {
+                               showHelp(panel);
+                       }
+               });
+               panel.add(helpButton);
+
+               /**
+                * The resetButton changes the property values shown to those
+                * corresponding to the configuration currently applied.
+                */
+               JButton resetButton = new JButton(new AbstractAction("Reset") {
+                       @Override
+                       public void actionPerformed(ActionEvent arg0) {
+                               setFields(configuration);
+                       }
+               });
+               panel.add(resetButton);
+
+               /**
+                * The applyButton applies the shown field values to the
+                * {@link HttpProxyConfiguration} and saves them for future.
+                */
+               JButton applyButton = new JButton(new AbstractAction("Apply") {
+                       @Override
+                       public void actionPerformed(ActionEvent arg0) {
+                               applySettings();
+                               setFields(configuration);
+                       }
+               });
+               panel.add(applyButton);
+
+               return panel;
+       }
+
+       /**
+        * Save the currently set field values to the {@link 
GraphViewConfiguration}
+        * . Also apply those values to the currently running Taverna.
+        */
+       private void applySettings() {
+               // Service display
+               if (noPorts.isSelected()) {
+                       configuration.setProperty(PORT_STYLE, 
PortStyle.NONE.toString());
+               } else if (allPorts.isSelected()) {
+                       configuration.setProperty(PORT_STYLE, 
PortStyle.ALL.toString());
+               } else if (blobs.isSelected()) {
+                       configuration.setProperty(PORT_STYLE, 
PortStyle.BLOB.toString());
+               }
+
+               // Diagram alignment
+               if (vertical.isSelected()) {
+                       configuration.setProperty(ALIGNMENT, 
Alignment.VERTICAL.toString());
+               } else if (horizontal.isSelected()) {
+                       configuration.setProperty(ALIGNMENT,
+                                       Alignment.HORIZONTAL.toString());
+               }
+
+               // Animation and its speed
+               if (animation.isSelected()) {
+                       configuration.setProperty(ANIMATION_ENABLED, 
String.valueOf(true));
+               } else {
+                       configuration.setProperty(ANIMATION_ENABLED, 
String.valueOf(false));
+               }
+               int speed = animationSpeedSlider.getValue();
+               configuration.setProperty(ANIMATION_SPEED, 
String.valueOf(speed));
+       }
+
+       /**
+        * Set the shown configuration field values to those currently in use 
(i.e.
+        * last saved configuration).
+        */
+       private void setFields(GraphViewConfiguration configurable) {
+               PortStyle portStyle = PortStyle.valueOf(configurable
+                               .getProperty(PORT_STYLE));
+               if (portStyle.equals(PortStyle.NONE)) {
+                       noPorts.setSelected(true);
+               } else if (portStyle.equals(PortStyle.ALL)) {
+                       allPorts.setSelected(true);
+               } else {
+                       blobs.setSelected(true);
+               }
+
+               Alignment alignment = Alignment.valueOf(configurable
+                               .getProperty(ALIGNMENT));
+               if (alignment.equals(Alignment.VERTICAL)) {
+                       vertical.setSelected(true);
+               } else {
+                       horizontal.setSelected(true);
+               }
+
+               boolean animationEnabled = Boolean.parseBoolean(configurable
+                               .getProperty(ANIMATION_ENABLED));
+               animation.setSelected(animationEnabled);
+
+               Integer animationSpeed = Integer.valueOf(configurable
+                               .getProperty(ANIMATION_SPEED));
+               if (animationSpeed > ANIMATION_SPEED_MAX) {
+                       animationSpeed = ANIMATION_SPEED_MAX;
+               } else if (animationSpeed < ANIMATION_SPEED_MIN) {
+                       animationSpeed = ANIMATION_SPEED_MIN;
+               }
+               animationSpeedSlider.setValue(animationSpeed);
+               animationSpeedSlider.setEnabled(animationEnabled);
+
+               animationSpeedLabel.setEnabled(animationEnabled);
+       }
+
+       // for testing only
+       public static void main(String[] args) {
+               JDialog dialog = new JDialog();
+               dialog.add(new GraphViewConfigurationPanel(null));
+               dialog.setModal(true);
+               dialog.setSize(500, 400);
+               dialog.setVisible(true);
+               System.exit(0);
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/config/GraphViewConfigurationUIFactory.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/config/GraphViewConfigurationUIFactory.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/config/GraphViewConfigurationUIFactory.java
new file mode 100644
index 0000000..770b79c
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/config/GraphViewConfigurationUIFactory.java
@@ -0,0 +1,54 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph.config;
+
+import javax.swing.JPanel;
+
+import uk.org.taverna.configuration.Configurable;
+import uk.org.taverna.configuration.ConfigurationUIFactory;
+
+/**
+ * ConfigurationFactory for the GraphViewConfiguration.
+ * 
+ * @author David Withers
+ */
+public class GraphViewConfigurationUIFactory implements ConfigurationUIFactory 
{
+       private GraphViewConfiguration graphViewConfiguration;
+
+       @Override
+       public boolean canHandle(String uuid) {
+               return uuid.equals(getConfigurable().getUUID());
+       }
+
+       @Override
+       public JPanel getConfigurationPanel() {
+               return new GraphViewConfigurationPanel(graphViewConfiguration);
+       }
+
+       @Override
+       public Configurable getConfigurable() {
+               return graphViewConfiguration;
+       }
+
+       public void setGraphViewConfiguration(
+                       GraphViewConfiguration graphViewConfiguration) {
+               this.graphViewConfiguration = graphViewConfiguration;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/AddWFInputMenuAction.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/AddWFInputMenuAction.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/AddWFInputMenuAction.java
new file mode 100644
index 0000000..cad5986
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/AddWFInputMenuAction.java
@@ -0,0 +1,59 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph.menu;
+
+import static org.apache.taverna.workbench.views.graph.menu.InsertMenu.INSERT;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.selection.SelectionManager;
+import org.apache.taverna.workbench.views.graph.actions.AddWFInputAction;
+
+/**
+ * @author Alex Nenadic
+ */
+public class AddWFInputMenuAction extends AbstractMenuAction {
+       private static final URI ADD_WF_INPUT_URI = URI
+                       
.create("http://taverna.sf.net/2008/t2workbench/menu#graphMenuAddWFInput";);
+
+       private EditManager editManager;
+       private SelectionManager selectionManager;
+
+       public AddWFInputMenuAction() {
+               super(INSERT, 10, ADD_WF_INPUT_URI);
+       }
+
+       @Override
+       protected Action createAction() {
+               return new AddWFInputAction(editManager, selectionManager);
+       }
+
+       public void setEditManager(EditManager editManager) {
+               this.editManager = editManager;
+       }
+
+       public void setSelectionManager(SelectionManager selectionManager) {
+               this.selectionManager = selectionManager;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/AddWFOutputMenuAction.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/AddWFOutputMenuAction.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/AddWFOutputMenuAction.java
new file mode 100644
index 0000000..1aeb495
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/AddWFOutputMenuAction.java
@@ -0,0 +1,59 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph.menu;
+
+import static org.apache.taverna.workbench.views.graph.menu.InsertMenu.INSERT;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.selection.SelectionManager;
+import org.apache.taverna.workbench.views.graph.actions.AddWFOutputAction;
+
+/**
+ * @author Alex Nenadic
+ */
+public class AddWFOutputMenuAction extends AbstractMenuAction {
+       private static final URI ADD_WF_OUTPUT_URI = URI
+                       
.create("http://taverna.sf.net/2008/t2workbench/menu#graphMenuAddWFOutput";);
+
+       private EditManager editManager;
+       private SelectionManager selectionManager;
+
+       public AddWFOutputMenuAction() {
+               super(INSERT, 20, ADD_WF_OUTPUT_URI);
+       }
+
+       @Override
+       protected Action createAction() {
+               return new AddWFOutputAction(editManager, selectionManager);
+       }
+
+       public void setEditManager(EditManager editManager) {
+               this.editManager = editManager;
+       }
+
+       public void setSelectionManager(SelectionManager selectionManager) {
+               this.selectionManager = selectionManager;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/DeleteGraphComponentMenuAction.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/DeleteGraphComponentMenuAction.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/DeleteGraphComponentMenuAction.java
new file mode 100644
index 0000000..243350e
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/DeleteGraphComponentMenuAction.java
@@ -0,0 +1,60 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph.menu;
+
+import static 
org.apache.taverna.workbench.views.graph.menu.GraphDeleteMenuSection.GRAPH_DELETE_MENU_SECTION;
+
+import java.net.URI;
+
+import javax.swing.Action;
+
+import org.apache.taverna.ui.menu.AbstractMenuAction;
+import org.apache.taverna.workbench.edits.EditManager;
+import org.apache.taverna.workbench.selection.SelectionManager;
+import 
org.apache.taverna.workbench.views.graph.actions.DeleteGraphComponentAction;
+
+/**
+ * @author Alex Nenadic
+ * @author Alan R Williams
+ */
+public class DeleteGraphComponentMenuAction extends AbstractMenuAction {
+       private static final URI DELETE_GRAPH_COMPONENT_URI = URI
+                       
.create("http://taverna.sf.net/2008/t2workbench/menu#graphMenuDeleteGraphComponent";);
+
+       private EditManager editManager;
+       private SelectionManager selectionManager;
+
+       public DeleteGraphComponentMenuAction() {
+               super(GRAPH_DELETE_MENU_SECTION, 10, 
DELETE_GRAPH_COMPONENT_URI);
+       }
+
+       @Override
+       protected Action createAction() {
+               return new DeleteGraphComponentAction(editManager, 
selectionManager);
+       }
+
+       public void setEditManager(EditManager editManager) {
+               this.editManager = editManager;
+       }
+
+       public void setSelectionManager(SelectionManager selectionManager) {
+               this.selectionManager = selectionManager;
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-taverna-workbench/blob/bf8a7ea2/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/DiagramMenu.java
----------------------------------------------------------------------
diff --git 
a/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/DiagramMenu.java
 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/DiagramMenu.java
new file mode 100644
index 0000000..0b1497b
--- /dev/null
+++ 
b/taverna-graph-view/src/main/java/org/apache/taverna/workbench/views/graph/menu/DiagramMenu.java
@@ -0,0 +1,43 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+
+package org.apache.taverna.workbench.views.graph.menu;
+
+import static java.awt.event.KeyEvent.VK_V;
+import static javax.swing.Action.MNEMONIC_KEY;
+import static org.apache.taverna.ui.menu.DefaultMenuBar.DEFAULT_MENU_BAR;
+
+import java.net.URI;
+
+import org.apache.taverna.ui.menu.AbstractMenu;
+
+public class DiagramMenu extends AbstractMenu {
+       public static final URI DIAGRAM = URI
+                       
.create("http://taverna.sf.net/2008/t2workbench/menu#diagram";);
+
+       public DiagramMenu() {
+               super(DEFAULT_MENU_BAR, 65, DIAGRAM, "View");
+       }
+
+       public static DummyAction makeAction() {
+               DummyAction action = new DummyAction("View");
+               action.putValue(MNEMONIC_KEY, VK_V);
+               return action;
+       }
+}

Reply via email to