Aligning Sub-Nodes With layoutChildren

Hi,
I have a node which the user will add and remove symbols too depending on various factors (such as status, location etc.) in the real world.
However since these symbols are nodes in their own right each symbol is drawn and encapsualted as a subclass of JGoNode. What I would like to know is that if add two symbolnodes on initialisation how do I set the position of each symbol so they sit next to rather than on top of each other. For instance I would like to increment the x position of each by 15 but keep y the same.
I am trying to do this with layoutChildren with code as follows. It is being run but is not having any effect. Any suggestions?
Neil

int spacingX=0;

// Get first object in collection

JGoListPosition pos = this.getFirstObjectPos();

// Iterate through collection

while (pos != null) {

// Get object from collection

JGoObject obj = this.getObjectAtPos(pos);

if ( obj instanceof AbstractBasicNode ) {

AbstractNode an = (AbstractNode)obj;

Point currP = an.getLocation();

currP.translate(0, spacingX);

currP.setLocation(currP);

spacingX += 50;

}

// Iterate to next item in collection

pos = this.getNextObjectPosAtTop(pos);

}

public void layoutChildren(JGoObject child) {
if (isInitializing()) return;
setInitializing(true);
int x = 0;
boolean first = true;
JGoListPosition pos = getFirstObjectPos();
while (pos != null) {
JGoObject obj = getObjectAtPos(pos);
pos = getNextObjectPosAtTop(pos);
if (first) {
first = false;
x = obj.getLeft() + obj.getWidth();
} else {
obj.setLeft(x);
x += obj.getWidth();
}
}
setInitializing(false);
}

Thanks Walter.

Hi W,
Your code worked perfect when I hardcoded the sub-symbols into the class but what we really need to do is add and remove the sub-symbols at runtime, i.e. depending on real-time data.
We have numerous nodes which have a standard layout. The nodes are somewhat complex, each item to be displayed is held in a class as a class member. These are then added to the node by a method called by the constructor on initialisation.
However when I come to update the class members, the view of the node is not updated. I have to remove the member object from the node, which incidentally can not be with this.removeObject(obj), I have to iterate around all objects in the node and test for an instanceof that member object. Q1a: Is there not a more elegant way to remove items from a node? Since you cannot test for instanceof when there are multiple occurences within the node. Q1b: Can I not remove the one referred to by the class member?
Once the member is removed and re-added this still does not update the display, a new object instance needs to be created and then added to the node.
This is problematic because firstly when I re-add a child node containing symbols its position is incorrect since layoutChildren refers to class members, this is also true for rotating symbols within nodes as nodes themselves cannot be rotated (you may remember the email you sent me). Q2a: Is there a way to avoid using class members to represent jgo objects? Q2b: Is there a more elegant way of implementing complex jgonodes?
Secondly it is expensive to create a new object instance each time. Q3: Can this not be avoided?

Q1a: You need to have some way to distinguish different instances of some JGoObject class that you have added to your JGoArea/JGoNode. JGo can’t know which one you want to remove, so you either need to keep references around (and remember to update those references when you copy the node or add/remove children), or you need to annotate those objects with some information so that you can tell which is which.
Q1b: I’m not sure what you mean. I don’t understand why you need to remove an object and then add it again. Did you just want to change the Z-order of those children relative to each other? Or did you want to get layoutChildren to re-order those children? You could use JGoArea.addObjectAtHead or addObjectAtTail to move a child to the beginning or to the end of the list.
Q2a: I guess I don’t understand what you mean about class members.
Q2b: All “complex” nodes consist of nested JGoAreas. Usually it’s just one level deep, but it could be more.
Q3: No, it’s not very expensive to create JGoObjects.

I want to modify a class member of a node and those changes be refelected in the JGoView/Document.
All child elements are held as class members and then each class member is added to the node, like int is in the sample application in the user guide. Everything from rectangles to JGoText to sub-nodes are class members. I am struggling to get JGo to update/locate its display when these members change state. Similarly when restoring from SVG there are quite a few npe becuase the class members are not initialised in the usual way.
I was wondering at this point should we do this completely differently. For instance should the nodes and all its elements be drawn using a different process that JGo desires or intended thus eliminating the need for class members (which are effectively pointers) to the child elements. Hope this makes sense.
Kind Regards,
Neil

JGo implements grouping by having JGoObjects be “children” of a “parent” JGoArea. So you need to use JGoArea.addObjectAtTail or related methods to add a JGoObject to a JGoArea.
If you also choose to keep references to some or all of those child objects as fields in your class, that’s OK, but you’ll need to maintain those fields – particularly when the JGoArea is copied (that’s why you override the JGoArea.copyChildren method).
The layoutChildren method has responsibility for sizing and positioning the child objects.
If you modify a child object’s size, it will call the layoutChildren method so that everything can be repositioned, if needed. An example is setting a JGoText object’s text string. Other modifications to child objects might not cause any calls to layoutChildren. An example would be setting the brush of a JGoDrawable.
In all these cases all views that are displaying your document will automatically update.

I do understand what your saying from studying and practising the JGo USer Guide but what I cannot figure out that if I use a getter to the ‘symbol’ node within a greater node and add symbols to it, these changes are not reflected within the JGoView.
Similarly when I get a JGoRectangle (for instance) and set it with a new size pen, the class member is updated, no exceptions is thrown yet the rectangle is not updated in the view.
It is myunderstanding that this is becuase the object held by the JGoNode has a different hashcode than the class member so the instance JGoNode refers to is different to what the class member refers too and consequently no update occurs. This is despite the fact the class member is referencing the object that was added to the node using addObjectAtTail. Furthermore the reference of the class member in the newobj is copied in copyObject.
It would seem that the only way to get at the instance held by the JGoNode is iterate through the node objects until you find the instance you are looking for. Unfortunately calling a JGoRectangle that is part of a node directly with getters/setters of the class members that has no effect.
To sum up what I am trying to ascertain from this topic is are we doing something which cannot be done with JGo? Or does JGo require a different approach to updating its objects dynamically?
Updating objects at runtime with JGo makes it very difficult and sometimes impossible, we find it quite inflexible. Is this a problem with our implemantation or JGo?
Yours Confused,
Neil

If just changing the pen or brush of a JGoRectangle isn’t working for you, then there’s definitely something wrong.
I’m guessing that that JGoRectangle isn’t actually in your JGoDocument, either directly in a JGoLayer as a top-level object, or indirectly by being a child of a JGoArea that is in a document layer.
Could you check that JGoRectangle.getDocument() is returning the same document that JGoView.getDocument() returns?
Are you initializing your node by creating child objects in the node’s zero-argument/default constructor? This will cause problems when the node is copied, because you will have two copies of those child objects – those created by the constructor and those copied by copyChildren.

Hi Walter,
Debugging output shows my controller has a class member of a specialised view which in turn has a class member of a specialised document. They are specialised to test Document.isModified.
While the ‘complex’ node was refering to a JGoDocument with a different hashcode it is now resolved. The symbol node, however, is refering to a different document than its parent the ‘complex’ node. I have not yet tested if this is the case with the JGoRectange.
I have not implemented multiple layers but I presume the different documents are refering to the document associated with the layer for the symbol node and its parent the ‘complex’ node.
I guess that is why changes to it are not being reflected in the view because the view is referring to a different document. Any suggestions on how to resolve this? Do I need to define or test for a changed hint, sand if so how would I do this?

If I understand you correctly, you want to have an instance of a subclass of JGoView displaying an instance of a subclass of JGoDocument. There are several ways of having your view use your document.
One way to make sure your view displays your document is to just call JGoView.setDocument.
Another way is to call the JGoView constructor that takes a JGoDocument as a parameter.
Since the default JGoView constructor creates its own document, an instance of JGoDocument, a third way is to override JGoView.createDocumentModel to return an instance of your document class.
After that, of course, you need to make sure that whenever you create JGoObjects that you add them to the view’s document.

Hmm,
I already create a schematicsview with a schematicsdocument and have overriden createDefaultModel to return a new schematicsdocumument and getdocument returns a schematicdocument.
The symbolnode creates an instance of a symbol, say ‘valve’ and the invoke addobjectattail to add it. However it would appear that the symbolnode exists on one document as a child of complexnode but the symbol exists on another document that I presume symbolnode has created. So the child of complexnode, symbolnode exists on one document but a child of symbolnode, a symbol, exists on a different document to symbolnode, the parent. Eh?
That could explain why adding a symbol to symbolnode has no effect on the view, since the view represents the document of symbolnode, NOT of the document of the children symbolnode where the symbols exist. Is this a bug of JGo? How do I resolve this riddle? I guess this is why adjusting rectangle pen thickness has no effect also.
I construct a node first, symbol and then add it to another node the symbolnode and then add the symbol node to the complexnode. Is this not possible with JGo or is this implementation wrong?

Here’s the part or containment hierarchy:
JGoDocument, displayed by one or more JGoViews
JGoLayer
JGoArea or JGoNode or subclass thereof
… maybe more intermediate areas
JGoObject
You can’t see a JGoObject unless it is in a JGoLayer in a JGoDocument viewed by a JGoView. I suspect for this part of your application there should be only one JGoDocument ever created.

Okay,
So how do I add jgoobject’s to a node using a specified document instead of the node creating and using an arbitary document.
I can tell the view which document to use, therefore nodes I drag to it form the palette use that document but nodes within that node use a different document; why is this walter and how do I stop it?.
I can not setDocument on an area or layer so how do I tell a node which document to use. Each node builds itself individually to the parent as it may be used on its own.
I feel there is something fundamentally wrong, but I cannot find out what?
My understanding of JGo is knowledgable but not proficent. Therefore I am using the user guide but it lacks sufficent detail, the javadocs are okay but you have to know what you are looking for them to be helpful. As a result JGo support is the last option and after many posts on this topic I feel we have made no progress.
So to return to my previous question how do I update a node within a node dynamiically? What do I have to do?
Regards,
Neil

Nodes should not be creating documents.
Nodes are part of a document just because they are part of a layer, either directly because they are top-level objects, or indirectly because they belong to a JGoArea that is part of a layer.
If you want to add an object to an area/node, just call JGoArea.addObjectAtTail.

Yes but symbolnode is adding to a different document instance to the one used in view. I tested this and the hashcodes are different. W would the symbolnode use a different document to the one complexnode is using?
Is it how it has been initialised? Symbols are being added to the symbolnode after it has been added to the complexnode but symbolnode adds to a different document than the complenode it is contained in. How come?

I’m sorry, but you lost me there.
You can certainly maintain as many different documents as you want. None of them even have to have any JGoViews displaying them.
Are you intentionally constructing a hierarchy of documents, where a node in one document can lead to a different document, perhaps viewed simultaneously in a different JGoView as in a “drill-down”? That is a reasonably common scenario.
If you only intend there to be one document, then you need to set a break point and figure out why you are constructing more than one.

Well I have successfully gone full circle. I have decided not to bother with an intermediary symbolnode and I add symbols directly to the complex node directly. Unfortunately layoutchildren is not positioning them correctly and if I change layoutChildren the rest of the node is affected.
Now after a week’s worth of debugging I have managed somehow to get symbols to add to the node at runtime - hoorah, but how do I get the symbols to line up correctly without interupting the rest of the elements in the complex node? Should I test for it with the parameter of layoutChildren(JGoObject)?
Neil

I assume you are talking about your complexnode’s layoutChildren method.
In my original reply, you can add a statement just before the “if (first) …” statement to check to see what kind of object that child is. If it’s one of your symbols, fine, keep going. If it’s not, then you need to decide what kind of object that is in your complex node, and whether and where and how you are going to position it relative to the other children of your complexnode.

Hi W,

After much ado I have managed to add/remove symbols from a complex node. However when I remove a symbol it leaves a hole in the layout and I therefore need to re-layout all the symbols.

In order for me to do this I need to remove all of the symbols, however we return to the old problem of class members not representing node elements. This is despite the implementation copyChildren and copyObject. As a result invoking removeObject(obj) does not have any effect since obj as far as removeObject is concerned the class members is not ‘an immediate child of this area’.

How do I implement class members to represent node elements?

Neil