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"/>
</file>
</folder>
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"/>
</file>
</folder>
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:
@Override
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:
ListtempList = 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:
tempList.add(descriptionAttribute);
}//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:
ctc.requestActive();
}
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.
Too much work. Use regular \*.instance files such as:
<file name="org-cms-multiview-source-SourceMultiviewDescription.instance">
<attr name="position" intvalue="200"/>
</file>
and then get them all with a single call:
MultiViewDescription[] descriptionArray = Lookups.forPath("multiviews").lookupAll(MultiViewDescription.class).toArray(new MultiViewDescription[0]);
Nice,
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.