NetBeans Code Snippet Module Tutorial
| This tutorial needs a review. You can edit it in GitHub following these contribution guidelines. | 
This tutorial demonstrates how to create and add code snippets to the HTML/JSP Component Palette. Code snippets are small pieces of code that can be dragged from a component palette and dropped in the Source Editor. They serve to speed up coding. The HTML/JSP Component Palette has several code snippets already, but you might want to add some additional ones and share them with others.
- 
Scenario 1: Simple Palette Items
 - 
Scenario 2: Complex Palette Items
 
For troubleshooting purposes, you are welcome to download the completed tutorial source code.
Introduction to Code Snippets
To create a code snippet, you use the NetBeans Palette API. A code snippet requires the following files:
- 
A Java class that defines the piece of code to be dragged into the Source Editor.
 - 
A display name for the palette item.
 - 
A tooltip for the palette item.
 - 
A 16x16 pixel image for the 'Small Icon' display.
 - 
A 32x32 pixel image for the 'Big Icon' display.
 
After you have created or added the above files to the NetBeans module, you declare them in a resource declaration XML file, which you register in the NetBeans System Filesystem by using the  layer.xml  file.
You will learn about two different scenarios in this tutorial. The first scenario is simple, requiring no coding, and is useful if you do not need a customizer to appear when the palette item is dropped. The second scenario is more complex, and therefore more flexible, requiring you to provide Java code to define a customizer.
Scenario 1: Simple Palette Items
Before you start writing the module, you have to make sure you that your project is set up correctly. The IDE provides a wizard that sets up all the basic files needed for a module.
Creating the Module Project
- 
Choose File > New Project (Ctrl+Shift+N). Under Categories, select NetBeans Modules. Under Projects, select Module. Click Next.
 
- 
In the Name and Location panel, type
NewSnippets1in the Project Name field. Change the Project Location to any directory on your computer. Click Next. 
- 
In the Basic Module Configuration panel, type
org.netbeans.modules.newsnippets1in Code Name Base. Click Finish. 
The IDE creates the  NewSnippets1  project. The project contains all of your sources and project metadata, such as the project’s Ant build script. The project opens in the IDE. You can view its logical structure in the Projects window (Ctrl-1) and its file structure in the Files window (Ctrl-2).
Defining and Registering the Code Snippet
You need to create an XML file that defines the code snippet, together with a registration in the XML layer file.
- 
Right-click the
org.netbeans.modules.newsnippets1package, choose New | Other and then Java | Java Package Info. Click Next and then Finish. 
- 
Right-click the Libraries node in the Projects window, click Add Module Dependency, and set a dependency on Common Palette.
 
- 
Define the
package-info.javaclass as follows. 
@PaletteItemRegistration
(
         paletteid = "HTMLPalette",
         category = "HTML",
         itemid = "BR",
         icon32 = "org/netbeans/modules/newsnippets1/BR32.png",
         icon16 = "org/netbeans/modules/newsnippets1/BR16.png",
         body = "<br>",
         name = "New Line",
         tooltip = "<br>")
package org.netbeans.modules.newsnippets1;
import org.netbeans.spi.palette.PaletteItemRegistration;
- 
Add two icons to the module, such as these below, in locations defined by the
icon16element and theicon32element above: 
- 
Compile the file or build the module. Then open the Files window (Ctrl-2) and go to build/classes/META-INF/generated-layer.xml and notice that the following XML tags have been generated, which register your new palette item, via the annotation you created above.
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN"
                            "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
<filesystem>
    <folder name="HTMLPalette">
        <folder name="HTML">
            <file name="BR.xml">
                <![CDATA[<!DOCTYPE editor_palette_item
                    PUBLIC '-//NetBeans//Editor Palette Item 1.1//EN'
                    'http://www.netbeans.org/dtds/editor-palette-item-1_1.dtd'>
                <editor_palette_item version="1.1">
                    <body><![CDATA[<br>]]]]><![CDATA[> </body>
                    <icon16 urlvalue="org/netbeans/modules/newsnippets1/BR16.png" />
                    <icon32 urlvalue="org/netbeans/modules/newsnippets1/BR32.png" />
                    <inline-description>
                        <display-name>New Line</display-name>
                        <tooltip> <![CDATA[ <br>]]]]><![CDATA[></tooltip>
                    </inline-description>
                </editor_palette_item>]]>
            </file>
        </folder>
    </folder>
</filesystem>
Run the module. Open an HTML file. In the Palette (Ctrl-Shift-8), notice an item named "New Line". Drag it into the HTML file and drop it. You should see a BR tag added at the point where you dropped the item.
Scenario 2: Complex Palette Items
Before you start writing the module, you have to make sure you that your project is set up correctly. The IDE provides a wizard that sets up all the basic files needed for a module.
Creating the Module Project
- 
Choose File > New Project (Ctrl+Shift+N). Under Categories, select NetBeans Modules. Under Projects, select Module. Click Next.
 
- 
In the Name and Location panel, type
NewSnippets2in the Project Name field. Change the Project Location to any directory on your computer. Click Next. 
- 
In the Basic Module Configuration panel, type
org.netbeans.modules.newsnippets2in Code Name Base. Click Finish. 
The IDE creates the  NewSnippets2  project. The project contains all of your sources and project metadata, such as the project’s Ant build script. The project opens in the IDE. You can view its logical structure in the Projects window (Ctrl-1) and its file structure in the Files window (Ctrl-2).
Specifying the Module’s Dependencies
You will need to use several classes that belong to the NetBeans APIs. Each has to be declared as a module dependency. Use the Project Properties dialog box for this purpose, as described below.
- 
In the Projects window, right-click the
NewSnippets2project node and choose Properties. In the Project Properties dialog box, click Libraries. 
1. For each of the following, click "Add…", select the name from the Module list, and then click OK to confirm it:
- 
Common Palette
 - 
Text API
 - 
Utilities API
 
Click OK to exit the Project Properties dialog box.
- 
In the Projects window, expand the Important Files node, double-click the Project Metadata node, and note that the APIs you selected have been declared as module dependencies.
 
Coding the Code Snippet
In this section, you create  BR.java , which defines a code snippet for an HTML line break. By implementing the   ActiveEditorDrop  class, you let the NetBeans APIs provide the infrastructure for a palette item for NetBeans editors. You also create  HTMLPaletteUtilities.java , which defines the insertion of the tag in the editor.
- 
Right-click the
org.netbeans.modules.newsnippets2node and choose New > Java Class. TypeBRin Class Name, make sure that theorg.netbeans.modules.newsnippets2package is selected in the Package drop-down list, and click Finish. 
- 
Replace the default content of the
BR.javafile with the following: 
package org.netbeans.modules.newsnippets2;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import org.netbeans.modules.newsnippets2.HTMLPaletteUtilities;
import org.openide.text.ActiveEditorDrop;
public class BR implements ActiveEditorDrop {
    public BR() {
    }
    private String createBody() {
        String Br = "<br>";
        return Br;
    }
    @Override
    public boolean handleTransfer(JTextComponent targetComponent) {
        String body = createBody();
        try {
            HTMLPaletteUtilities.insert(body, targetComponent);
        } catch (BadLocationException ble) {
            return false;
        }
        return true;
    }
}
A red error message remains because you have not created the  HTMLPaletteUtilities  class yet, which you will do in the next section.
Defining the Insertion
In this section, you create the  HTMLPaletteUtilities  class, which defines the place where the snippet will be dropped.
- 
Right-click the
org.netbeans.modules.newsnippets2node and choose New > Java Class. TypeHTMLPaletteUtilitiesin Class Name, make sure that theorg.netbeans.modules.newsnippets2package is selected in the Package drop-down list, and click Finish. 
- 
Replace the default content of the
HTMLPaletteUtilities.javafile with the following: 
package org.netbeans.modules.newsnippets2;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.StyledDocument;
import org.openide.text.NbDocument;
public class HTMLPaletteUtilities {
    public static void insert(final String s, final JTextComponent target) throws BadLocationException {
        final StyledDocument doc = (StyledDocument)target.getDocument();
        class AtomicChange implements Runnable {
            @Override
            public void run() {
                Document value = target.getDocument();
                if (value == null)
                    return;
                try {
                    insert(s, target, doc);
                } catch (BadLocationException e) {}
            }
        }
        try {
            NbDocument.runAtomicAsUser(doc, new AtomicChange());
        } catch (BadLocationException ex) {}
    }
    private static int insert(String s, JTextComponent target, Document doc) throws BadLocationException {
        int start = -1;
        try {
            //firstly, find selected text range:
            Caret caret = target.getCaret();
            int p0 = Math.min(caret.getDot(), caret.getMark());
            int p1 = Math.max(caret.getDot(), caret.getMark());
            doc.remove(p0, p1 - p0);
            //then, replace selected text range with the inserted one:
            start = caret.getDot();
            doc.insertString(start, s, null);
        } catch (BadLocationException ble) {}
        return start;
    }
}
Declaring the Code Snippet
The NetBeans Editor Palette Item DTD is used to declare the  ActiveEditorDrop  class, the icons, the display name, and the tooltip.
- 
Right-click the
org.netbeans.modules.newsnippets2package node and choose New > Other. Select XML Document in the XML folder and click Next. TypeBRin File Name. Type\resourcesat the end ofsrc\org\netbeans\modules\newsnippets2in Folder. Click Next and then click Finish. 
- 
Replace the default content of the
BR.xmlfile with the following: 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE editor_palette_item PUBLIC "-//NetBeans//Editor Palette Item 1.0//EN"
  "https://netbeans.org/dtds/editor-palette-item-1_0.dtd">
<editor_palette_item version="1.0">
    <class name="org.netbeans.modules.newsnippets2.BR" />
    <icon16 urlvalue="org/netbeans/modules/newsnippets2/resources/BR16.png" />
    <icon32 urlvalue="org/netbeans/modules/newsnippets2/resources/BR32.png" />
    <description localizing-bundle="org.netbeans.modules.newsnippets2.Bundle"
               display-name-key="NAME_html-BR"
               tooltip-key="HINT_html-BR" />
</editor_palette_item>
Instead of the above, you can use the 1.1 DTD, where you can define the display name and tooltip without using a properties file. Below, only the difference with the previous XML file definition is highlighted:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE editor_palette_item PUBLIC "-//NetBeans//Editor Palette Item 1.1//EN"
  "https://netbeans.org/dtds/editor-palette-item-1_1.dtd">
<editor_palette_item version="1.0">
    <class name="org.netbeans.modules.newsnippets2.BR" />
    <icon16 urlvalue="org/netbeans/modules/newsnippets2/resources/BR16.png" />
    <icon32 urlvalue="org/netbeans/modules/newsnippets2/resources/BR32.png" />
    <inline-description>
       <display-name>New Line</display-name>
       <tooltip> <![CDATA[ <br>  ]]></tooltip>
    </inline-description>
</editor_palette_item>
| You can choose either of the two approaches above, depending on your requirements. | 
- 
Add a 16x16 pixel icon and a 32x32 pixel icon to the new
resourcesfolder. Name themBR16.pngandBR32.png. They can also be in other icon formats, such as GIF or JPG. Make sure that the resource is correctly declared in theBR.xmlfile. You can right-click them here and then save them to your module’s source structure: 
- 
If you want to use a properties file for declaring the palette item’s display name and tooltip, which implies that you are using the 1.0 DTD, add the following to the
Bundle.propertiesfile: 
Registering the Code Snippet
The  layer.xml  file registers the user interface elements of your module in your application, which in this case is the IDE. Here, we need to register the palette item in the  layer.xml  file so that the item will appear in the HTML Palette.
- 
Right-click the
org.netbeans.modules.newsnippets2package node and choose New > Other. Select Module Development > XML Layer. Click Next and then click Finish. 
- 
Add the following tags to the
layer.xmlfile, between the<filesystem>tags: 
<folder name="HTMLPalette">
   <folder name="HTML">
      <file name="BR.xml" url="resources/BR.xml">
         <attr name="position" intvalue="150"/>
      </file>
   </folder>
</folder>
Building and Installing the Code Snippet
Now we need to think about installation and distribution. Install and try out the code snippet, by following the steps below.
- 
In the Projects window, right-click the
NewSnippets2project and choose Run. The module is built and installed in a new instance of NetBeans IDE. 
- 
Create a new HTML file in the IDE. When the HTML file opens, it displays the Component Palette (Ctrl-Shift-8) with one additional code snippet, called "New Line", with a tooltip that displays the result of drag-and-dropping the item:
 
- 
Drag the 'New Line' item into the Source Editor and notice that a new
<br>tag is inserted at the cursor. 
Adding a Customizer
Optionally, you can let a  JPanel  appear when the palette item is dropped. In the  JPanel , you can let the user define values for attributes that relate to the snippet that is about to be created. However, note that adding such a customizer is optional. In the case of a line break, which is what we are creating in this tutorial, there are no attributes that relate to the BR tag. For that reason, to illustrate the customizer functionality, we will add a comment before the BR tag, by means of a customizer.
If you check out the   html  module from the NetBeans sources, you will find many examples of customizers in the   org/netbeans/modules/html/palette/items  package.
 | 
- 
Add a dependency on the NetBeans
Dialogs APIand theUI Utilities API. 
1.
Use the New File dialog (Ctrl-N) to create a  JPanel  in the  org.netbeans.modules.newsnippets2  package. Name it  BRCustomizer .
- 
Use the Pallette (Ctrl-Shift-8) to drag and drop a
JLabeland aJTextFieldonto theJPaneland arrange theJPanelas follows: 
- 
You will need to declare the following at the top of the
BRCustomizerclass: 
private Dialog dialog = null;
private DialogDescriptor descriptor = null;
private boolean dialogOK = false;
private BR br;
private JTextComponent target;
- 
Rewrite the
BRCustomizerconstructor as follows: 
public BRCustomizer(BR br, JTextComponent target) {
    this.br = br;
    this.target = target;
    initComponents();
}
- 
In your
BRCustomizerclass, add this method, so that, in the next steps, you can open the customizer from yourActiveEditorDropimplementation class: 
@NbBundle.Messages({
    "LBL_Customizer_InsertPrefix=Insert",
    "NAME_html-BR=Line Break"})
public boolean showDialog() {
    dialogOK = false;
    descriptor = new DialogDescriptor(this, Bundle.LBL_Customizer_InsertPrefix(), true,
            DialogDescriptor.OK_CANCEL_OPTION, DialogDescriptor.OK_OPTION,
            new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (descriptor.getValue().equals(DialogDescriptor.OK_OPTION)) {
                        evaluateInput();
                        dialogOK = true;
                    }
                    dialog.dispose();
                }
            });
    dialog = DialogDisplayer.getDefault().createDialog(descriptor);
    dialog.setVisible(true);
    return dialogOK;
}
- 
Define the
evaluateInput()method, which is called in theshowDialog()method above, as follows: 
private void evaluateInput() {
   String comment = jTextField1.getText();
   br.setComment(comment);
}
- 
Hook your customizer into the
ActiveEditorDropimplementation class as follows (only the lines that are changed are highlighted below): 
package org.netbeans.modules.newsnippets2;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import org.netbeans.modules.newsnippets2.HTMLPaletteUtilities;
import org.openide.text.ActiveEditorDrop;
public class BR implements ActiveEditorDrop {
    private String comment = "";
    public BR() {
    }
    private String createBody() {
        comment = getComment();
        String Br = "<!-- " + comment + " -->"
                + "\n        <br>";
        return Br;
    }
    @Override
    public boolean handleTransfer(JTextComponent targetComponent) {
        BRCustomizer c = new BRCustomizer(this, targetComponent);
        boolean accept = c.showDialog();
        if (accept) {
            String body = createBody();
            try {
                HTMLPaletteUtilities.insert(body, targetComponent);
            } catch (BadLocationException ble) {
                accept = false;
            }
        }
        return accept;
    }
    public String getComment() {
        return comment;
    }
    public void setComment(String comment) {
        this.comment = comment;
    }
}
Run the module. Open an HTML file. In the Palette (Ctrl-Shift-8), notice the item named "New Line". Drag it into the HTML file and drop it. You should see your customizer. Enter something, finish the dialog, and the BR tag is added, together with a comment, at the point where you dropped the item.
Next Steps
For more information about creating and developing NetBeans modules, see the following resources: