private JTree createTreeFromWorkflow()

in taverna-workflow-explorer/src/main/java/org/apache/taverna/workbench/ui/workflowexplorer/WorkflowExplorer.java [409:640]


	private JTree createTreeFromWorkflow(final Workflow workflow) {
		// Create a new tree and populate it with the workflow's data
		final JTree tree = new JTree(new WorkflowExplorerTreeModel(workflow));
		tree.setRowHeight(18);
		tree.setLargeModel(true);
		tree.setEditable(false);
		tree.setExpandsSelectedPaths(true);
		tree.setDragEnabled(false);
		tree.setScrollsOnExpand(false);
		tree.setCellRenderer(new WorkflowExplorerTreeCellRenderer(workflow,
				reportManager, activityIconManager));
		// tree.setSelectionModel(new WorkflowExplorerTreeSelectionModel());
		tree.addTreeSelectionListener(new TreeSelectionListener() {
			@Override
			public void valueChanged(TreeSelectionEvent e) {
				TreePath selectionPath = e.getNewLeadSelectionPath();
				if (selectionPath != null) {
					final DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) selectionPath
							.getLastPathComponent();

					DataflowSelectionModel selectionModel = selectionManager
							.getDataflowSelectionModel(workflow.getParent());

					/*
					 * If the node that was clicked on was inputs, outputs,
					 * services, data links, control links or merges in the main
					 * workflow then just make it selected and clear the
					 * selection model (as these are just containers for the
					 * 'real' workflow components).
					 */
					if ((selectedNode.getUserObject() instanceof String)
							&& (selectionPath.getPathCount() == 2)) {
						selectionModel.clearSelection();
						tree.getSelectionModel().setSelectionPath(selectionPath);
					} else {
						/*
						 * a 'real' workflow component or the 'whole' workflow
						 * (i.e. the tree root) was clicked on
						 */

						/*
						 * We want to disable selection of any nested workflow
						 * components (apart from input and output ports in the
						 * wrapping DataflowActivity)
						 */
						TreePath path = getPathForObject(selectedNode
								.getUserObject(), (DefaultMutableTreeNode) tree
								.getModel().getRoot());

						/*
						 * The getPathForObject() method will return null in a
						 * node is inside a nested workflow and should not be
						 * selected
						 */
						if (path == null)
							// Just return
							return;

						/*
						 * Add it to selection model so it is also selected
						 * on the graph as well that listens to the
						 * selection model
						 */
						selectionModel.addSelection(selectedNode.getUserObject());
					}
				}
			}
		});

		tree.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent evt) {
				handleMouseEvent(evt);
			}

			@Override
			public void mouseReleased(MouseEvent evt) {
				handleMouseEvent(evt);
			}

			private void handleMouseEvent(MouseEvent evt) {
				if (!evt.isPopupTrigger())
					return;
				// Discover the tree row that was clicked on
				int selRow = tree.getRowForLocation(evt.getX(), evt.getY());
				if (selRow == -1)
					return;

				// Get the selection path for the row
				TreePath selectionPath = tree.getPathForLocation(evt.getX(),
						evt.getY());
				if (selectionPath == null)
					return;

				// Get the selected node
				final DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) selectionPath
						.getLastPathComponent();

				/*
				 * For both left and right click - add the workflow object to
				 * selection model. This will cause the node to become selected
				 * (from the selection listener's code)
				 */
				DataflowSelectionModel selectionModel = selectionManager
						.getDataflowSelectionModel(workflow.getParent());

				/*
				 * If the node that was clicked on was inputs, outputs,
				 * services, data links, control links or merges in the main
				 * workflow then just make it selected and clear the selection
				 * model (as these are just containers for the 'real' workflow
				 * components).
				 */
				if ((selectedNode.getUserObject() instanceof String)
						&& selectionPath.getPathCount() == 2) {
					selectionModel.clearSelection();
					tree.getSelectionModel().setSelectionPath(selectionPath);

					Object userObject = selectedNode.getUserObject();
					if (userObject.equals(PROCESSORS)) {
						JPopupMenu menu = new JPopupMenu();
						menu.add(new ShadedLabel("Tree", PURPLISH));
						menu.add(new JMenuItem(new AbstractAction("Expand",
								plusIcon) {
							@Override
							public void actionPerformed(ActionEvent evt) {
								expandAscendants(tree, selectedNode);
							}
						}));
						menu.add(new JMenuItem(new AbstractAction("Collapse",
								minusIcon) {
							@Override
							public void actionPerformed(ActionEvent evt) {
								collapseAscendants(tree, selectedNode);
							}
						}));
						menu.show(evt.getComponent(), evt.getX(), evt.getY());
					} else if (userObject.equals(INPUTS)) {
						JPopupMenu menu = new JPopupMenu();
						menu.add(new ShadedLabel("Workflow input ports", GREEN));
						menu.add(new JMenuItem(new AbstractAction(
								"Add workflow input port", inputIcon) {
							@Override
							public void actionPerformed(ActionEvent evt) {
								new AddDataflowInputAction(
										(Workflow) ((DefaultMutableTreeNode) tree
												.getModel().getRoot())
												.getUserObject(), wfTree
												.getParent(), editManager,
										selectionManager).actionPerformed(evt);
							}
						}));
						menu.show(evt.getComponent(), evt.getX(), evt.getY());
					} else if (userObject.equals(OUTPUTS)) {
						JPopupMenu menu = new JPopupMenu();
						menu.add(new ShadedLabel("Workflow output ports", GREEN));
						menu.add(new JMenuItem(new AbstractAction(
								"Add workflow output port", outputIcon) {
							@Override
							public void actionPerformed(ActionEvent evt) {
								new AddDataflowOutputAction(
										(Workflow) ((DefaultMutableTreeNode) tree
												.getModel().getRoot())
												.getUserObject(), wfTree
												.getParent(), editManager,
										selectionManager).actionPerformed(evt);
							}
						}));
						menu.show(evt.getComponent(), evt.getX(), evt.getY());
					}
				} else {
					/*
					 * a 'real' workflow component or the 'whole' workflow (i.e.
					 * the tree root) was clicked on
					 */

					/*
					 * We want to disable selection of any nested workflow
					 * components (apart from input and output ports in the
					 * wrapping DataflowActivity)
					 */
					TreePath path = getPathForObject(
							selectedNode.getUserObject(),
							(DefaultMutableTreeNode) tree.getModel().getRoot());

					/*
					 * The getPathForObject() method will return null in a node
					 * is inside a nested workflow and should not be selected
					 */
					if (path == null)
						// Just return
						return;

					/*
					 * Add it to selection model so it is also selected on the
					 * graph as well that listens to the selection model
					 */
					selectionModel.addSelection(selectedNode.getUserObject());

					// Show a contextual pop-up menu
					JPopupMenu menu = menuManager.createContextMenu(workflow,
							selectedNode.getUserObject(), wfTree.getParent());
					if (menu == null)
						menu = new JPopupMenu();

					if (selectedNode.getUserObject() instanceof Workflow) {
						menu.add(new ShadedLabel("Tree", PURPLISH));
						// Action to expand the whole tree
						menu.add(new JMenuItem(new AbstractAction("Expand all",
								plusIcon) {
							@Override
							public void actionPerformed(ActionEvent evt) {
								expandAll(tree);
							}
						}));
						// Action to collapse the whole tree
						menu.add(new JMenuItem(new AbstractAction(
								"Collapse all", minusIcon) {
							@Override
							public void actionPerformed(ActionEvent evt) {
								collapseAll(tree);
							}
						}));
					}

					menu.show(evt.getComponent(), evt.getX(), evt.getY());
				}
			}
		});

		return tree;
	}