Java tutorial
/* * The University of Wales, Cardiff Triana Project Software License (Based * on the Apache Software License Version 1.1) * * Copyright (c) 2007 University of Wales, Cardiff. All rights reserved. * * Redistribution and use of the software in source and binary forms, with * or without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. The end-user documentation included with the redistribution, if any, * must include the following acknowledgment: "This product includes * software developed by the University of Wales, Cardiff for the Triana * Project (http://www.trianacode.org)." Alternately, this * acknowledgment may appear in the software itself, if and wherever * such third-party acknowledgments normally appear. * * 4. The names "Triana" and "University of Wales, Cardiff" must not be * used to endorse or promote products derived from this software * without prior written permission. For written permission, please * contact triana@trianacode.org. * * 5. Products derived from this software may not be called "Triana," nor * may Triana appear in their name, without prior written permission of * the University of Wales, Cardiff. * * 6. This software may not be sold, used or incorporated into any product * for sale to third parties. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL UNIVERSITY OF WALES, CARDIFF OR ITS CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * * ------------------------------------------------------------------------ * * This software consists of voluntary contributions made by many * individuals on behalf of the Triana Project. For more information on the * Triana Project, please see. http://www.trianacode.org. * * This license is based on the BSD license as adopted by the Apache * Foundation and is governed by the laws of England and Wales. * */ package org.trianacode.gui.hci; import org.apache.commons.logging.Log; import org.trianacode.TrianaInstance; import org.trianacode.TrianaInstanceProgressListener; import org.trianacode.config.Locations; import org.trianacode.config.cl.ArgumentParser; import org.trianacode.config.cl.TrianaOptions; import org.trianacode.enactment.addon.CLIaddon; import org.trianacode.enactment.logging.Loggers; import org.trianacode.gui.action.*; import org.trianacode.gui.action.clipboard.CopyAction; import org.trianacode.gui.action.clipboard.CutAction; import org.trianacode.gui.action.clipboard.PasteAction; import org.trianacode.gui.action.files.*; import org.trianacode.gui.action.taskgraph.*; import org.trianacode.gui.action.tools.*; import org.trianacode.gui.components.hidden.HiddenComponentModel; import org.trianacode.gui.components.map.MapComponentModel; import org.trianacode.gui.components.map.MapLocationComponentModel; import org.trianacode.gui.components.script.ScriptColorModel; import org.trianacode.gui.components.script.ScriptComponentModel; import org.trianacode.gui.components.text.TextToolComponentModel; import org.trianacode.gui.components.triana.TrianaColorModel; import org.trianacode.gui.components.triana.TrianaComponentModel; import org.trianacode.gui.desktop.DesktopView; import org.trianacode.gui.desktop.DesktopViewController; import org.trianacode.gui.desktop.DesktopViewListener; import org.trianacode.gui.desktop.DesktopViewManager; import org.trianacode.gui.extensions.*; import org.trianacode.gui.hci.color.ColorManager; import org.trianacode.gui.hci.color.ColorTable; import org.trianacode.gui.hci.color.RegisterableColorModel; import org.trianacode.gui.hci.tools.*; import org.trianacode.gui.main.TaskGraphPanel; import org.trianacode.gui.panels.MsgBoxErrorListener; import org.trianacode.gui.panels.ParameterPanelManager; import org.trianacode.gui.service.LocalServer; import org.trianacode.gui.service.WorkflowActionManager; import org.trianacode.gui.util.Env; import org.trianacode.gui.windows.ErrorDialog; import org.trianacode.gui.windows.SplashScreen; import org.trianacode.gui.windows.TrianaWindow; import org.trianacode.taskgraph.Task; import org.trianacode.taskgraph.TaskException; import org.trianacode.taskgraph.TaskGraph; import org.trianacode.taskgraph.TaskGraphManager; import org.trianacode.taskgraph.constants.HiddenToolConstants; import org.trianacode.taskgraph.constants.MapConstants; import org.trianacode.taskgraph.constants.ScriptConstants; import org.trianacode.taskgraph.constants.TextToolConstants; import org.trianacode.taskgraph.event.*; import org.trianacode.taskgraph.ser.XMLReader; import org.trianacode.taskgraph.service.LocalDeployAssistant; import org.trianacode.taskgraph.service.TrianaClient; import org.trianacode.taskgraph.tool.Tool; import org.trianacode.taskgraph.tool.ToolTable; import javax.swing.*; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.plaf.FontUIResource; import javax.swing.plaf.metal.MetalLookAndFeel; import javax.swing.plaf.metal.OceanTheme; import javax.swing.tree.TreePath; import java.awt.*; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.io.File; import java.io.FileReader; import java.util.*; import java.util.List; /** * @author Mathew Shields & Ian Taylor * @version $Revision: 4051 $ */ public class ApplicationFrame extends TrianaWindow implements TaskListener, TaskGraphListener, ToolSelectionHandler, SelectionManager, TreeModelListener, ComponentListener, LocalDeployAssistant, FocusListener, TrianaInstanceProgressListener, DesktopViewListener { private static Log log = Loggers.LOGGER; /** * tool tip delays */ private static int TOOL_TIP_SHOW_DELAY = ToolTipManager.sharedInstance().getInitialDelay(); private static int TOOL_TIP_HIDE_DELAY = Integer.MAX_VALUE; /** * the current loaded tools */ private ToolTable tools; /** * The manager responsible for instantiating parameter panels */ private ParameterPanelManager panelmanager = new ParameterPanelManager(); /** * a hashtable of the Triana Clients for each taskgraph */ private Hashtable clienttable = new Hashtable(); /** * an array list of all the top-level main trianas */ private ArrayList<TaskGraphPanel> parents = new ArrayList<TaskGraphPanel>(); /** * the main workspace containing the tools panel and the main trianas */ private Container workspace = new JPanel(new BorderLayout()); /** * The leaf listener that handles all mouse events on desktop panes. */ private LeafListener leaflistener; // a lookup table for MainTriana object and their containers //private static Hashtable taskGraphConts = new Hashtable(); private TaskGraphFileHandler taskGraphFileHandler = null; private JTree toolboxTree; /** * a thread that monitors which tools are broken */ private BrokenToolMonitor toolmonitor; /** * the currently selected component (tool tree/main triana) */ private Object selected; TrianaInstance engine; SplashScreen splash = new SplashScreen(); /** * Initialise the application */ public static ApplicationFrame initTriana(String args[]) { // todo: this is crap, use andrew's UI stuff // Andrew Sept 2010: Done - 6 years on... :-) UIDefaults uiDefaults = UIManager.getDefaults(); Object font = ((FontUIResource) uiDefaults.get("TextArea.font")).deriveFont((float) 11); Enumeration enumeration = uiDefaults.keys(); while (enumeration.hasMoreElements()) { Object key = enumeration.nextElement(); if (key.toString().endsWith("font")) { uiDefaults.put(key, font); } } String myOSName = Locations.os(); if (myOSName.equals("windows")) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { } } else { if (!myOSName.equals("osx")) { try { MetalLookAndFeel.setCurrentTheme(new OceanTheme()); UIManager.setLookAndFeel(new MetalLookAndFeel()); } catch (Exception e) { } } } ApplicationFrame app = new ApplicationFrame("Triana"); app.init(args); return app; } /** * Constructor for the ApplicationFrame object */ private ApplicationFrame(String title) { super(title); } public void showCurrentProgress(String progress) { splash.setSplashProgress(progress); } public void setProgressSteps(int stepsInInitialization) { splash.showSplashScreen(stepsInInitialization); } private void init(String args[]) { try { log.info("Initialising"); engine = new TrianaInstance(args); engine.addExtensionClasses(Extension.class, CLIaddon.class, TaskGraphExporterInterface.class, TaskGraphImporterInterface.class, ToolImporterInterface.class, RegisterableToolComponentModel.class, RegisterableColorModel.class); engine.init(this, false); engine.getErrorTracker().addErrorListener(new MsgBoxErrorListener()); tools = engine.getToolTable(); initTools(); initActionTable(); initWorkflowVerifiers(); initMonitors(); initExtensions(); Env.initConfig(true); initLayout(); // init extensions that require some gui stuff to be there first initPostLayoutExtensions(); Env.readStateFiles(); initWindow(super.getTitle()); List<String> workflows = null; if (args.length > 0) { ArgumentParser parser = new ArgumentParser(args); parser.parse(); workflows = TrianaOptions.getOptionValues(parser, TrianaOptions.WORKFLOW_OPTION); } loadTools(workflows); if (workflows == null || workflows.size() == 0) { addParentTaskGraphPanel(); } splash.setSplashProgress(""); splash.hideSplashScreen(); } catch (Exception e) { e.printStackTrace(); } } private void loadTools(final List<String> workflows) { new Thread() { public void run() { engine.resolve(); if (workflows != null) { for (String workflow : workflows) { try { File f = new File(workflow); XMLReader reader = new XMLReader(new FileReader(f)); Tool t = reader.readComponent(engine.getProperties()); if (t instanceof TaskGraph) { addParentTaskGraphPanel((TaskGraph) t); } } catch (Exception e) { log.error(e); } } } } }.start(); } public TrianaInstance getEngine() { return engine; } /** * @return the cuurently loaded tool table */ ToolTable getTools() { return tools; } /** * @return the MenuBar for the main application */ public TrianaMainMenu getTrianaMenuBar() { return (TrianaMainMenu) trianaMenuBar; } /** * @return the handler for opening/saving taskgraphs */ public TaskGraphFileHandler getTaskGraphFileHandler() { return taskGraphFileHandler; } /** * Initialises the main window */ private void initWindow(String title) { setName(title); setSize(Env.getWindowSize()); setLocation(Env.getWindowPosition()); addComponentListener(this); setVisible(true); getTrianaMenuBar().updateRecentMenu(); } /** * Initialise the actions in the ActionTable */ private void initActionTable() { log.debug("Init"); ActionTable.putAction(ActionTable.NEW_ACTION, new NewAction()); ActionTable.putAction(ActionTable.OPEN_ACTION, new OpenAction(this)); ActionTable.putAction(ActionTable.OPEN_FILE_ACTION, new OpenAction(this, OpenAction.FILE_ONLY_MODE)); ActionTable.putAction(ActionTable.SAVE_ACTION, new SaveAction(this, tools)); ActionTable.putAction(ActionTable.SAVE_AS_ACTION, new SaveAsAction(this, tools)); ActionTable.putAction(ActionTable.CLOSE_ACTION, new CloseAction()); ActionTable.putAction(ActionTable.IMPORT_ACTION, new ImportAction()); ActionTable.putAction(ActionTable.EXPORT_ACTION, new ExportAction()); ActionTable.putAction(ActionTable.PRINT_ACTION, new PrintAction(this)); ActionTable.putAction(ActionTable.FIND_ACTION, new FindAction(this)); ActionTable.putAction(ActionTable.HELP_ACTION, new HelpAction(this)); ActionTable.putAction(ActionTable.RENDER_ACTION, new RenderAction(this)); ActionTable.putAction(ActionTable.CUT_ACTION, new CutAction(this)); ActionTable.putAction(ActionTable.COPY_ACTION, new CopyAction(this)); ActionTable.putAction(ActionTable.PASTE_ACTION, new PasteAction(this)); ActionTable.putAction(ActionTable.PASTE_INTO_ACTION, new PasteIntoAction(this, tools)); ActionTable.putAction(ActionTable.DELETE_ACTION, new DeleteAction(this)); ActionTable.putAction(ActionTable.DELETE_REFERENCES_ACTION, new DeleteRefsAction(this)); ActionTable.putAction(ActionTable.RENAME_ACTION, new RenameAction(this)); ActionTable.putAction(ActionTable.PROPERTIES_ACTION, new PropertiesAction(this)); ActionTable.putAction(ActionTable.CONTROL_PROERTIES_ACTION, new ControlPropertiesAction(this)); ActionTable.putAction(ActionTable.NODE_EDITOR_ACTION, new NodeEditorAction(this)); ActionTable.putAction(ActionTable.HISTORY_TRACKING_ACTION, new HistoryTrackingAction(this)); ActionTable.putAction(ActionTable.GROUP_ACTION, new GroupAction(this, tools)); ActionTable.putAction(ActionTable.UNGROUP_ACTION, new UnGroupAction(this)); ActionTable.putAction(ActionTable.SELECT_ALL_ACTION, new SelectAllAction(this)); ActionTable.putAction(ActionTable.CLEAR_ACTION, new ClearAction(this)); ActionTable.putAction(ActionTable.ORGANIZE_ACTION, new OrganizeAction(this)); ActionTable.putAction(ActionTable.ZOOMIN_ACTION, new ZoomAction(this)); ActionTable.putAction(ActionTable.ZOOMOUT_ACTION, new ZoomOutAction(this)); ActionTable.putAction(ActionTable.RUN_ACTION, new RunAction(this)); ActionTable.putAction(ActionTable.PAUSE_ACTION, new PauseAction(this)); ActionTable.putAction(ActionTable.RESET_ACTION, new ResetAction(this)); ActionTable.putAction(ActionTable.COMPILE_ACTION, new CompileAction(this, tools)); ActionTable.putAction(ActionTable.RUN_SCRIPT_ACTION, new RunScriptAction(this, tools)); ActionTable.putAction(ActionTable.DEC_INPUT_NODES_ACTION, new DecInNodeAction(this)); ActionTable.putAction(ActionTable.DEC_OUTPUT_NODES_ACTION, new DecOutNodeAction(this)); ActionTable.putAction(ActionTable.INC_INPUT_NODES_ACTION, new IncInNodeAction(this)); ActionTable.putAction(ActionTable.INC_OUTPUT_NODES_ACTION, new IncOutNodeAction(this)); ActionTable.putAction(ActionTable.ADD_TRIGGER_NODE_ACTION, new AddTriggerAction(this)); ActionTable.putAction(ActionTable.REMOVE_TRIGGER_NODE_ACTION, new RemoveTriggerAction(this)); ActionTable.putAction(ActionTable.TOGGLE_ERROR_NODE_ACTION, new ToggerErrorAction(this)); ActionTable.putAction(Actions.TABBED_DESKTOP_VIEW, new TabbedDesktopAction(this)); ActionTable.putAction(Actions.VIRTUAL_DESKTOP_VIEW, new VirtualDesktopAction(this)); ActionTable.putAction(Actions.EDIT_TOOLBOXES, new EditToolboxesAction(this.tools)); ActionTable.putAction(Actions.OPTIONS, new OptionsAction(this.tools)); ActionTable.putAction(Actions.CREATE_IMAGE, new ImageAction()); ActionTable.putAction(Actions.SAVE_AS_FILE, new SaveAsFileAction(this, tools)); } /** * Initialise the actions in the ActionTable */ private void initWorkflowVerifiers() { log.debug("Init"); WorkflowActionManager.registerWorkflowAction(new TrianaWorkflowVerifier()); //WorkflowActionManager.registerWorkflowAction(new ProtoServiceWorkflowVerifier()); } /** * Initialise the application monitors */ private void initMonitors() { log.debug("Init"); //new ServicesMonitor(); } /** * Discover and initialize the extension classes and populate the extension manager */ private void initExtensions() { Set<Object> en = engine.getExtensions(Extension.class); // System.out.println("Extensions : " + Arrays.toString(en.toArray())); for (Object o : en) { Extension e = (Extension) o; e.init(this); ExtensionManager.registerExtension(e); } en = engine.getExtensions(TaskGraphExporterInterface.class); for (Object o : en) { TaskGraphExporterInterface e = (TaskGraphExporterInterface) o; log.debug("**** Found an exporter : " + e.toString()); ImportExportRegistry.addExporter(e); } en = engine.getExtensions(TaskGraphImporterInterface.class); for (Object o : en) { TaskGraphImporterInterface e = (TaskGraphImporterInterface) o; log.debug("**** Found an importer : " + e.toString()); ImportExportRegistry.addImporter(e); } en = engine.getExtensions(ToolImporterInterface.class); for (Object o : en) { ToolImporterInterface e = (ToolImporterInterface) o; ImportExportRegistry.addToolImporter(e); } en = engine.getExtensions(RegisterableColorModel.class); for (Object o : en) { RegisterableColorModel e = (RegisterableColorModel) o; String[] names = e.getRegistrationNames(); for (String name : names) { ColorManager.registerColorModel(name, e); Color c = e.getDefaultColorForRegistrationName(name); if (c != null) { ColorTable.instance().initDefaultColor(e, name, c); } } } } private void initPostLayoutExtensions() { TaskGraphView defaultview = TaskGraphViewManager.getDefaultTaskgraphView(); Set<Object> en = engine.getExtensions(RegisterableToolComponentModel.class); for (Object o : en) { RegisterableToolComponentModel e = (RegisterableToolComponentModel) o; defaultview.registerToolModel(e.getRegistrationString(), e); } } /** * Initialises the panels in the main window */ private void initLayout() { GUIEnv.setApplicationFrame(this); ColorManager.setDefaultColorModel(new TrianaColorModel()); ColorManager.registerColorModel(ScriptConstants.SCRIPT_RENDERING_HINT, new ScriptColorModel()); // do this after all other color loading ColorTable.instance().loadUserPrefs(); TaskGraphView defaultview = new TaskGraphView("Default View"); TrianaComponentModel compmodel = new TrianaComponentModel(tools, this, this); defaultview.setDefaultToolModel(compmodel); defaultview.setDefaultOpenGroupModel(compmodel); defaultview.registerToolModel(ScriptConstants.SCRIPT_RENDERING_HINT, new ScriptComponentModel()); defaultview.registerToolModel(TextToolConstants.TEXT_TOOL_RENDERING_HINT, new TextToolComponentModel()); defaultview.registerToolModel(HiddenToolConstants.HIDDEN_RENDERING_HINT, new HiddenComponentModel()); TaskGraphView mapview = new TaskGraphView("Map View", defaultview); mapview.registerOpenGroupModel(MapConstants.MAP_RENDERING_HINT, new MapComponentModel()); mapview.registerToolModel(MapConstants.MAP_LOCATION_RENDERING_HINT, new MapLocationComponentModel()); TaskGraphViewManager.setDefaultTaskGraphView(defaultview); TaskGraphViewManager.registerTaskGraphView(MapConstants.MAP_RENDERING_HINT, mapview); taskGraphFileHandler = new TaskGraphFileHandler(); trianaMenuBar = new TrianaMainMenu(this, tools); this.setJMenuBar(trianaMenuBar); TrianaShutdownHook shutDownHook = new TrianaShutdownHook(); Runtime.getRuntime().addShutdownHook(shutDownHook); getDesktopViewManager().addDesktopViewListener(this); this.workspace.add(getDesktopViewManager().getWorkspace(), BorderLayout.CENTER); ((TrianaMainMenu) trianaMenuBar).addHelp(); ToolTreeModel treemodel = new ToolTreeModel(tools); toolboxTree = new JTree(treemodel); toolboxTree.addFocusListener(this); toolboxTree.setCellRenderer(new TrianaTreeRenderer()); toolmonitor.setTree(toolboxTree); treemodel.addTreeModelListener(this); ToolTipManager.sharedInstance().registerComponent(toolboxTree); ToolTipManager.sharedInstance().setInitialDelay(TOOL_TIP_SHOW_DELAY); ToolTipManager.sharedInstance().setDismissDelay(TOOL_TIP_HIDE_DELAY); //set up key maps MainTrianaKeyMapFactory keymaps = new MainTrianaKeyMapFactory(this, ActionDisplayOptions.DISPLAY_NAME); InputMap inputMap = keymaps.getInputMap(); inputMap.setParent(this.getRootPane().getInputMap()); this.getRootPane().setInputMap(JComponent.WHEN_FOCUSED, inputMap); ActionMap actMap = keymaps.getActionMap(); actMap.setParent(this.getRootPane().getActionMap()); this.getRootPane().setActionMap(actMap); leaflistener = new LeafListener(toolboxTree, this, tools); keymaps = new MainTrianaKeyMapFactory(leaflistener, ActionDisplayOptions.DISPLAY_NAME); inputMap = keymaps.getInputMap(); inputMap.setParent(toolboxTree.getInputMap()); toolboxTree.setInputMap(JComponent.WHEN_FOCUSED, inputMap); actMap = keymaps.getActionMap(); actMap.setParent(toolboxTree.getActionMap()); toolboxTree.setActionMap(actMap); toolboxTree.addMouseListener(leaflistener); toolboxTree.addMouseMotionListener(leaflistener); //toolboxTree.setRootVisible(false); JPanel toolPanel = new JPanel(new BorderLayout()); SearchToolBar searchtoolbar = new SearchToolBar("Search", toolboxTree, treemodel); searchtoolbar.setFloatable(false); toolPanel.add(searchtoolbar, BorderLayout.NORTH); JScrollPane scroll = new JScrollPane(toolboxTree); toolPanel.add(scroll, BorderLayout.CENTER); JSplitPane verticalSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, toolPanel, workspace); TrianaToolBar toolbar = new TrianaToolBar("Main ToolBar", this); TrianaUnitToolBar unitToolbar = new TrianaUnitToolBar("Unit ToolBar"); toolbar.setRollover(true); unitToolbar.setRollover(true); JPanel innerpanel = new JPanel(); innerpanel.setLayout(new BoxLayout(innerpanel, BoxLayout.X_AXIS)); innerpanel.add(toolbar); innerpanel.add(Box.createHorizontalStrut(10)); innerpanel.add(unitToolbar); innerpanel.add(Box.createHorizontalGlue()); JPanel outerpanel = new JPanel(new BorderLayout()); outerpanel.add(innerpanel, BorderLayout.NORTH); outerpanel.add(verticalSplit, BorderLayout.CENTER); getContentPane().add(outerpanel); } /** * Initialises the tool table */ public void initTools() { log.debug("Init"); toolmonitor = new BrokenToolMonitor(tools); toolmonitor.start(); /* TODO ServiceManager.registerImporter(new WSServiceImporter(tools)); ServiceManager.registerDeployer(new GAPServiceDeployer(GAPPeerTypes.WEB_SERVICES, tools, new WSDeployAssistant(), this)); ServiceManager.registerImporter(new P2PSServiceImporter(tools)); ServiceManager.registerDeployer(new GAPServiceDeployer(GAPPeerTypes.P2PS, tools, new P2PSDeployAssistant(), this)); */ } /** * Adds a listener to be notified when the tool selection changes */ public void addToolSelectionListener(ToolSelectionListener listener) { } /** * Removes a listener from being notified when the tool selection changes */ public void removeToolSelectionListener(ToolSelectionListener listener) { } /** * Close the selected MainTriana window. * <p/> * TODO add checks for saved or not, finalise and tidy up graph etc. */ void closeSelectedWindow() { closeTaskGraphPanel(getDesktopViewManager().getDesktopViewFor(getSelectedTaskGraphPanel())); } /** * Closes the specified main triana and cleans-up the taskgraph if required */ public void closeTaskGraphPanel(DesktopView panel) { disposeTaskGraphPanel(panel); } public DesktopView getDesktopView(TaskGraphPanel panel) { return getDesktopViewManager().getDesktopViewFor(panel); } /** * @return an array all the taskgraph panels that are open within the application */ public TaskGraphPanel[] getTaskGraphPanels() { DesktopView[] views = getDesktopViewManager().getViews(); TaskGraphPanel[] panels = new TaskGraphPanel[views.length]; for (int i = 0; i < views.length; i++) { DesktopView view = views[i]; panels[i] = view.getTaskgraphPanel(); } return panels; } /** * @return an array of all taskgraph panels with no parents */ public TaskGraphPanel[] getRootTaskGraphPanels() { DesktopView[] views = getDesktopViewManager().getViews(); List<TaskGraphPanel> panels = new ArrayList<TaskGraphPanel>(); for (int i = 0; i < views.length; i++) { DesktopView view = views[i]; if (view.getTaskgraphPanel().getTaskGraph().getParent() == null) { panels.add(view.getTaskgraphPanel()); } } return panels.toArray(new TaskGraphPanel[panels.size()]); } /** * @param parent the taskgraph panel to find children for * @return the child taskgraph panels */ public TaskGraphPanel[] getChildTaskGraphPanels(TaskGraphPanel parent) { DesktopView[] views = getDesktopViewManager().getViews(); List<TaskGraphPanel> panels = new ArrayList<TaskGraphPanel>(); for (int i = 0; i < views.length; i++) { DesktopView view = views[i]; if (view.getTaskgraphPanel().getTaskGraph().getParent() == parent.getTaskGraph()) { panels.add(view.getTaskgraphPanel()); } } return panels.toArray(new TaskGraphPanel[panels.size()]); } /** * @return the taskgraph panel which is representing the specified task graph, or null if the task isn't * represented */ public DesktopView getDesktopViewFor(TaskGraph group) { return getDesktopViewManager().getTaskgraphViewFor(group); } public void removeDesktopView(DesktopView view) { getDesktopViewManager().remove(view); } public String getTitle(DesktopView view) { return getDesktopViewManager().getTitle(view); } /** * Add a blank taskgraph panel */ public TaskGraph addParentTaskGraphPanel() { try { return addParentTaskGraphPanel(TaskGraphManager.createTaskGraph()); } catch (TaskException except) { ErrorDialog.show(this, "Error Creating Parent TaskGraph", except); return null; } } /** * Add a taskgraph panel for the specified taskgraph. This method creates a new instance of the specified taskgraph * using the current taskgraph factory * * @return the instance of taskgraph created using the current taskgraph factory */ public TaskGraph addParentTaskGraphPanel(TaskGraph initgraph) { String factoryType = TaskGraphManager.DEFAULT_FACTORY_TYPE; try { return addParentTaskGraphPanel(initgraph, factoryType); } catch (TaskException e) { ErrorDialog.show(this, "Error Rendering TaskGraph: " + initgraph.getToolName(), e); return null; } } public TaskGraph addNoExecParentTaskGraphPanel(TaskGraph initgraph) { String factoryType = TaskGraphManager.NON_RUNNABLE_FACTORY_TYPE; try { return addParentTaskGraphPanel(initgraph, factoryType); } catch (TaskException e) { ErrorDialog.show(this, "Error Rendering TaskGraph: " + initgraph.getToolName(), e); return null; } } private TaskGraph addParentTaskGraphPanel(TaskGraph initgraph, String factoryType) throws TaskException { TaskGraph taskgraph = (TaskGraph) TaskGraphManager.createTask(initgraph, factoryType, false); LocalServer server = new LocalServer(taskgraph); TaskGraphManager.setTrianaServer(taskgraph, server); if ((taskgraph.getToolName() == null) || taskgraph.getToolName().equals("")) { String name = getNextUntitledName(); taskgraph.setToolName(name); } TaskGraphPanel parent = addChildTaskGraphPanel(taskgraph, server); parents.add(parent); return taskgraph; } /** * Add an taskgraph panel for a child taskgraph to the workspace. */ public TaskGraphPanel addChildTaskGraphPanel(final TaskGraph taskgraph, TrianaClient client) { registerTrianaClient(taskgraph, client); final TaskGraphPanel panel = TaskGraphViewManager.getTaskGraphPanel(taskgraph, client); panelmanager.monitorTaskGraph(taskgraph); panel.getContainer().addFocusListener(this); new ToolMouseHandler(panel); panel.init(); panel.getTaskGraph().addTaskGraphListener(this); panel.getTaskGraph().addTaskListener(this); SwingUtilities.invokeLater(new Runnable() { public void run() { DesktopView view = getDesktopViewManager().newDesktopView(panel); selected = panel; } }); return panel; } /** * @return A string for the new window/taskgraph, Untitled1, Untitled2... */ private String getNextUntitledName() { int untitledCount = 1; DesktopView[] views = getDesktopViewManager().getViews(); for (DesktopView view : views) { String name = getDesktopViewManager().getTitle(view); if (name.startsWith("Untitled")) { String numberString = name.substring(8); int number = Integer.parseInt(numberString); if (number + 1 > untitledCount) { untitledCount = number + 1; } } } return "Untitled" + untitledCount; } /** * Registers the specified TrianaClient to handle the specified taskgraph. This is generally called when * addTaskGraphPanel/addParentTaskGraphPanel is called and does not need to be called explicitally. */ public void registerTrianaClient(TaskGraph taskgraph, TrianaClient client) { clienttable.put(taskgraph, client); } /** * Unregisters the TrianaClient for the specified task */ public void unregisterTrianaClient(TaskGraph taskgraph) { clienttable.remove(taskgraph); } /** * @return the TrianaClient for the specified taskgraph (null if none registered) */ public TrianaClient getTrianaClient(TaskGraph taskgraph) { if (clienttable.containsKey(taskgraph)) { return (TrianaClient) clienttable.get(taskgraph); } else { return null; } } /** * Handle the local publish (and view if required) of the specified taskgraph */ public void localDeploy(TaskGraph taskgraph, TrianaClient client) { addChildTaskGraphPanel(taskgraph, client); } /** * Handle the local retract of the specified taskgraph */ public void localRetract(TaskGraph taskgraph) { TaskGraphPanel[] panels = getTaskGraphPanels(); String id = taskgraph.getInstanceID(); for (int count = 0; count < panels.length; count++) { if (id.equals(panels[count].getTaskGraph().getInstanceID())) { cleanUpWindows(panels[count].getTaskGraph()); } } } /** * Gets the helpFile attribute of the ApplicationFrame object * * @return The helpFile value */ public String getHelpFile() { return Env.home() + "help" + File.separator + "index.html"; } /** * Hides of a main triana window and all its sub windows. If the main triana is a parent this also disposes of the * whole taskgraph. */ private void disposeTaskGraphPanel(DesktopView panel) { TaskGraph taskgraph = panel.getTaskgraphPanel().getTaskGraph(); cleanUpWindows(taskgraph); } private void cleanUpWindows(TaskGraph taskgraph) { Task[] tasks = taskgraph.getTasks(false); DesktopView cont; cont = getDesktopViewManager().getTaskgraphViewFor(taskgraph); if (cont != null) { disposeWindow(cont); } for (int count = 0; count < tasks.length; count++) { if (tasks[count] instanceof TaskGraph) { cleanUpWindows((TaskGraph) tasks[count]); } } unregisterTrianaClient(taskgraph); } /** * Cleans up a main triana window */ private void disposeWindow(final DesktopView view) { final TaskListener tasklist = this; final TaskGraphListener tgraphlist = this; SwingUtilities.invokeLater(new Runnable() { public void run() { if (view != null) { TaskGraphPanel comp = view.getTaskgraphPanel(); comp.getTaskGraph().removeTaskGraphListener(tgraphlist); comp.getTaskGraph().removeTaskListener(tasklist); comp.dispose(); if (parents.contains(comp)) { parents.remove(comp); comp.getTaskGraph().dispose(); } } } }); } public DesktopViewManager getDesktopViewManager() { return DesktopViewController.getCurrentView(); } /** * Called when the user wants to close the window. If the window is in another application then the window is just * made invisible, but if it is a stand alone application then a really Quit ? window is given to ask the user if * he/she really wants to quit or not. */ public void cleanUp() { Env.writeConfig(); Env.stopConfigWriters(); TaskGraphPanel[] cont = parents.toArray(new TaskGraphPanel[parents.size()]); for (int count = 0; count < cont.length; count++) { DesktopView tdv = getDesktopViewManager().getDesktopViewFor(cont[count]); closeTaskGraphPanel(tdv); } } /** * @return the current selected MainTriana panel within the main Triana application within e.g. the reference to the * frame within the workspace which has the focus */ public TaskGraphPanel getSelectedTaskGraphPanel() { if (selected instanceof TaskGraphPanel) { return (TaskGraphPanel) selected; } else { return null; } } public DesktopView getSelectedDesktopView() { log.debug("ApplicationFrame.getSelectedDesktopView selected:" + selected); if (selected instanceof TaskGraphPanel) { return getDesktopViewManager().getDesktopViewFor((TaskGraphPanel) selected); } else { return null; } } /** * @return true if only a single tool is selected */ public boolean isSingleSelectedTool() { if ((getSelectionHandler() != this) && (getSelectionHandler() instanceof ToolSelectionHandler)) { return ((ToolSelectionHandler) getSelectionHandler()).isSingleSelectedTool(); } else { return false; } } /** * @return the currently selected tool (null if none selected) */ public Tool getSelectedTool() { if ((getSelectionHandler() != this) && (getSelectionHandler() instanceof ToolSelectionHandler)) { return ((ToolSelectionHandler) getSelectionHandler()).getSelectedTool(); } else { return null; } } /** * @return an array of the currently selected tools */ public Tool[] getSelectedTools() { if ((getSelectionHandler() != this) && (getSelectionHandler() instanceof ToolSelectionHandler)) { return ((ToolSelectionHandler) getSelectionHandler()).getSelectedTools(); } else { return new Tool[0]; } } /** * @return the triana client responsible for the selected tools (null if none) */ public TrianaClient getSelectedTrianaClient() { if ((getSelectionHandler() != this) && (getSelectionHandler() instanceof ToolSelectionHandler)) { return ((ToolSelectionHandler) getSelectionHandler()).getSelectedTrianaClient(); } else { return null; } } /** * @return the currently selected taskgraph (usually parent of selected tool) */ public TaskGraph getSelectedTaskgraph() { if ((getSelectionHandler() != this) && (getSelectionHandler() instanceof ToolSelectionHandler)) { return ((ToolSelectionHandler) getSelectionHandler()).getSelectedTaskgraph(); } else { return null; } } /** * @return The object that is selected for this handler. */ public Object getSelectionHandler() { return selected; } /** * Called when the core options of a task change. */ public void taskPropertyUpdate(TaskPropertyEvent event) { Task task = event.getTask(); TaskGraphPanel[] comps = getTaskGraphPanels(); int count = 0; while ((count < comps.length) && (comps[count].getTaskGraph() != task)) { count++; } if (comps[count].getTaskGraph() == task) { DesktopView view = getDesktopViewManager().getDesktopViewFor(comps[count]); getDesktopViewManager().setTitle(view, comps[count].getTaskGraph().getToolName()); } } /** * Called when the value of a parameter is changed, including when a parameter is removed. */ public void parameterUpdated(ParameterUpdateEvent event) { } /** * Called when a data input node is added. */ public void nodeAdded(TaskNodeEvent event) { } /** * Called before a data input node is removed. */ public void nodeRemoved(TaskNodeEvent event) { } /** * Called before the task is disposed */ public void taskDisposed(TaskDisposedEvent event) { } /** * Called when a new task is created in a taskgraph. */ public void taskCreated(TaskGraphTaskEvent event) { } /** * Called when a task is removed from a taskgraph. Note that this method is called when tasks are removed from a * taskgraph due to being grouped (they are placed in the new groups taskgraph). */ public void taskRemoved(TaskGraphTaskEvent event) { if (event.getTask() instanceof TaskGraph) { DesktopView view = getDesktopViewFor((TaskGraph) event.getTask()); if (view != null) { closeTaskGraphPanel(view); } } } /** * Called when a new connection is made between two tasks. */ public void cableConnected(TaskGraphCableEvent event) { } /** * Called when a connection is reconnected to a different task. */ public void cableReconnected(TaskGraphCableEvent event) { } /** * Called before a connection between two tasks is removed. */ public void cableDisconnected(TaskGraphCableEvent event) { } /** * Called when the control task is connected/disconnected or unstable */ public void controlTaskStateChanged(ControlTaskStateEvent event) { } public void treeNodesChanged(TreeModelEvent event) { } public void treeNodesInserted(TreeModelEvent event) { TreePath path = event.getTreePath(); if (path.getPathCount() >= 2) { toolboxTree.scrollPathToVisible(event.getTreePath()); toolboxTree.getModel().removeTreeModelListener(this); } } public void treeNodesRemoved(TreeModelEvent event) { } public void treeStructureChanged(TreeModelEvent event) { } public void componentHidden(ComponentEvent event) { } public void componentMoved(ComponentEvent event) { if (event.getSource() == this) { Env.setWindowPosition(getLocation()); } } public void componentResized(ComponentEvent event) { if (event.getSource() == this) { Env.setWindowSize(getSize()); } } public void componentShown(ComponentEvent event) { } /** * Invoked when a component gains the keyboard focus. */ public void focusGained(FocusEvent event) { if (event.getSource() == toolboxTree) { selected = leaflistener; } else { selected = event.getSource(); } } /** * Invoked when a component loses the keyboard focus. * ANDREW: IS THIS NEEDED NOW? */ public void focusLost(FocusEvent event) { // required to fix internal frame focus/selection bug if (event.getComponent() instanceof TaskGraphPanel) { DesktopView frame = getDesktopViewManager().getDesktopViewFor((TaskGraphPanel) event.getComponent()); if (frame != null) { getDesktopViewManager().setSelected(frame, false); } } } @Override public void ViewClosing(DesktopView view) { disposeTaskGraphPanel(view); } @Override public void ViewClosed(DesktopView view) { disposeTaskGraphPanel(view); } @Override public void ViewOpened(DesktopView view) { selected = view.getTaskgraphPanel(); } @Override public void desktopChanged(DesktopViewManager manager) { if (workspace.getComponentCount() > 0) { workspace.remove(0); workspace.add(manager.getWorkspace()); workspace.invalidate(); workspace.validate(); workspace.repaint(); } } public void repaintWorkspace() { workspace.repaint(); } private class TrianaShutdownHook extends Thread { /** * If this thread was constructed using a separate <code>Runnable</code> run object, then that * <code>Runnable</code> object's <code>run</code> method is called; otherwise, this method does nothing and * returns. * <p/> * Subclasses of <code>Thread</code> should override this method. * * @see Thread#start() * @see Thread#stop() * @see Thread#Thread(ThreadGroup, Runnable, String) * @see Runnable#run() */ public void run() { cleanUp(); } } }