diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8cf6ad8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/build/
+/nbproject/private/
\ No newline at end of file
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..7464e6d
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Tuupertunut
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..48daf72
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+# FXML templates
+
+Netbeans plugin for creating standalone FXML Nodes to JavaFX projects.
+
+This plugin adds two new creatable file types under the JavaFX category:
+
+### JavaFX FXML Node
+
+Creates two files. One FXML file and one Java class file which works as both the root and controller of the FXML. The Java file works as a standalone Node, meaning it can be added as a child to other Nodes.
+
+### JavaFX FXML Application
+
+Creates three files. A JavaFX application main class and one JavaFX FXML Node, as described in the previous section. The node is used as the root node of the application.
diff --git a/build.xml b/build.xml
new file mode 100644
index 0000000..c8a7c02
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+ Builds, tests, and runs the project tuupertunut.fxmltemplates.
+
+
diff --git a/manifest.mf b/manifest.mf
new file mode 100644
index 0000000..36d0747
--- /dev/null
+++ b/manifest.mf
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+AutoUpdate-Show-In-Client: true
+OpenIDE-Module: tuupertunut.fxmltemplates
+OpenIDE-Module-Layer: tuupertunut/fxmltemplates/layer.xml
+OpenIDE-Module-Localizing-Bundle: tuupertunut/fxmltemplates/Bundle.properties
+OpenIDE-Module-Needs: org.netbeans.api.templates.wizard, javax.script.ScriptEngine.freemarker
+OpenIDE-Module-Specification-Version: 1.0
+
diff --git a/nbproject/build-impl.xml b/nbproject/build-impl.xml
new file mode 100644
index 0000000..963f69d
--- /dev/null
+++ b/nbproject/build-impl.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nbproject/genfiles.properties b/nbproject/genfiles.properties
new file mode 100644
index 0000000..8b398b8
--- /dev/null
+++ b/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=3b0d48c4
+build.xml.script.CRC32=9e80c752
+build.xml.stylesheet.CRC32=a56c6a5b@2.72.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=3b0d48c4
+nbproject/build-impl.xml.script.CRC32=0e932cb4
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.72.1
diff --git a/nbproject/platform.properties b/nbproject/platform.properties
new file mode 100644
index 0000000..6cffef9
--- /dev/null
+++ b/nbproject/platform.properties
@@ -0,0 +1,12 @@
+cluster.path=\
+ ${nbplatform.active.dir}/apisupport:\
+ ${nbplatform.active.dir}/extide:\
+ ${nbplatform.active.dir}/harness:\
+ ${nbplatform.active.dir}/ide:\
+ ${nbplatform.active.dir}/java:\
+ ${nbplatform.active.dir}/javafx:\
+ ${nbplatform.active.dir}/nb:\
+ ${nbplatform.active.dir}/platform:\
+ ${nbplatform.active.dir}/profiler:\
+ ${nbplatform.active.dir}/websvccommon
+nbplatform.active=default
diff --git a/nbproject/project.properties b/nbproject/project.properties
new file mode 100644
index 0000000..c48e9be
--- /dev/null
+++ b/nbproject/project.properties
@@ -0,0 +1,5 @@
+auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml
+javac.source=1.8
+javac.compilerargs=-Xlint -Xlint:-serial
+nbm.module.author=Tuupertunut
+project.license=default
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644
index 0000000..c9fb922
--- /dev/null
+++ b/nbproject/project.xml
@@ -0,0 +1,128 @@
+
+
+ org.netbeans.modules.apisupport.project
+
+
+ tuupertunut.fxmltemplates
+
+
+
+ net.java.html
+
+
+
+ 1.3.0
+
+
+
+ net.java.html.json
+
+
+
+ 1.3.0
+
+
+
+ org.netbeans.api.templates
+
+
+
+ 1.7.1
+
+
+
+ org.netbeans.modules.java.project.ui
+
+
+
+ 1
+ 1.69.1
+
+
+
+ org.netbeans.modules.projectapi
+
+
+
+ 1
+ 1.66.1
+
+
+
+ org.netbeans.modules.projectuiapi
+
+
+
+ 1
+ 1.88.1.8
+
+
+
+ org.openide.awt
+
+
+
+ 7.67.1
+
+
+
+ org.openide.dialogs
+
+
+
+ 7.42.1
+
+
+
+ org.openide.filesystems
+
+
+
+ 9.10.1
+
+
+
+ org.openide.loaders
+
+
+
+ 7.66.1
+
+
+
+ org.openide.nodes
+
+
+
+ 7.45.1
+
+
+
+ org.openide.util
+
+
+
+ 9.7.1
+
+
+
+ org.openide.util.lookup
+
+
+
+ 8.33.1
+
+
+
+ org.openide.util.ui
+
+
+
+ 9.6.1
+
+
+
+
+
+
+
diff --git a/src/tuupertunut/fxmltemplates/BaseJavaIterator.java b/src/tuupertunut/fxmltemplates/BaseJavaIterator.java
new file mode 100644
index 0000000..20ac28a
--- /dev/null
+++ b/src/tuupertunut/fxmltemplates/BaseJavaIterator.java
@@ -0,0 +1,103 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2017 Tuupertunut.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package tuupertunut.fxmltemplates;
+
+import java.io.IOException;
+import java.util.Set;
+import javax.swing.event.ChangeListener;
+import org.netbeans.spi.java.project.support.ui.templates.JavaTemplates;
+import org.openide.WizardDescriptor;
+import org.openide.filesystems.FileObject;
+
+/**
+ *
+ * @author Tuupertunut
+ */
+public class BaseJavaIterator implements WizardDescriptor.InstantiatingIterator {
+
+ protected WizardDescriptor wizard;
+
+ private WizardDescriptor.InstantiatingIterator delegate;
+
+ public BaseJavaIterator() {
+ delegate = JavaTemplates.createJavaTemplateIterator();
+ }
+
+ @Override
+ public Set instantiate() throws IOException {
+ return delegate.instantiate();
+ }
+
+ @Override
+ public void initialize(WizardDescriptor wd) {
+ wizard = wd;
+ delegate.initialize(wd);
+ }
+
+ @Override
+ public void uninitialize(WizardDescriptor wd) {
+ wizard = null;
+ delegate.uninitialize(wd);
+ }
+
+ @Override
+ public WizardDescriptor.Panel current() {
+ return delegate.current();
+ }
+
+ @Override
+ public String name() {
+ return delegate.name();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return delegate.hasNext();
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return delegate.hasPrevious();
+ }
+
+ @Override
+ public void nextPanel() {
+ delegate.nextPanel();
+ }
+
+ @Override
+ public void previousPanel() {
+ delegate.previousPanel();
+ }
+
+ @Override
+ public void addChangeListener(ChangeListener cl) {
+ delegate.addChangeListener(cl);
+ }
+
+ @Override
+ public void removeChangeListener(ChangeListener cl) {
+ delegate.removeChangeListener(cl);
+ }
+}
diff --git a/src/tuupertunut/fxmltemplates/Bundle.properties b/src/tuupertunut/fxmltemplates/Bundle.properties
new file mode 100644
index 0000000..6289473
--- /dev/null
+++ b/src/tuupertunut/fxmltemplates/Bundle.properties
@@ -0,0 +1,7 @@
+FxmlNode_displayName=JavaFX FXML Node
+FxmlApp_displayName=JavaFX FXML Application
+OpenIDE-Module-Display-Category=JavaFX 2
+OpenIDE-Module-Long-Description=\
+ Adds templates for creating new JavaFX FXML Nodes and Applications.
+OpenIDE-Module-Name=FXML templates
+OpenIDE-Module-Short-Description=Adds templates for creating new JavaFX FXML Nodes and Applications.
diff --git a/src/tuupertunut/fxmltemplates/FxmlAppDescription.html b/src/tuupertunut/fxmltemplates/FxmlAppDescription.html
new file mode 100644
index 0000000..7136942
--- /dev/null
+++ b/src/tuupertunut/fxmltemplates/FxmlAppDescription.html
@@ -0,0 +1,8 @@
+
+
+
+
+
+ Creates new JavaFX application main class and a root Node using FXML.
+
+
diff --git a/src/tuupertunut/fxmltemplates/FxmlAppIterator.java b/src/tuupertunut/fxmltemplates/FxmlAppIterator.java
new file mode 100644
index 0000000..06a2c8f
--- /dev/null
+++ b/src/tuupertunut/fxmltemplates/FxmlAppIterator.java
@@ -0,0 +1,69 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2017 Tuupertunut.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package tuupertunut.fxmltemplates;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import org.netbeans.spi.project.ui.templates.support.Templates;
+import org.openide.filesystems.FileObject;
+import org.openide.loaders.DataFolder;
+import org.openide.loaders.DataObject;
+
+/**
+ *
+ * @author Tuupertunut
+ */
+public class FxmlAppIterator extends BaseJavaIterator {
+
+ @Override
+ public Set instantiate() throws IOException {
+ FileObject targetFolder = Templates.getTargetFolder(wizard);
+ FileObject mainTemplate = Templates.getTemplate(wizard);
+
+ /* Retrieving the node templates relative to the main template. */
+ FileObject rootNodeJavaTemplate = mainTemplate.getParent().getFileObject("FxmlNode.java");
+ FileObject rootNodeFxmlTemplate = mainTemplate.getParent().getFileObject("FxmlNode.fxml");
+
+ String mainClassName = Templates.getTargetName(wizard);
+ String rootNodeClassName = mainClassName + "Pane";
+ String rootNodeFxmlName = rootNodeClassName;
+
+ DataFolder targetFolderData = DataFolder.findFolder(targetFolder);
+ DataObject mainTemplateData = DataObject.find(mainTemplate);
+ DataObject rootNodeJavaTemplateData = DataObject.find(rootNodeJavaTemplate);
+ DataObject rootNodeFxmlTemplateData = DataObject.find(rootNodeFxmlTemplate);
+
+ DataObject createdMainFileData = mainTemplateData.createFromTemplate(targetFolderData, mainClassName, Collections.singletonMap("rootNodeName", rootNodeClassName));
+ DataObject createdRootNodeJavaFileData = rootNodeJavaTemplateData.createFromTemplate(targetFolderData, rootNodeClassName, Collections.singletonMap("fxmlName", rootNodeFxmlName));
+ DataObject createdRootNodeFxmlFileData = rootNodeFxmlTemplateData.createFromTemplate(targetFolderData, rootNodeFxmlName);
+
+ Set files = new HashSet<>();
+ files.add(createdMainFileData.getPrimaryFile());
+ files.add(createdRootNodeJavaFileData.getPrimaryFile());
+ files.add(createdRootNodeFxmlFileData.getPrimaryFile());
+ return files;
+ }
+}
diff --git a/src/tuupertunut/fxmltemplates/FxmlNodeDescription.html b/src/tuupertunut/fxmltemplates/FxmlNodeDescription.html
new file mode 100644
index 0000000..c730666
--- /dev/null
+++ b/src/tuupertunut/fxmltemplates/FxmlNodeDescription.html
@@ -0,0 +1,8 @@
+
+
+
+
+
+ Creates new JavaFX FXML-based Node. Includes both Java file and FXML file.
+
+
diff --git a/src/tuupertunut/fxmltemplates/FxmlNodeIterator.java b/src/tuupertunut/fxmltemplates/FxmlNodeIterator.java
new file mode 100644
index 0000000..a8c42f3
--- /dev/null
+++ b/src/tuupertunut/fxmltemplates/FxmlNodeIterator.java
@@ -0,0 +1,64 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2017 Tuupertunut.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package tuupertunut.fxmltemplates;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import org.netbeans.spi.project.ui.templates.support.Templates;
+import org.openide.filesystems.FileObject;
+import org.openide.loaders.DataFolder;
+import org.openide.loaders.DataObject;
+
+/**
+ *
+ * @author Tuupertunut
+ */
+public class FxmlNodeIterator extends BaseJavaIterator {
+
+ @Override
+ public Set instantiate() throws IOException {
+ FileObject targetFolder = Templates.getTargetFolder(wizard);
+ FileObject javaTemplate = Templates.getTemplate(wizard);
+
+ /* Retrieving the FXML template relative to the java template. */
+ FileObject fxmlTemplate = javaTemplate.getParent().getFileObject("FxmlNode.fxml");
+
+ String className = Templates.getTargetName(wizard);
+ String fxmlName = className;
+
+ DataFolder targetFolderData = DataFolder.findFolder(targetFolder);
+ DataObject javaTemplateData = DataObject.find(javaTemplate);
+ DataObject fxmlTemplateData = DataObject.find(fxmlTemplate);
+
+ DataObject createdJavaFileData = javaTemplateData.createFromTemplate(targetFolderData, className, Collections.singletonMap("fxmlName", fxmlName));
+ DataObject createdFxmlFileData = fxmlTemplateData.createFromTemplate(targetFolderData, fxmlName);
+
+ Set files = new HashSet<>();
+ files.add(createdJavaFileData.getPrimaryFile());
+ files.add(createdFxmlFileData.getPrimaryFile());
+ return files;
+ }
+}
diff --git a/src/tuupertunut/fxmltemplates/layer.xml b/src/tuupertunut/fxmltemplates/layer.xml
new file mode 100644
index 0000000..733e701
--- /dev/null
+++ b/src/tuupertunut/fxmltemplates/layer.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/tuupertunut/fxmltemplates/templates/FxmlApp.java.template b/src/tuupertunut/fxmltemplates/templates/FxmlApp.java.template
new file mode 100644
index 0000000..dc31023
--- /dev/null
+++ b/src/tuupertunut/fxmltemplates/templates/FxmlApp.java.template
@@ -0,0 +1,36 @@
+<#assign licenseFirst = "/*">
+<#assign licensePrefix = " * ">
+<#assign licenseLast = " */">
+<#include "${project.licensePath}">
+
+<#if package?? && package != "">
+package ${package};
+#if>
+
+import javafx.application.Application;
+import javafx.scene.Scene;
+import javafx.stage.Stage;
+
+/**
+ *
+ * @author ${user}
+ */
+public class ${name} extends Application {
+
+ @Override
+ public void start(Stage stage) throws Exception {
+ ${rootNodeName} root = new ${rootNodeName}();
+
+ Scene scene = new Scene(root);
+
+ stage.setScene(scene);
+ stage.show();
+ }
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String[] args) {
+ launch(args);
+ }
+}
diff --git a/src/tuupertunut/fxmltemplates/templates/FxmlNode.fxml.template b/src/tuupertunut/fxmltemplates/templates/FxmlNode.fxml.template
new file mode 100644
index 0000000..d5a0f08
--- /dev/null
+++ b/src/tuupertunut/fxmltemplates/templates/FxmlNode.fxml.template
@@ -0,0 +1,9 @@
+
+<#assign licenseFirst = "">
+<#include "${project.licensePath}">
+
+
+
+
diff --git a/src/tuupertunut/fxmltemplates/templates/FxmlNode.java.template b/src/tuupertunut/fxmltemplates/templates/FxmlNode.java.template
new file mode 100644
index 0000000..8ae66cc
--- /dev/null
+++ b/src/tuupertunut/fxmltemplates/templates/FxmlNode.java.template
@@ -0,0 +1,36 @@
+<#assign licenseFirst = "/*">
+<#assign licensePrefix = " * ">
+<#assign licenseLast = " */">
+<#include "${project.licensePath}">
+
+<#if package?? && package != "">
+package ${package};
+#if>
+
+import java.io.IOException;
+import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
+import javafx.scene.layout.AnchorPane;
+
+/**
+ *
+ * @author ${user}
+ */
+public class ${name} extends AnchorPane {
+
+ public ${name}() {
+ FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("${fxmlName}.fxml"));
+ fxmlLoader.setRoot(this);
+ fxmlLoader.setController(this);
+
+ try {
+ fxmlLoader.load();
+ } catch (IOException exception) {
+ throw new RuntimeException(exception);
+ }
+ }
+
+ @FXML
+ private void initialize() {
+ }
+}