X

Geertjan's Blog

  • November 29, 2005

Shadowing and Hiding in Layer XML Files in NetBeans IDE

Geertjan Wielenga
Product Manager
In the IDE, when you go to Tools > Palette Manager, you get two menu items—Swing/AWT Components and HTML/JSP Code Clips. Here's what the HTML/JSP Code Clips Palette Manager looks like:

Now, let's say you've created your own palette (as I've done for the jboss-web.xml file and the Manifest.mf file, as shown in the previous few blog entries). How would you add the code snippets in your palette to the Palette Manager? At first I didn't understand it, then I looked in the layer.xml files (plural)—because two layer.xml files are involved here. The first is the layer.xml file provided by the HTML module; the second is the layer.xml file provided by the JSP module. Together, the two layer.xml files specify that the code snippets defined by their modules belong to the same Palette Manager. How is this done? It's quite funny, if you like this kind of humour...
The place to start is to realize that the IDE makes use of something called shadow files. (Read here for details.) A shadow file is a link that points to an original file. It is useful in the layer.xml file, because often you need multiple instances of the same file. Instead of forcing the IDE to instantiate the same file multiple times, you create a shadow file that links to the original. As a result, the IDE creates the instance once only—and the related shadow files all say: "Hey, we'd like to use that instance too!" The HTML/JSP Code Clips Palette Manager is a case in point. Here's how its content is represented in the layer.xml file's logical view:

Notice how two of the folders have little squares in brackets? That means that they're shadow files. This means that the instances within the HTML and HTML_Forms folders are declared elsewhere—in fact, they're declared in the HTMLPalette folder (notice that here there are no little squares between brackets):

Now, back in the XML code, this is how the first part of the JSPPalette is declared:

<folder name="JSPPalette"><folder name="HTML.shadow">
<attr name="SystemFileSystem.localizingBundle"
stringvalue="org.netbeans.modules.web.core.palette.Bundle"/>
<attr name="originalFile" stringvalue="HTMLPalette/HTML"/>
</folder>
<folder name="HTML_Forms.shadow">
<attr name="SystemFileSystem.localizingBundle"
stringvalue="org.netbeans.modules.web.core.palette.Bundle"/>
<attr name="originalFile" stringvalue="HTMLPalette/HTML_Forms"/>
</folder>

<folder name="JSP">
<attr name="SystemFileSystem.localizingBundle"
stringvalue="org.netbeans.modules.web.core.palette.Bundle"/>
<file name="UseBean.xml"
url="nbresloc:/org/netbeans/modules/web/core/palette/items/resources/UseBean.xml" />
<file name="GetProperty.xml"
url="nbresloc:/org/netbeans/modules/web/core/palette/items/resources/GetProperty.xml" />
<file name="SetProperty.xml"
url="nbresloc:/org/netbeans/modules/web/core/palette/items/resources/SetProperty.xml" />
<file name="Choose.xml"
url="nbresloc:/org/netbeans/modules/web/core/palette/items/resources/Choose.xml" />
<file name="If.xml"
url="nbresloc:/org/netbeans/modules/web/core/palette/items/resources/If.xml" />
<file name="ForEach.xml"
url="nbresloc:/org/netbeans/modules/web/core/palette/items/resources/ForEach.xml" />
</folder>
...
...
...
</folder>

If you look at the folders that are in bold above, you see that they're shadow folders that point to original files—they're created somewhere else (in the HTML module) but referenced in the JSP module.

A second technique worth knowing about is that you can hide folders and files that belong to other modules. (An example of that was discussed in an earlier blog entry: How to Become Helpless in 5 Minutes.) By hiding folders and files, you have a lot of control over other modules. So, this is what I did (a technique I learnt by looking in the two layer.xml files mentioned above, one in the JSP module and the other in the HTML module) to add my JBoss code snippets to the JSP/HTML Code Clips Palette Manager:

  1. Make sure that the menu item named in your Bundle.properties file is the same name as used by the other two modules. So, in my Bundle.properties file, I had this value for the key that defines my menu item, which is the same value for the key used by the HTML module and the JSP module:

    ACT_OpenJbossddCustomizer=&HTML/JSP Code Clips

  2. Hide the other two actions (the action in the HTML module and the JSP module that displays the JSP/HTML Code Clips Palette Manager) and declare an instance of your own in your layer.xml file:

    <folder name="Menu">
    <folder name="Tools">
    <folder name="PaletteManager">
    <file name="org-netbeans-modules-jbosswebxml-palette-jbossddPaletteCustomizerAction.instance"/>
    <file name="org-netbeans-modules-html-palette-HTMLPaletteCustomizerAction.instance_hidden"/>
    <file name="org-netbeans-modules-web-core-palette-JSPPaletteCustomizerAction.instance_hidden"/>
    </folder>
    </folder>
    </folder>

    Notice the _hidden flags above? This is how you hide folders and files from other modules. (You can also let the IDE generate the above code for you—right-click a folder or file in the layer.xml file's logical view and choose Delete. That doesn't do anything scary—it just adds tags with _hidden flags to your own module's layer.xml file.)

  3. Finally, declare the resource declaration XML file for your module's code snippets and then declare all the other ones as shadow files:

    <folder name="JBOSSPalette">
    <folder name="JBoss">
    <attr name="SystemFileSystem.localizingBundle"
    stringvalue="org.netbeans.modules.jbosswebxml.Bundle"/>
    <file name="ContextRoot.xml"
    url="ContextRoot.xml"/>
    <file name="ResourceReference.xml"
    url="ResourceReference.xml"/>
    <file name="SecurityDomain.xml"
    url="SecurityDomain.xml"/>
    </folder>
    <folder name="HTML.shadow">
    <attr name="SystemFileSystem.localizingBundle"
    stringvalue="org.netbeans.modules.web.core.palette.Bundle"/>
    <attr name="originalFile"
    stringvalue="HTMLPalette/HTML"/>
    </folder>
    <folder name="HTML_Forms.shadow">
    <attr name="SystemFileSystem.localizingBundle"
    stringvalue="org.netbeans.modules.web.core.palette.Bundle"/>
    <attr name="originalFile"
    stringvalue="HTMLPalette/HTML_Forms"/>
    </folder>
    <folder name="JSP.shadow">
    <attr name="SystemFileSystem.localizingBundle"
    stringvalue="org.netbeans.modules.web.core.palette.Bundle"/>
    <attr name="originalFile"
    stringvalue="JSPPalette/JSP"/>
    </folder>
    <folder name="Database.shadow">
    <attr name="SystemFileSystem.localizingBundle"
    stringvalue="org.netbeans.modules.web.core.palette.Bundle"/>
    <attr name="originalFile"
    stringvalue="JSPPalette/Database"/>
    </folder>
    </folder>

    By taking the three simple steps above, you can get a very nice result—your new code clips are now integrated in the JSP/HTML Code Clips Palette Manager:

    Plus, take a look at what my component palette now looks like, but only for jboss-web.xml files:

    And now I'm waiting for someone to respond: "But why would you want your JBoss code clips in the JSP/HTML Code Clip Palette Manager? They don't belong there at all! They don't provide JSP or HTML code clips—they provide you with a bunch of XML code clips instead... And why would you want JSP and HTML code clips in your jboss-web.xml editor?" And my answer is... just for the fun of it.

Join the discussion

Comments ( 1 )
  • Business for sale Sunday, January 1, 2006
    Happy New Year to Everyone!
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.