/* -*-Java-*- ******************************************************************************** * * File: CytoscapeEditorManagerSupport.java * RCS: $Header: $ * Description: * Author: Allan Kuchinsky * Created: Sat Jul 30 17:00:27 2005 * Modified: Wed Jul 09 08:35:21 2008 (Michael L. Creech) creech@w235krbza760 * Language: Java * Package: * Status: Experimental (Do Not Distribute) * * (c) Copyright 2006, Agilent Technologies, all rights reserved. * ******************************************************************************** * * Revisions: * * Wed Jul 09 08:34:53 2008 (Michael L. Creech) creech@w235krbza760 * Migrated isEditorInOperation() to CytoscapeEditorManager and changed * references. * Tue Oct 30 10:58:16 2007 (Michael L. Creech) creech@w235krbza760 * Fixed bug in propertyChange() for NETWORK_VIEW_FOCUSED where * palette was being redrawn when the Editor tab wasn't * selected. Added isEditorInOperation(). Changed * updateEditorPalette() to be private. * Thu Oct 25 05:42:55 2007 (Michael L. Creech) creech@w235krbza760 * Changed onComponentSelected() to not generate a bogus CyNetworkView * but the desired CyNetworkView. * Wed May 09 13:59:45 2007 (Michael L. Creech) creech@w235krbza760 * Removed several unneeded imports. * Wed Dec 27 09:04:18 2006 (Michael L. Creech) creech@w235krbza760 * Added getDeleteAction() and parameter to constructor. * Sun Aug 06 11:14:28 2006 (Michael L. Creech) creech@w235krbza760 * Fixed updateEditorPalette() to not assume visualStyleName is the * same as Editor name. * Sat Aug 05 17:01:38 2006 (Michael L. Creech) creech@w235krbza760 * Added some comments. ******************************************************************************** */ package cytoscape.editor.impl; import cytoscape.CyNetwork; import cytoscape.Cytoscape; import cytoscape.editor.CytoscapeEditor; import cytoscape.editor.CytoscapeEditorFactory; import cytoscape.editor.CytoscapeEditorManager; import cytoscape.editor.InvalidEditorException; import cytoscape.logger.CyLogger; import cytoscape.view.CyNetworkView; import cytoscape.view.CytoscapeDesktop; import cytoscape.view.cytopanels.CytoPanelListener; import cytoscape.view.cytopanels.CytoPanelState; import cytoscape.visual.VisualMappingManager; import cytoscape.visual.VisualStyle; import giny.model.GraphPerspectiveChangeEvent; import giny.model.GraphPerspectiveChangeListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.SwingConstants; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /** * provides non-static methods needed by the CytoscapeEditorManager, in * particular those methods associated with the PropertyChangeListener class * * @author Allan Kuchinsky, Agilent Technologies * @version 1.0 * @see CytoscapeEditorManager * */ public class CytoscapeEditorManagerSupport implements PropertyChangeListener, ChangeListener, GraphPerspectiveChangeListener, CytoPanelListener { private CyLogger logger = CyLogger.getLogger(CytoscapeEditorManagerSupport.class); /** * register interest in NETWORK_VIEW_FOCUSED and NETWORK_VIEW_CREATED events * */ /** * Creates a new CytoscapeEditorManagerSupport object. * */ public CytoscapeEditorManagerSupport() { super(); Cytoscape.getDesktop().getSwingPropertyChangeSupport() .addPropertyChangeListener(CytoscapeDesktop.NETWORK_VIEW_FOCUSED, this); Cytoscape.getDesktop().getSwingPropertyChangeSupport() .addPropertyChangeListener(CytoscapeDesktop.NETWORK_VIEW_CREATED, this); Cytoscape.getSwingPropertyChangeSupport().addPropertyChangeListener(this); Cytoscape.getVisualMappingManager().addChangeListener(this); Cytoscape.getDesktop().getCytoPanel(SwingConstants.WEST).addCytoPanelListener(this); new NewEmptyNetworkListener(); } /** * respond to a ChangeEvent, typically this is caused by switching * visual styles */ // implements ChangeListener interface: // TODO: Since this can be frequently called, this code should check // if the current palette already reflects the current visual style before // updateEditorPalette is called. public void stateChanged(ChangeEvent e) { CytoscapeEditorManager.log("Got State change: " + e.toString()); if (!CytoscapeEditorManager.isEditingEnabled()) { return; } // AJK: 06/10/06 BEGIN // don't do any work building editor palette if editor tab is not // selected in CytoPanel // MLC 07/09/08: // if (!isEditorInOperation ()) { // MLC 07/09/08: if (!CytoscapeEditorManager.isEditorInOperation ()) { return; } VisualMappingManager VMM = (VisualMappingManager) e.getSource(); if (VMM != null) { updateEditorPalette(VMM.getVisualStyle()); } } /** * respond to selection of a CytoPanels component, in particular respond to * selection of a tab on the WEST CytoPanel. */ // implements CytoPanelListener interface: public void onComponentSelected(int componentIndex) { // MLC 07/09/08: // if (isEditorInOperation (componentIndex)) { // MLC 07/09/08: if (CytoscapeEditorManager.isEditorInOperation (componentIndex)) { updateEditorPalette(Cytoscape.getVisualMappingManager().getVisualStyle()); // If no networks exist, create an empty network. if ( Cytoscape.getNetworkSet().size() == 0 ) { // MLC 10/24/07 BEGIN: // DON'T call the one argument createNetwork()--it will end up setting // our current visual style to "default" thru CytoscapeDesktop // event listener: // CyNetwork newNet = Cytoscape.createNetwork(CytoscapeEditorManager.createUniqueNetworkName()); // DON'T create a CyNetworkView: CyNetwork newNet = Cytoscape.createNetwork(new int[] { }, new int[] { }, CytoscapeEditorManager.createUniqueNetworkName(), null, false); // CyNetworkView newView = Cytoscape.createNetworkView(newNet); // Now build the right view: CyNetworkView newView = Cytoscape.createNetworkView(newNet, newNet.getTitle(), null, // use the existing visual style: Cytoscape.getVisualMappingManager().getVisualStyle()); // MLC 10/24/07 END. CytoscapeEditorManager.setEditorForView(newView, CytoscapeEditorManager.getCurrentEditor()); // AJK: 10/25/2007 if we have a new view then we need to set it up with event handler CytoscapeEditorManager.setupNewNetworkView(newView); } } } /** * Notifies the listener on a change in the CytoPanel state. * * @param newState * The new CytoPanel state - see CytoPanelState class. */ public void onStateChange(CytoPanelState newState) { } /** * Notifies the listener when a component is added to the CytoPanel. * * @param count * The number of components on the CytoPanel after the add. */ // implements CytoPanelListener interface: public void onComponentAdded(int count) { } /** * Notifies the listener when a component is removed from the CytoPanel. * * @param count * The number of components on the CytoPanel after the remove. */ // implements CytoPanelListener interface: public void onComponentRemoved(int count) { } /** * sets up editor and visual style and builds the ShapePalette * @param style */ // public void updateEditorPalette(VisualStyle style) { private void updateEditorPalette(VisualStyle style) { // AJK: 06/16/06 only update palette after CYTOSCAPE_INITIALIZED CytoscapeEditorManager.log("setting up editor for visual style: " + style); if (!CytoscapeEditorManager.isEditingEnabled()) { return; } // ASSUMES visual style name is the same as the editor! // String editorType = style.getName(); String editorType = CytoscapeEditorManager.getEditorNameForVisualStyleName(style.getName()); CytoscapeEditorManager.log("got editor name for visual style: " + editorType); CytoscapeEditor editorForStyle = null; try { editorForStyle = CytoscapeEditorFactory.INSTANCE.getEditor(editorType); CytoscapeEditorManager.log("got editor for style: " + style.getName() + " = " + editorForStyle); } catch (InvalidEditorException ex) { CytoscapeEditorManager.log("Could not find editor for editor type: " + editorType); editorType = CytoscapeEditorManager.DEFAULT_EDITOR_TYPE; try { editorForStyle = CytoscapeEditorFactory.INSTANCE.getEditor(editorType); } catch (InvalidEditorException exe) { logger.warn("Error building editor for editor type = " + editorType, exe); } } if (editorForStyle != null) { CyNetworkView view = Cytoscape.getCurrentNetworkView(); CytoscapeEditor editorForView = CytoscapeEditorManager.getEditorForView(Cytoscape.getCurrentNetworkView()); CytoscapeEditorManager.log("Got editor for view: " + editorForView); if ((editorForView != null) && (!CytoscapeEditorManager.isSettingUpEditor())) { CytoscapeEditorManager.log("Disabling controls for editor: " + editorForView); editorForView.disableControls(null); } CytoscapeEditorManager.log("Initializing controls for " + editorForStyle); editorForStyle.initializeControls(null); CytoscapeEditorManager.setEditorForView(view, editorForStyle); CytoscapeEditorManager.setupNewNetworkView(view); CytoscapeEditorManager.setCurrentEditor(editorForStyle); CytoscapeEditorManager.setEventHandlerForView(view); } } /** * respond to a PropertyChangeEvent. This is typically the Creation or Modification * of a Network or NetworkView. * If networkView focus changes, then bring up the appropriate editor for the * enw network view. */ // implements PropertyChangeListener interface: public void propertyChange(PropertyChangeEvent e) { //CytoscapeEditorManager.log("Got property change: " + e.getPropertyName()); if (e.getPropertyName().equals(Cytoscape.NETWORK_CREATED)) { String netId = e.getNewValue().toString(); CyNetwork net = Cytoscape.getNetwork(netId); net.addGraphPerspectiveChangeListener(this); } // redraw graph if the network is modified, e.g. by an undoable edit // else if (e.getPropertyName().equals(Cytoscape.NETWORK_MODIFIED)) { if (e.getPropertyName().equals(Cytoscape.NETWORK_MODIFIED)) { if (e.getOldValue() != null) { // AJK: 06/19/06 hack that uses OldValue field to indicate that this // event was fired from CytoscapeEditor, thus avoids any // unnecessary redraws due to multiple event firings from an // -- any non-null value will do if ((e.getOldValue().equals(CytoscapeEditorManager.CYTOSCAPE_EDITOR)) || (e.getOldValue().equals("cytoscape.util.UndoManager"))) { Cytoscape.getCurrentNetworkView().redrawGraph(true, true); } } } // AJK: 06/15/06: enable editing once Cytoscape has been initialized else if (e.getPropertyName().equals(Cytoscape.CYTOSCAPE_INITIALIZED)) { CytoscapeEditorManager.setEditingEnabled(true); } else if (e.getPropertyName().equals(CytoscapeDesktop.NETWORK_VIEW_FOCUSED)) { CytoscapeEditorManager.log("NETWORK_VIEW_FOCUSED: " + e.getNewValue()); CytoscapeEditorManager.log("From older network view: " + e.getOldValue()); CyNetworkView view = Cytoscape.getCurrentNetworkView(); CytoscapeEditorManager.log("Current network view = " + view); view = Cytoscape.getNetworkView(e.getNewValue().toString()); CytoscapeEditorManager.log("Current network view = " + view); // AJK: 12/09/06 BEGIN // try to get editor for visual style // VisualStyle vs = view.getVisualStyle(); CytoscapeEditor cyEditor = CytoscapeEditorManager.getEditorForView(view); CytoscapeEditorManager.log("Editor for this view is: " + cyEditor); if (cyEditor == null) { try { CytoscapeEditorManager.log("looking for default editor"); cyEditor = CytoscapeEditorFactory.INSTANCE.getEditor(CytoscapeEditorManager.DEFAULT_EDITOR_TYPE); CytoscapeEditorManager.log("got default editor: " + cyEditor); // AJK: 10/25/07 need to update editor palette because we have a new edito // but this may cause two update palettes when we have first new network // will that matter? // only redraw the palette when we are on the Editor tab: // MLC 07/09/08: // if (isEditorInOperation ()) { // MLC 07/09/08 if (CytoscapeEditorManager.isEditorInOperation ()) { updateEditorPalette(Cytoscape.getVisualMappingManager().getVisualStyle()); } } catch (InvalidEditorException ex) { } } if (cyEditor == null) { cyEditor = CytoscapeEditorManager.getCurrentEditor(); if (cyEditor == null) { // this would be because no editor has been set yet. Just // return return; } else { // at this point there is an editor but it is not assigned // to this view // this is probably the case if we are loading a network, // rather than creating a new one // in this case, we need to setup the network view, which // sets all the event handler, etc. CytoscapeEditorManager.log("Building network view for: " + view + " using editor " + cyEditor); CytoscapeEditorManager.setupNewNetworkView(view); } } } } /** * Implementation of the GraphPerspectiveChangeListener interface. Responds * to the removal of nodes and edges by saving them, so that they can be * restored via RestoreDeleted action. Fires a NETWORK_MODIFIED event. */ public void graphPerspectiveChanged(GraphPerspectiveChangeEvent event) { // careful: this event can represent both hidden nodes and hidden edges // if a hide node operation implicitly hid its incident edges CyNetwork net = Cytoscape.getCurrentNetwork(); // CytoscapeEditorManager.log ("GraphPerspectiveChanged for network: " + net); boolean nodeChanges = false; // only create the set if we need it // CytoscapeEditorManager.log ("GraphPerspectiveChanged for network: " + net); boolean edgeChanges = false; // only create the set if we need it // at least one node was hidden if (event.isNodesHiddenType()) { int[] hiddenNodes = event.getHiddenNodeIndices(); for (int i = 0; i < hiddenNodes.length; i++) { CytoscapeEditorManager.addHiddenNodeForNetwork(net, hiddenNodes[i]); } if (hiddenNodes != null) { nodeChanges = true; } } // at least one edge is hidden if (event.isEdgesHiddenType()) { int[] hiddenEdges = event.getHiddenEdgeIndices(); if (hiddenEdges != null) { edgeChanges = true; } for (int i = 0; i < hiddenEdges.length; i++) { CytoscapeEditorManager.addHiddenEdgeForNetwork(net, hiddenEdges[i]); } } if (nodeChanges || edgeChanges) { // AJK: 12/13/06 to fix NPE bug // Cytoscape.firePropertyChange(Cytoscape.NETWORK_MODIFIED, // for distinguishing from batch firing of event // CytoscapeEditorManager.CYTOSCAPE_EDITOR, // Cytoscape.getCurrentNetwork()); } } }