user2463877
user2463877

Reputation: 3

Can you help me understand this Java code?

I am working on a small project that requires loading an XML file. I found a nice code sample that extends DefaultHandler and uses a custom TreeRender to format the XML into a treeview here. The code compiles and runs (always a plus) and gives me the starting point I'm looking for but there is one little thing I don't understand in the code.

Here's the code snippet that I don't get:

public class XmlTreeView extends DefaultHandler {

private DefaultMutableTreeNode _base;

<snip>

@Override
public void startElement(String uri, String localName, String tagName, Attributes attr) throws SAXException {
    System.out.println("startElement: uri=" + uri + " localname=" + localName + " tagName=" + tagName );

    DefaultMutableTreeNode current = new DefaultMutableTreeNode(tagName);
    _base.add(current);
    _base = current;
    for (int i = 0; i < attr.getLength(); i++) {
      // <snip> attribute processing
    }
}

The class declares a DefaultMutableTreeNode named _base. The startElement() method instantiates a new DefaultMutableTreeNode named current then does

_base.add(current);
_base = current;

All my programming knowledge tells me that the second statement assigns the new object (current) to the _base "variable", making the first statement useless. However, if I take out the first statement the code no longer works properly. In fact, if I take out either statement it no longer works properly. Both statements are required for the element to get added to the tree.

Can you explain to me what's happening here? I just don't get it.

Thanks in advance,

Steve

Upvotes: 0

Views: 93

Answers (3)

jrbeverly
jrbeverly

Reputation: 1621

You have a strange piece of code here in my mind but this is what is happening:

private DefaultMutableTreeNode _base;

Is acting as a global currentNode for the class. When you call startElement you are doing this:

DefaultMutableTreeNode current = new DefaultMutableTreeNode(tagName);
//Create a new TreeNode item based off the tagName

So you now have:

  • _base (no children)

Now you are going to add to the children of _base, the freshly created node

_base.add(current);

Now that this is done you have:

  • _base (no children)
    • current (child)

Finally

_base = current;

Now you have

  • (parent of _base) (the old base)
    • _base / current

The reference to _base now points to the freshly created child. When you call endElement, you will exit out of the _base and return to your old _base

_base is storing the xmlElement that you are currently working on. When you call startElement all calls to setAttribute or startElement will be based off this.

SUMMARY:

Here is what this looks like played out in code:

XmlWriter xWriter;
xWriter.startElement("NPC"); //_base becomes new node "hello"
xWriter.startAttribute("Greeting", "Hi"); //attribute is now set to _base (or greeting)
xWriter.startElement("Data"); //_base becomes new node "data"
xWriter.startAttribute("Height", "200"); //attribute is now set to _base (or data)
xWriter.endElement(); //on end element you move to parent of data, so greeting
xWriter.endElement(); //again you move to the parent

Creating:

<NPC Greeting='Hi'>
  <Data Height='200'/>
</NPC>

Upvotes: 0

dkatzel
dkatzel

Reputation: 31648

These variables are badly named which is causing most of the confusion.

The field _base should really be called something like currentNode and the new Node created in startElement should be something like childNode.

Here is the same code but rewritten using these new variable names:

currentNode.add(childNode);
currentNode= childNode;

So you see when we enter a start element in the XML file, we create a new node and add it to our Object representation of the tree structure of the XML. The new child element that we just started is added to the current node as a child. Then we change our reference of the current node to point to this new child node. This makes the new child node our current node.

I assume in code that you haven't shown, there is an endElement where we do the reverse operation and move up the tree to the currentNode's parent.

Upvotes: 2

ajb
ajb

Reputation: 31689

_base is a reference to an object. When you say _base.add(current), you are calling a method that makes some change to that object. When you then say _base = current;, _base becomes a reference to a different object. But the first object is still there. And whatever change you made to it can still impact the rest of the program, if there's a reference to it somewhere else.

Upvotes: 3

Related Questions