How to change a NodeView to show a custom view for a node? I (MarcioSilva) have only a part of the answer. :-) Here some discussions about my experiences with this and the problems I found. Feel free to add more information to this page. I started my hack using as a base, the PetalNode from the MDNodes plugin. Then I started to make my modifications in the {{{drawNodeView()}}} method. I tried to use the {{{PPath}}} class, but I could not find a way to draw arcs of circles with it. Then I overrrided the {{{paint()}}} method from {{{PPath}}}, like this: {{{#!java PPath n = new PPath() { public void paint(PPaintContext aPaintContext) { Arc2D.Double arc = new Arc2D.Double(); arc.setArcByCenter(0,0,40,0,300,Arc2D.PIE); Graphics2D g2 = aPaintContext.getGraphics(); g2.setPaint(Color.red); g2.fill(arc); } }; }}} Then I had trouble selecting nodes that have the new shape. This was fixed with this modification in the {{{selected()}}} method: {{{#!java public void select() { selected = true; nodeView.setSelected(true); // added by mrsva drawSelected(); } }}} and with the use of {{{setPathToEllipse()}}} and {{{setBounds()}}} in the {{{drawNodeView()}}} method. also the ''context menu'' doesn't work in the nodes with the changed shape. I tried to change: {{{#!java view.addContextMethod( "class phoebe.PNodeView", // <-- changed line "csplugins.mrsva.metadata.MDMenus", "getMetaDataMenu", new Object[] { view } , CytoscapeInit.getClassLoader() ); }}} to: {{{#!java view.addContextMethod( "class csplugins.mrsva.metadata.PieChartNode", // <-- changed line "csplugins.mrsva.metadata.MDMenus", "getMetaDataMenu", new Object[] { view } , CytoscapeInit.getClassLoader() ); }}} but this didn't helped. Another problem, which affects the use of custom node views with the MetaNodes plugin, is that Cytoscape raises an exception when one tries to remove a node with the custom node view. When I tried to remove such nodes (with custom view), I received the following exception: {{{ java.lang.ClassCastException at phoebe.PGraphView.removeNodeView(PGraphView.java:1166) at cytoscape.view.BasicGraphViewHandler.removeGraphViewNodes(BasicGraphViewHandler.java:388) at cytoscape.view.BasicGraphViewHandler.handleGraphPerspectiveEvent(BasicGraphViewHandler.java:76) at cytoscape.view.GraphViewController.graphPerspectiveChanged(GraphViewController.java:403) at fing.model.GraphPerspectiveChangeListenerChain.graphPerspectiveChanged(GraphPerspectiveChangeListenerChain.java:38) at fing.model.FGraphPerspective$GraphWeeder.hideNode(FGraphPerspective.java:1180) at fing.model.FGraphPerspective$GraphWeeder.access$300(FGraphPerspective.java:1133) at fing.model.FGraphPerspective.hideNode(FGraphPerspective.java:230) at metaNodeViewer.model.AbstractMetaNodeModeler.undoModel(AbstractMetaNodeModeler.java:600) at metaNodeViewer.MetaNodeUtils.uncollapseNodes(MetaNodeUtils.java:196) at metaNodeViewer.actions.UncollapseSelectedNodesAction.uncollapseSelectedNodes(UncollapseSelectedNodesAction.java:126) at metaNodeViewer.actions.UncollapseSelectedNodesAction.actionPerformed(UncollapseSelectedNodesAction.java:88) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1786) at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(AbstractButton.java:1839) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:245) at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:231) at java.awt.Component.processMouseEvent(Component.java:5100) at java.awt.Component.processEvent(Component.java:4897) at java.awt.Container.processEvent(Container.java:1569) at java.awt.Component.dispatchEventImpl(Component.java:3615) at java.awt.Container.dispatchEventImpl(Container.java:1627) at java.awt.Component.dispatchEvent(Component.java:3477) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:3483) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3198) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3128) at java.awt.Container.dispatchEventImpl(Container.java:1613) at java.awt.Window.dispatchEventImpl(Window.java:1606) at java.awt.Component.dispatchEvent(Component.java:3477) at java.awt.EventQueue.dispatchEvent(EventQueue.java:456) at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:201) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:145) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:137) at java.awt.EventDispatchThread.run(EventDispatchThread.java:100) }}} I am not sure what that means, but looking at the method on the top of the list ({{{phoebe.PGraphView.removeNodeView}}}) I found that there is a cast to ({{{PNodeView}}}): {{{ PNodeView node_view = ( PNodeView )getNodeView( node ); }}} Shouldn't this be {{{ NodeView node_view = ( NodeView )getNodeView( node ); }}} as {{{NodeView}}} is the interface implemented by {{{PNodeView}}} (and by my {{{PieChartNode}}})? Shouldn't we use the interface in such cases? If {{{PNodeView}}} is right here, how one can define other node views and remove them? Then, in the case that the correct cast is {{{NodeView}}}, {{{NodeView}}} should have the interface for {{{removeFromParent()}}}. Here the complete code of {{{phoebe.PGraphView.removeNodeView}}} to explain why: {{{#!java public NodeView removeNodeView ( int node ) { PNodeView node_view = ( PNodeView )getNodeView( node ); try { node_view.removeFromParent(); } catch ( Exception e ) { System.out.println( "GINY at PGraphView.removeNodeView(int): Parent was most likely null for: "+node); return null; } nodeViewMap.removeKey( perspective.getRootGraphNodeIndex( node_view.getGraphPerspectiveIndex() ) ); ensureNodeSelectionCapacity(); nodeSelectionList.setQuick( node_view.getGraphPerspectiveIndex(), 0 ); return node_view; } }}} so, {{{node_view}}} should have the method {{{removeFromParent()}}}. Here is the signature of my class (I didn't changed it from the PetalNode class): {{{#!java public class PieChartNode extends PPath implements NodeView, PropertyChangeListener { }}} and {{{PPath}}} extends {{{PNode}}}. Then I tried to modify {{{phoebe}}} and {{{NodeView}}} to test my theory. But when I load the sources of {{{phoebe}}} some methods are not recognized well. For example in the file {{{phoebe.PGraphView}}}, there is a call to {{{edu.umd.cs.piccolo.PNode.firePropertyChange()}}} but seems to be a difference in the signature of this method in {{{PGraphView}}} and in '''Piccolo'''. My guess is that a different version of '''Piccolo''' was used in the development of '''Phoebe''' and I got the version 1.1 of '''Piccolo''' website. Which version of Piccolo was used in the development of Phoebe? Here the error I receive: {{{ "The method firePropertyChange(int, String, Object, Object) in the type PNode is not applicable for the arguments (String, null, List)" }}} in this line: {{{#!java if ( firePiccoloEvents ) firePropertyChange(PROPERTY_CHILDREN, null, getChildrenReference() ); }}} Any ideas/discussion? Please, add your experience to this page. MarcioSilva