Now here's a pretty cool piece of code.
Let's imagine you're populating a node hierarchy from a database. In addition, you want to populate the same node hierarchy from the filesystem because you're using @ConvertAsJavaBean to serialize a new business object whenever the user steps through a wizard to create a new customer. At that point, i.e., when Finish is clicked, the .settings file is created in the userdir because maybe the user doesn't want to save the new object as soon as it is created.
So now you need a way to visually distinguish between nodes built from objects in the database versus nodes built from objects in the layer.
Here's how, thanks to Ernest from the course in Stellenbosch. (As the trainer, I set the task but couldn't completely figure out the answer myself.) Look at the code below. We listen for new objects in the layer, at which point we refresh the node hierarchy, i.e., refresh calls createKeys. In createNodeForKey, a FilterNode is used to add an asterisk to the display name of the node, if the underlying object is found in the result object (i.e., in that case, it doesn't come from the database): public class BusAcctChildFactory extends ChildFactory< BusAcct> implements LookupListener { private final Result< BusAcct> result; private InstanceContent ic; public BusAcctChildFactory() { //Here we're listening to a folder in the layer //for new .settings files, which are //serialized from 'BusAcct' business object, //via @ConvertAsJavaBean: result = Lookups.forPath("BusinessAccounts").lookupResult(BusAcct.class); result.addLookupListener(this); resultChanged(new LookupEvent(result)); } @Override public void resultChanged(LookupEvent ev) { refresh(true); } @Override protected boolean createKeys(List< BusAcct> toPopulate) { //Populate the list from the db: EntityManager em = Persistence.createEntityManagerFactory("AMSWinJPU"). createEntityManager(); em.getTransaction().begin(); Query query = em.createQuery("SELECT c FROM BusAcct c"); List< BusAcct> resultList = query.getResultList(); for (BusAcct busAcct : resultList) { toPopulate.add(busAcct); } //Populate the list from the layer: Collection< ? extends BusAcct> busAcctsFromFS = result.allInstances(); for (BusAcct busAcct : busAcctsFromFS) { toPopulate.add(busAcct); } return true; } @Override protected Node createNodeForKey(BusAcct key) { //Create new InstanceContent per Node: ic = new InstanceContent(); ic.add(key); BusAcctNode node = null; try { node = new BusAcctNode(ic); //if the key is from the layer, //which we can check by seeing //if the current object is in the result, //create a FilterNode and mark the //display name of the //object from the layer as not being //saved in the database: if (result.allInstances().contains(key)) { return new FilterNode(node) { @Override public String getDisplayName() { return "*" + super.getDisplayName(); } }; } } catch (IntrospectionException ex) { Exceptions.printStackTrace(ex); } return node; } }
Thanks Ernest! We'll be getting more tips and tricks from him on NetBeans Zone soon.


Read More about [Constructing Nodes from the Layer and from a Database...