Geertjan's Blog

  • March 5, 2013

Synchronizing an Editor Window with a Viewer Window

Geertjan Wielenga
Product Manager

Now that we're able to open a TopComponent per Node, let's... synchronize back to the viewer window from the editor window.

Below you can see that right now there's a TopComponent open for each of the Nodes. However, wouldn't it be nice if selecting one of the open TopComponents would cause the related Node to automatically be selected? In other words, below I have clicked on the "professor" window, which automatically results in the "professor" node in the viewer window being highlighted:

How to achieve this? Via a very elegant NetBeans Platform mechanism.

  1. Create a "Synchronizable" Capability. Here it is, in the domain module:

    package org.person.domain.capabilities;
    import org.person.domain.Person;
    public interface Synchronizable {
    Person getPerson();
  2. Add an Implementation of the Capability to the Node Lookup. You can see that the Synchronizable capability has been added to the Lookup of the Node, in the Node constructor, as shown in the highlighted bit below:

    private PersonNode(final Person person, InstanceContent ic) throws IntrospectionException {
    super(person, Children.LEAF, new AbstractLookup(ic));
    ic.add(new Openable() {
    public void open() {
    TopComponent tc = findTopComponent(person);
    if (tc == null) {
    tc = new PersonEditorTopComponent(person);
    });ic.add(new Synchronizable() {
    public Person getPerson() {
    return person;


    Note: There's no 'naked' Person object in the Node Lookup, only a Person object wrapped in a capability. This way, you have more control over the Object; since various other parts of the application may (and currently are already) be listening/responding to Person objects, using a capability gives you a fresh access point to the Object.

  3. Retrieve the Capability from the Lookup in the Viewer. In the Viewer window, implement LookupListener, listen for the current Person object, and set the Node that has the same Person object in the Synchronizable in its Lookup to be the selected Node in the ExplorerManager:

    public void resultChanged(LookupEvent le) {
    Collection<? extends Person> p = personResult.allInstances();
    if (p.size() == 1) {
    Person currentPerson = p.iterator().next();
    for (Node node : em.getRootContext().getChildren().getNodes()) {
    if (node.getLookup().lookup(Synchronizable.class).getPerson() == currentPerson) {
    try {
    em.setSelectedNodes(new Node[]{node});
    } catch (PropertyVetoException ex) {

And these are the three files created/changed during the above instructions:

Source code of the current state of the sample above:


Join the discussion

Comments ( 1 )
  • Derek Witt Friday, March 8, 2013

    When we were initially investigating using Nodes for our internal app, we looked at BeanNode. Unfortunately, one can't replace the object in BeanNode after instantiation.

    Having a wrapper class such as the aforementioned Synchronizable/capability is a great workaround for BeanNode. One can add events (e.g. PropertyChangeSupport) to that wrapper class.

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