Page Index Toggle Pages: 1 Send TopicPrint
Normal Topic Odd problem updating Custom Composite Nodes (Read 6360 times)
AR
Junior Member
**
Offline


I Love MindFusion!

Posts: 65
Joined: Jan 23rd, 2015
Odd problem updating Custom Composite Nodes
Feb 19th, 2015 at 1:54pm
Print Post  
I am using custom composite nodes set up as follows:
Code
Select All
<?xml version="1.0" encoding="ISO-8859-1"?>
<SimplePanel>
    <Shape Name="Shape" Shape="Rectangle" />
    <Border Padding="2">
        <StackPanel Orientation="Vertical" GridColumn="1">
            <Text Name="Title" Font="Arial-12" TextAlignment="Centre" />
            <Image Name="Image" />
            <Text Name="NamesList" Font="Arial-10" TextAlignment="Centre" />
        </StackPanel>
    </Border>
</SimplePanel> 



When I create the Node on the Diagram, I can change either of the text components or the image and the changes are immediately reflected on screen. This is true as long as the Diagram remains displayed.

If I close the Diagram (saving it as XML) then reload it, I can make changes and see the changes (via debugging) in the components of the custom composite node. However the changes are NOT reflected on screen or in the data subsequently saved to XML.

If I add a new custom composite node to the Diagram, I can see changes to the new custom composite node, but not to any that existed prior to the Diagram being loaded from XML.

Is there something I need to do to be able to show the changes made to the existing nodes on screen and in new saves to XML??

The code I use to load from XML (and match up to my application classes) is shown below. [Class names have been changed]

Code
Select All
 diagram = new Diagram();
      diagram.setLinkHeadShape( ArrowHeads.Triangle );
      diagram.setLinkHeadShapeSize( 10 );
      diagram.setAdjustmentHandlesSize( 4 );
      diagram.setBackBrush( new SolidBrush( Color.white ) );
      diagram.setBackgroundImageAlign( ImageAlign.TopLeft );
      diagram.setDynamicLinks( true );
      diagram.setMeasureUnit( GraphicsUnit.Point );
      diagram.setLinkShape( LinkShape.Bezier );
      diagram.setAllowSelfLoops( false );

      diagram.addDiagramListener( new DiagramAdapter()
      {
        @Override
        public void nodeClicked( NodeEvent e )
        {
          onNodeClicked( e );
        }

        @Override
        public void clicked( DiagramEvent e )
        {
          onClicked( e );
        }

        @Override
        public void linkCreated( LinkEvent linkEvent )
        {
          onLinkCreated( linkEvent );
        }

        @Override
        public void linkDeleted( LinkEvent linkEvent )
        {
          onLinkDeleted( linkEvent );
        }

        @Override
        public void linkDoubleClicked( LinkEvent linkEvent )
        {
          onLinkDoubleClicked( linkEvent );
        }

        @Override
        public void serializeTag( SerializeTagEvent serializeTagEvent )
        {
          onSerializeTag( serializeTagEvent );
        }

        @Override
        public void deserializeTag( SerializeTagEvent serializeTagEvent )
        {
          onDeserializeTag( serializeTagEvent );
        }
      } );

      diagramView = new DiagramView( diagram );
      if (readOnly)
      {
        diagramView.setBehavior( Behavior.DoNothing );
      }
      else
      {
        diagramView.setBehavior( Behavior.LinkShapes );
      }
      diagramView.setDiagram( diagram );
      diagramView.setInplaceEditFont( new Font( "Microsoft Sans Serif", Font.PLAIN, 12 ) );
      diagramView.setModificationStart( ModificationStart.AutoHandles );
      diagramView.getPrintOptions().setRenderTarget( RenderTarget.Printer );

      // Enable serialization of CustomCompositeNode instances
      Diagram.registerItemClass( CustomCompositeNode.class.getClass(), "CustomCompositeNode", 1 );

      mainComponent.add( diagramView, BorderLayout.CENTER );


      if (diagramHolder != null && diagramHolder.getXml() != null && !diagramHolder.getXml().isEmpty())
      {
        // load from xml found on diagramHolder
        Diagram.registerItemClass( CustomCompositeNode.class, "CustomCompositeNode", 1 );
        try
        {
          DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
          DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
          StringReader reader = new StringReader( diagramHolder.getXml() );
          Document doc = builder.parse( new InputSource( reader ) );
          diagram.loadFromXml( doc, false );
          // match and update MyClasses
          if (diagram.getNodes() != null && !diagram.getNodes().isEmpty())
          {
            for (DiagramNode node : diagram.getNodes())
            {
              if (node instanceof CustomCompositeNode)
              {
                CustomCompositeNode ccNode = (CustomCompositeNode) node;
                MyClass classOnNode = ccNode.getMyClass();
                MyClass match = matchMyClass( classOnNode, ccNode.getClassName(), ccNode.getClassId() );
                if (match != null)
                {
                  ccNode.setMyClass( match );
                  ccNode.updateNamesList(); // sets the text to the correct list of names derived from values in MyClass
                }
              }
            }
          }
          // remove any previous selection - stops delete button working on 'readonly' diagrams
          diagram.getSelection().clear();
          diagram.repaint();
        }
        catch (SAXException se)
        {
          logger.error( "Failed to initialise diagram from XML", se );
        }
        catch (ParserConfigurationException pce)
        {
          logger.error( "Failed to initialise diagram from XML", pce );
        }
        catch (IOException e)
        {
          logger.error( "Failed to initialise diagram from XML", e );
        }
        catch (XmlException e)
        {
          logger.error( "Failed to initialise diagram from XML", e );
        }
      } 

  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Odd problem updating Custom Composite Nodes
Reply #1 - Feb 19th, 2015 at 3:05pm
Print Post  
What does your nodes' loadFromXml method code look like? You might be getting two copies of the components if you are applying the template from loadFromXml again, since by default it is serialized by the base CompositeNode code. E.g. if loadFromXml calls this code from tutorial node's constructor, you'll end up with a second hierarchy of components in the node and the changes you are seeing in the debugger could be affecting the components hidden behind second copy -

getComponents().add(XmlLoader.load....

If you prefer to reload the template from loadFromXml instead of serializing components (to keep the XML files smaller), you could override CompositeNode.serializeComponents() and return false to prevent the default serialization and avoid second copy.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
AR
Junior Member
**
Offline


I Love MindFusion!

Posts: 65
Joined: Jan 23rd, 2015
Re: Odd problem updating Custom Composite Nodes
Reply #2 - Feb 19th, 2015 at 4:46pm
Print Post  
This is the code from my custom composite node:
Code
Select All
protected void loadFromXml( Element element, XmlPersistContext xmlPersistContext )
    throws TransformerException, XmlException
  {
    super.loadFromXml( element, xmlPersistContext );
    Element myClassElement = xmlPersistContext.getChildElement( element, "MyClass" );
    classId = xmlPersistContext.readInt( "id", myClassElement );
    className = xmlPersistContext.readString( "name", myClassElement );
  } 



It doesn't look to me if that should create a second copy of the components.
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Odd problem updating Custom Composite Nodes
Reply #3 - Feb 19th, 2015 at 5:19pm
Print Post  
What do the setMyClass and updateNamesList methods do? You will see the same problem if they call getComponents().add(XmlLoader.load(..)) without clearing the Components list first.
  
Back to top
 
IP Logged
 
AR
Junior Member
**
Offline


I Love MindFusion!

Posts: 65
Joined: Jan 23rd, 2015
Re: Odd problem updating Custom Composite Nodes
Reply #4 - Feb 20th, 2015 at 11:41am
Print Post  
Here is the code for the two methods:

Code
Select All
public void setMyClass( MyClass myClass )
  {
    this.myClass = myClass; // MyClass variable
    MyClassName = myClass.getMyClassName(); // String variable
    MyClassId = myClass.getId();// int variable
    MyClassTitle.setText( myClass.getMyClassName() ); // TextComponent variable
  }

  public void updateNamesList()
  {
    namesList.setText( myClass.getListOfNames() ); //TextComponent varible (myClass set by previous method call, method call returns a string)
  }
 

  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Odd problem updating Custom Composite Nodes
Reply #5 - Feb 20th, 2015 at 1:08pm
Print Post  
If you check the contents of CustomCompositeNode.getComponents() in debugger after reloading from XML, does it show a single SimplePanel in the list or two of them?
  
Back to top
 
IP Logged
 
AR
Junior Member
**
Offline


I Love MindFusion!

Posts: 65
Joined: Jan 23rd, 2015
Re: Odd problem updating Custom Composite Nodes
Reply #6 - Feb 20th, 2015 at 3:19pm
Print Post  
It only has one SimplePanel - and the structure looks correct to me all the way down to my two TextComponents and one ImageComponent as shown in the screen shot attached.

  

components.png ( 27 KB | 137 Downloads )
components.png
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Odd problem updating Custom Composite Nodes
Reply #7 - Feb 20th, 2015 at 3:47pm
Print Post  
So there's no second copy. Could you attach a test project that reproduces the problem?
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: Odd problem updating Custom Composite Nodes
Reply #8 - Feb 20th, 2015 at 5:36pm
Print Post  
Is there onLoad overloaded method in CustomCompositeNode as in the tutorial? If you've missed implementing it, the node might keep references to components created by the constructor, while it displays new components created by loadFromXml. Then you might be seeing in debugger your property setters changing attributes of some components, but not the ones currently displayed.
  
Back to top
 
IP Logged
 
AR
Junior Member
**
Offline


I Love MindFusion!

Posts: 65
Joined: Jan 23rd, 2015
Re: Odd problem updating Custom Composite Nodes
Reply #9 - Feb 26th, 2015 at 10:52am
Print Post  
Yes - I had missed the 'onLoad' method - added it in and now I can see the changes I made.

Thank you.
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint