I was completely lost on how to use a wizard together with Freemarker templates. I did lots of googling in 2 days but only found outdated tutorials (for Netbeans 6.9, where layer.xml still exists), some briefly mentioned comments and tiny code snippets. Combining all those in my code chimpanzee brain, I have got a working and updated (for Netbeans 7.2) solution on how to use wizards together with Freemarker templates.
Adding a Wizard
Assuming you have followed the steps in NFTMT and get a working a file template, the first thing you need to do before adding a wizard is to delete the package-info.java file. Sorry, the wizards don't like package-info or maybe I, a mere code chimpanzee, can't please the wizards enough to work with package-info.Add a wizard to the module project by right-clicking on org.myorg.additionalfiletemplates and choosing New > Wizard.
Select New File in wizard type dialog since the module is all about creating a new file. Put any number of wizard panels you want in Number of Wizard Panels textbox. For this tutorial, we will just put 1. Going Next, you will need to add Class Name Prefix and Display Name. Here you will need to select a icon file of 16x16 pixels so prepare it beforehand.
After clicking Finish, you will see 4 new entries added to your project: a VisualPanel, a WizardIterator, a WizardPanel and an html file. You can delete the newly added hTMLTemplate.html file because you will be using Description.html for template description.
In this tutorial, we will reuse Netbeans' new HTML file dialog with an extra text field added to enter the title of the HTML page. Firstly, we will open the HTMLTemplateVisualPanel1.java to add a label and a text field. You will need GUI Builder plugin for Java SE installed in your Netbeans IDE to add label and text field graphically as shown. Change the variable names
jLabel1
and jTextField1
to jlblTitle
and jtxtTitle
respectively and edit text on label to Title:.
Make changes as follows to
HTMLTemplateVisualPanel1.java.
static final String TITLE = "Title";
...
@Override
public String getName() {
return "Name, Location and Title";
}
public String getTitle() {
return jtxtTitle.getText();
}
In HTMLTemplateWizardPanel1.java:
@Override
public void storeSettings(WizardDescriptor wiz) {
// use wiz.putProperty to remember current panel state
wiz.putProperty(HTMLTemplateVisualPanel1.TITLE, getTitleFromVisualPanel());
}
private String getTitleFromVisualPanel() {
return getComponent().getTitle();
}
Then, add "Project API", "Project UI API", "Nodes API", "Lookup API" and "File System API" libraries to the Netbeans module project. And add content="%Your Template File%" and scriptEngine="freemarker" values in @TemplateRegistration above HTMLTemplateWizardIterator class declaration.
@TemplateRegistration(
folder = "JSP_Servlet",
displayName = "#HTMLTemplateWizardIterator_displayName",
iconBase = "org/myorg/additionalfiletemplates/html.png",
content = "HTML.html",
description = "Description.html",
scriptEngine = "freemarker")
@Messages("HTMLTemplateWizardIterator_displayName=HTML with Title")
public final class HTMLTemplateWizardIterator implements WizardDescriptor.InstantiatingIterator<WizardDescriptor> {
Change getPanels() function in HTMLTemplateWizardIterator.java as follows:
private List<WizardDescriptor.Panel<WizardDescriptor>> getPanels() {
if (panels == null) {
panels = new ArrayList<WizardDescriptor.Panel<WizardDescriptor>>();
// Change to default new file panel and add our panel at bottom
Project p = Templates.getProject(wizard);
SourceGroup[] groups = ProjectUtils.getSources(p).getSourceGroups(Sources.TYPE_GENERIC);
// SimpleTargetChooser is the default new file panel,
// Add our panel at the bottom
WizardDescriptor.Panel<WizardDescriptor> advNewFilePanel = Templates.buildSimpleTargetChooser(p, groups).bottomPanel(new HTMLTemplateWizardPanel1()).create();
panels.add(advNewFilePanel);
String[] steps = createSteps();
for (int i = 0; i < panels.size(); i++) {
Component c = panels.get(i).getComponent();
if (steps[i] == null) {
// Default step name to component name of panel. Mainly
// useful for getting the name of the target chooser to
// appear in the list of steps.
steps[i] = c.getName();
}
if (c instanceof JComponent) { // assume Swing components
JComponent jc = (JComponent) c;
jc.putClientProperty(WizardDescriptor.PROP_CONTENT_SELECTED_INDEX, i);
jc.putClientProperty(WizardDescriptor.PROP_CONTENT_DATA, steps);
jc.putClientProperty(WizardDescriptor.PROP_AUTO_WIZARD_STYLE, true);
jc.putClientProperty(WizardDescriptor.PROP_CONTENT_DISPLAYED, true);
jc.putClientProperty(WizardDescriptor.PROP_CONTENT_NUMBERED, true);
}
}
}
return panels;
}
After that, edit the instantiate() method to read user-defined values and process the FreeMarker Template.
@Override
public Set<?> instantiate() throws IOException {
FileObject createdFile = null;
// Read Title from wizard
String HtmlTitle = (String) wizard.getProperty(HTMLTemplateVisualPanel1.TITLE);
// FreeMarker Template will get its variables from HashMap.
// HashMap key is the variable name.
Map args = new HashMap();
args.put("title", HtmlTitle);
//Get the template and convert it:
FileObject template = Templates.getTemplate(wizard);
DataObject dTemplate = DataObject.find(template);
//Get the package:
FileObject dir = Templates.getTargetFolder(wizard);
DataFolder df = DataFolder.findFolder(dir);
//Get the class:
String targetName = Templates.getTargetName(wizard);
//Define the template from the above,
//passing the package, the file name, and the map of strings to the template:
DataObject dobj = dTemplate.createFromTemplate(df, targetName, args);
//Obtain a FileObject:
createdFile = dobj.getPrimaryFile();
// Return the created file.
return Collections.singleton(createdFile);
}
Finally, use title variable in FreeMarker Template file HTML.html.
<!DOCTYPE html>
<html>
<head>
<title>${title}</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>TODO write content</div>
</body>
</html>
"Clean and Build" the project and "Install/Reload in Development IDE" to test your new module (New File > Web > HTML with Title). You will see the ${title} is replaced with whatever you entered in the wizard text field. That's all, folks!
(Please check out Geertjan's blog https://blogs.oracle.com/geertjan/ also if you want to know more about Netbeans module development. )