Geertjan's Blog

  • January 9, 2011

Modular/Decoupled Multiview Component

Geertjan Wielenga
Product Manager
Let's create a modular multiview component. The assumption is that you want to decouple the views in a multiview component from each other, each being provided by different contributors, potentially. To get started, set up a multiview component as described in the File Type Integration Tutorial.

Next, let's put one tab of the multiview in one module, with the second tab in a second module. In the first module's layer:

<folder name="multiviews">
<file name="org-cms-multiview-general-GeneralMultiviewDescription">
<attr name="description" newvalue="org.cms.multiview.general.GeneralMultiviewDescription"/>
<attr name="position" intvalue="100"/>

The class that will be created, i.e., "org.cms.multiview.general.GeneralMultiviewDescription", is a class that implements "org.netbeans.core.spi.multiview.MultiViewDescription".

Now, I have a second module. In the layer of the second module, I register my second tab:

<folder name="multiviews">
<file name="org-cms-multiview-source-SourceMultiviewDescription">
<attr name="description" newvalue="org.cms.multiview.source.SourceMultiviewDescription"/>
<attr name="position" intvalue="200"/>

Now, in a third module (i.e., one that doesn't know anything about the two modules above) we need an action to open a CloneableTopComponent (i.e., a multiview component), while loading the tabs from the two separate modules. Here's the "actionPerformed" of this action:

public void actionPerformed(ActionEvent ev) {//Get the "multiviews" folder, which we defined in the layer files above:
FileObject multiviewsFolder = FileUtil.getConfigFile("multiviews");//Get the children of the folder:
FileObject[] kids = multiviewsFolder.getChildren();//Set the array of multiview descriptions to equal the number of "multiviews" children:
MultiViewDescription[] descriptionArray = new MultiViewDescription[kids.length];//Create a temporary list for converting to our type:
List tempList = new ArrayList();//Get each "multiviews" child in the specified order via "position" in the layer:
for (FileObject kid : FileUtil.getOrder(Arrays.asList(kids), true)) {//Get the attribute named "description":
MultiViewDescription descriptionAttribute = (MultiViewDescription) kid.getAttribute("description");//Add the attribute to the temporary list:
}//Iterate through the temporary list and add to the array of multiview descriptions:
for (int i = 0; i < tempList.size(); i++) {
descriptionArray[i] = tempList.get(i);
}//Create a new CloneableTopComponent, using the array of multiview descriptions,
//the first of which will be the first tab that the user sees:

CloneableTopComponent ctc = MultiViewFactory.createCloneableMultiView(
descriptionArray, descriptionArray[0]);//Open the multiview component:
ctc.open();//Make the multiview component the active component:

Now I remember why I didn't blog about this earlier: I'm sure I don't need a temporary list, that's what makes the code a bit convoluted. I should simply be able to use the array of multiview descriptions, without using the "templist", which is only there to feed the array of multiview descriptions.

Join the discussion

Comments ( 2 )
  • Jesse Glick Monday, January 10, 2011

    Too much work. Use regular \*.instance files such as:

    <file name="org-cms-multiview-source-SourceMultiviewDescription.instance">

    <attr name="position" intvalue="200"/>


    and then get them all with a single call:

    MultiViewDescription[] descriptionArray = Lookups.forPath("multiviews").lookupAll(MultiViewDescription.class).toArray(new MultiViewDescription[0]);

  • Daniele Tuesday, January 11, 2011


    a newbie question: now how I could pass a DataObject to the instantiated MultiViewDescription? Before, I was simply passing the needed object to the constructors.

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