Aligning Sub-Nodes With layoutChildren

JGoArea.removeObject will call layoutChildren, if the argument is indeed an immediate child of the JGoArea. If you have nested areas, you need to call removeObject on the immediate parent of the object you want to remove.
JGoArea is a JGoObjectCollection. For JGoArea to have children (or “parts”), you have to use its methods, such as addObjectAtTail. Methods such as layoutChildren need to consider moving/resizing all of the children as seen by iterating over the collection.
You can, if you want, define fields that refer to children, in addition to the JGoArea’s reference in its collection. That’s up to your code. But those references can only be a convenience for easy access/identification of particular children.

Hi,
How can I update the corresponding class member when the user changes the text of a JGoText. Is there an eventhandler for this scenario? The class member is used layoutchildren and SVGWriteObject so it needs to reflect current user info.

I’m confused by your descriptions. Is the class member a reference to a (child) JGoObject, or is it a String which corresponds to the value of some (child) JGoText’s text string?
There’s no need to have a field in your parent class that is a string when the value should always be the same as the JGoText.getText() value for a particular child JGoText object. Just get (or set) the property on the JGoText object.
But you might need such a field in your class if the string value might sometimes be different from that which is displayed by the JGoText object.

Going back to the issue regarding identifying particular child objects, if you don’t want to have fields in your class that refer to particular children, that’s OK. You can always find a particular child by iterating through the list of children. Perhaps what you are looking for is always the first JGoText child.
If you don’t have a easy way of telling the children apart, maybe you can add data to each child so that you can distinguish them from each other. Perhaps you could use the Flags property (JGoObject.setFlags). Perhaps you could add fields to the class of those child objects.
Keeping a field reference to a child in the parent class is convenient for faster access. But then you need to maintain that reference when the parent is copied, and when the child object is removed or replaced.

Cheers Wal, using flags and iteration works, although it does kind of make my class members redundant in that aspect. Why do you think the class member references are not being updated despite us implementing copyChildren and copyObject?
In addition to this how do I preserve the layout of elements when restoring from svg? All nodes are dumped in to the top left corner of the view except the links which are in the correct place but lose their linkage. I don’t invoke super.SVGReadObject nor super.SVGWriteObject as they create a much larger svg file. What do they do and is it neccessary to call these?
Neil

What do you mean by “updated” when talking about those reference fields?
I do not recommend using extended SVG as a persistence format. It is much better to define your own XML schema, as some of the examples do. That should produce XML that is simple and “minimal”, easy to understand and to extend.
If you do use JGoSVG, yes, you do need to call the super methods. The implementation for JGoObject, for example, saves/restores the position.

I will have to look into that our objective is to just (try) to get a working prototype, at least our elements are saved.
Do I need to add ports to my complex node or are they there implicitly at the ‘spots’?

Ah, if you just want something convenient for prototyping purposes, you can use extended SVG. Or you could just serialize/deserialize the document by using ObjectOutputStream/ObjectInputStream.
Instances of the predefined subclasses of JGoNode, when initialized, already have one or more JGoPorts, depending on the class.
If you are inheriting directly from JGoNode, then yes, you need to add one or more ports, according to your needs.

We have implemented our own svgWriteObject and svgReadObject methods to record only the important aspects of the node’s state since the rest (mostly rectangles) can be recreated when the node is and therefore do not need to be serialised.
The labeled links and the text are restored, although I do not call super.svgWriteObject or super.svgReadObject, how then are the links being serialised? Also how do we iimplement serialisinig which links are attached which ports. To further complicate matters a link can be linked to another node (or link) since the midLabel is a JGoPort.
However how do we serialise and restore the links associated with the nodes?

JGoLinks are just other classes that are handled by the SVG reading and writing methods. If you haven’t overridden any methods or added any fields there, the default behavior should work.

Unfortunately the association of a link to a port is lost when I restore from an svg. Is there a way to preserve and restore this?
Also my undo is mixing up rectangles when I undo a moved linked node but not when I undo a moved unlinked node. How can this be overcome?
Thirdly how do I replace the link that is added to a document with one that is a labeledlink, specialised with our own objects? I currently achieve this in documentChanged method of a JGoDocumentListener but I remove the link that is already added and I think you will agree this is not particularly agile. I also need to break a link when a drop a symbol on top of it and then re-create the links with the symbol included? Is this possible and if so how?

I don’t know why links are not being restored correctly for you – perhaps because you aren’t calling the super methods consistently everywhere?
Undo/redo ought to just work if you have been careful to perform user-initiated actions within transactions (the standard behaviors do this for you already) and if you make sure you implement changeValue and related methods for managing any state that you have added to any JGoObject (or JGoDocument) classes.
Are you talking about the link that the user draws? Override JGoView.newLink to do what it currently does (see the definition in JGoView.java) but to construct your own link class, which might be a JGoLabeledLink or a subclass of that.
For breaking a link when dropping a symbol on it – you can implement a JGoViewListener that checks for either JGoViewEvent.EXTERNAL_OBJECTS_DROPPED (if drag-and-drop from a different window such as a JGoPalette) or JGoViewEvent.SELECTION_MOVED (if moving a symbol within the same JGoView). Then you need to decide what the definition is for “dropping onto a link” – how to handle overlap and does the mouse position matter and what to do about ambiguity if there are multiple links and/or multiple objects dropped. Once you know which link you want to modify, then that’s pretty easy, since you can just reconnect the existing link and create a new link for the other part.

Hi,
I have subclassed a labeledlink and moved the initialisation code into it from the gui controller. I have also now implemented JGoView.newlink in my SchematicsView.
However I cannot get the links to redraw correctly when I restore from svg. If I invoke the super methods from svgwriteobject and svgreadobject I get the same node twice on top of each other, and the one created from the super method does not have any colour.
If I therefore do not call super I stick to my implementation of writing svg then the complexnode is written and restored correctly but unfortunately the link is no longer connected to any port. If I comment out calling super in my SchematicsLink the stroke is not drawn but the text labels are correct. How do I serialise and restore links to svg?
Incidentally here is an element from the svg, notice the fromport and toport are null.
<jgoxml:JGoClass class=“com.nwoods.jgo.JGoLink” curviness=“10” fromport=“null” linkflags=“327680” partid="-1" toport=“null”/>

Are you allocating objects in your node constructor? That would cause duplicate child objects when loading.
I suspect your application isn’t seeing any ports because you didn’t call the super methods so that the JGoArea/JGoNode didn’t get a chance to save the ports.

I think you would be a lot happier if you took a little extra time to implement your own code to read/write your own XML schema.
Try the Flower example. When you do a File | Save As, you’ll note that there are a lot of possible file formats. I think the best one for your purposes is something like the “Flower Custom XML” format. It is implemented by the loadXML and storeXML methods in ProcessDocument.java. (Ignore all those SVG-related formats. You don’t want object serialization either.)
That code, and the schema that it writes/reads, assumes that you can identify the exact ports for each link by identifying the exact nodes. In other words, since each node has a single input port and a single output port, it is sufficient to identify the node in order to find the port to which a link is connected.
If you have multiple input ports and/or multiple output ports on your node, you’ll need to write out additional information for each port so that you can distinguish them when loading each link.

Okay Walter, thanks for the hint. I very much like the xml the flower example produces with the methods you mention. It is quite clean, small and light and have set about implementing our schema. We are trying to serialise unique id’s for each complexnode which can be achieved by calling getPartId since according to the javadoc each each node, port and link implements IdentifiablePart. However the partid of all the ports on the complexnode come out as -1 while the ports on the links have a unique number.
The ports are part of the complex node but I am guessing document does not call these when it is added to a document layer. How then do I set and get unique identifiers for these ports? Also if setPartId is not being invoked on widgets of the nodes, why are the id’s not sequential?. This does not make sense.
I need the partid of the links to be the same as the partid of the parts on the links in order for us to reconstruct the links. What do you suggest?
Neil

When a JGoArea is added to a document, and when JGoDocument.isMaintainsPartID() is true, the document will recursively traverse all of the children of the JGoArea, and for all JGoObjects that it sees that implement JGoIdentifiablePart, it will make sure it has a unique PartID and add it to a hashmap so that JGoDocument.findPart can get it quickly.
So if parts of your node do indeed implement JGoIdentifiablePart but have a PartID == -1, then I’m guessing this is due to the same problem as we identified earlier in this topic: not all of your “parts” JGoObjects are actually children of your JGoArea.

This returns us then to why copyChildren is not having any effect since I call each class member and set it to the corresponding class member in the new area, as shown in the following snippet.



@Override

protected void copyChildren(JGoArea newarea, JGoCopyEnvironment env) {

super.copyChildren(newarea, env);



if ( newarea instanceof ComplexNode) {

ComplexNode cn = (ComplexNode)newarea;



cn.setSymbolNode( this.setSymbolNode() );



The fact that I cannot use class members for convenience makes code more difficult and increasingly complicated as we progress.



If we set partid from a previously saved svg will there be any clash of partid that the document generates or will they continue to be unique?

Also if I iterate through all objects in a collection will this traverse into the children of the nodes? Such that I can find the port of a node that matches a partid within our SchematicsDocument.

Or would I have to find the node first then ask the node for its matching port?

As I described before, and as many of the example classes show, you can use fields (aka instance data members) to refer to child objects. You just need to add code in copyChildren, and maybe in other methods such as removeObjectAtPos and layoutChildren, to keep those references up-to-date with the children collection that the JGoArea maintains.
PartIDs are unique within the whole JGoDocument. You can just use JGoDocument.findPart to find a particular port or node, no matter how deeply nested it is.
Whether you need to find a node and then look for a port on that node depends on what information you are saving. If you are using PartIDs, then you might not need to. (But you still need to handle unresolved references, of course, by fixing up afterwards.)
But you might be using a different scheme for identifying nodes and particular ports on nodes, in which case you might need to find the node first, if the identifying information for ports is scoped to the node, not to the whole document.

We have decided to use partid’s otherwise we would be reinventing the wheel as JGo has it already implemented. When I restore links the link attaches itself to two ports on the same node.



I set and restore the partids of the ports in the node and the xml proves that each is diferent but the link element matches the node elements.



On restore I set the partid’s of the ports to the ones that had been serialised in the svg. Is this correct way to use partids? Is it worth us implementing our own unqiue id policy?

Yes, when you restore, you need to set the PartIDs of the ports, at least for those ports to which you need to refer from any links.

I go through a while loop in a subclass node and test for flags. Now I want to expand this into the superclass while leaving the speciality in the subclasses. How do I access the elements with out inefficently iterating around a while loop in each class of the hierachy testing for flags?



It would be beneficial if we were able to use class members but infortunately their references are not being updated and I do not know why even though I have implemenetd the methods you have selected. Is this the root cause of the problem?



In addition is it possible for the user to draw an orthogonal, dashed, stroke onto the view. We will also need to draw a stroke around the perimeter nodes of an arbitrary selection. The line will represent a region the postal areas(nodes) are situated in. Is this possible?



I also need to allow the user to change colour of objects from a pallete. Can this be achieved with an actionlistener which will create a new brush for the selected objects?



Eventually we will need to put the nodes into different layers that the user will toggle visibility. Is this easy to implement and if so how? Also how do I ‘driil down’ to a new sub-view with a new sub-pallete when the user doubleclicks a node in the schematics?



Thanks,



Neil