X

Geertjan's Blog

  • October 5, 2008

Serializing Marilyn Monroe

Geertjan Wielenga
Product Manager
I made a lot of progress with node serialization. Now, when I start up my application, I see ALL of the following selected:

The above are selected, without me doing anything at start up, because those were the ones I had selected at the time the application shut down. Hence, I serialized ALL the selected nodes. Before, I only managed to work with a single selection, instead of the multiple selection you see above, because I hadn't figured out how to iterate over my handles correctly and add them to the array of nodes that is selected at start up. The important changes over the previous blog entry is in bold below, within the context of everything else that is relevant here:

@Override
public Object writeReplace() {
Handle[] selectedHandles = NodeOp.toHandles(em.getSelectedNodes());
return new ResolvableHelper(selectedHandles);
}
public final static class ResolvableHelper implements Serializable {
private static final long serialVersionUID = 1L;
public Handle[] selectedHandles;
private ResolvableHelper(Handle[] selectedHandles) {
this.selectedHandles = selectedHandles;
}
public Object readResolve() {
try {
DemoTopComponent result = DemoTopComponent.getDefault();
String path;
int noOfHandles = selectedHandles.length;
Node rootNode = result.getExplorerManager().getRootContext();
Node foundNode = null;
Node[] allFoundNodes = new Node[noOfHandles];//We build up an array of found nodes:
for (int i = 0; i < noOfHandles; i++) {
Handle handle = selectedHandles[i];
path = handle.getNode().getDisplayName();
foundNode = NodeOp.findPath(rootNode, new String[]{path});
if (foundNode != null) {
allFoundNodes[i] = foundNode;
}
}//Then we select the array, which means each node is selected:
if (allFoundNodes != null) {
try {
result.getExplorerManager().setSelectedNodes(allFoundNodes);
} catch (PropertyVetoException ex) {
Exceptions.printStackTrace(ex);
}
}
return result;
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
return null;
}
}

However, in real life your children would probably have children too. (And your children's children would have children, ad nauseum.) How to serialize the entire hierarchy of selections from parent to child to grandchild and so on? Below you see my Marilyn Monroe window (search this blog for all the code, which is definitely somewhere), but this time the nodes that are selected below are selected at start up, i.e., automatically, because I serialized them at the time the application shut down:

Below is all the relevant code. Instead of serializing the entire set of selected nodes, we only serialize the first one. The cool thing is that when you serialize a node, you store the COMPLETE node, which means that all the information on the node is available to you, such as who its parent is! So, when the application restarts, we get the parent of the serialized node and, based on whether the parent is named 'Root' (which is the name of the hidden root node of the explorer view), we either select only the node or also the parent node:

@Override
public Object writeReplace() {
Handle childHandle = NodeOp.toHandles(em.getSelectedNodes())[0];
return new ResolvableHelper(childHandle);
}
public final static class ResolvableHelper implements Serializable {
private static final long serialVersionUID = 1L;
public Handle parentHandle;
public Handle childHandle;
private ResolvableHelper(Handle childHandle) {
try {
this.childHandle = childHandle;
this.parentHandle = childHandle.getNode().getParentNode().getHandle();
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
}
public Object readResolve() {
try {
MarilynTopComponent result = MarilynTopComponent.getDefault();
String parentName = parentHandle.getNode().getDisplayName();
String childName = childHandle.getNode().getDisplayName();
Node root = result.getExplorerManager().getRootContext();
Node parentNode = null;
Node childNode = null;//We know a movie has been selected if the parent is not named 'Root',
//which is the name of the hidden root node of the explorer view,
//so we find two nodes and select both:

if (!parentName.equals("Root")) {
parentNode = NodeOp.findPath(root, new String[]{parentName, childName});
childNode = NodeOp.findPath(root, new String[]{parentName});
result.getExplorerManager().setSelectedNodes(new Node[]{childNode, parentNode});
} //If the parent is 'Root', then we're dealing with a category,
//so we only need to find one node, the child of the 'Root', which we then select:

else {
childNode = NodeOp.findPath(root, new String[]{childName});
result.getExplorerManager().setSelectedNodes(new Node[]{childNode});
}
return result;
} catch (PropertyVetoException ex) {
Exceptions.printStackTrace(ex);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
return null;
}
}

This principle could be extended for a larger hierarchy of nodes and, if you don't only serialize a single node, your user could potentially see many hierarchies of selected nodes at the time that the application restarts.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.