blob: 98f3b5072cf99a33d98ec0de4b6b4cfa42b3acd2 [file] [log] [blame]
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
= NetBeans XML Editor Extension Module Tutorial
:jbake-type: platform_tutorial
:jbake-tags: tutorials
:jbake-status: published
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:icons: font
:experimental:
:description: NetBeans XML Editor Extension Module Tutorial - Apache NetBeans
:keywords: Apache NetBeans Platform, Platform Tutorials, NetBeans XML Editor Extension Module Tutorial
This tutorial demonstrates how to create a module that extends the functionality offered by one of NetBeans IDE's editors. The IDE has several editors—for example, the XML editor, the Java editor, the JSP editor, and the SQL editor. Normally all the IDE's editors are referred to collectively as the Source Editor. However, each of the editors is distinct—its functionality is targeted at the file type for which it exists. In this tutorial, you add an action to the XML editor. After you create and install the module, and you open an XML file, the editor's contextual menu will include a menu item that displays the XML file's tags in the Output Window:
image::images/taghandler_69-result-1.png[]
NOTE: This document is the latest version of this tutorial. If you are using an earlier version, see link:68/nbm-xmleditor.html[the 6.5/6.7/6.8 version of this tutorial].
Optionally, for troubleshooting purposes, you can link:http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=14039[download the completed sample].
== Setting up the Module Project
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
[start=1]
1. Choose File > New Project (Ctrl+Shift+N). Under Categories, select NetBeans Modules. Under Projects, select Module. Click Next.
[start=2]
1. In the Name and Location panel, type ``ShowXMLStructure`` in the Project Name field. Change the Project Location to any directory on your computer. Select the Standalone Module option and Set as Main Project checkbox selected. Click Next.
[start=3]
1. In the Basic Module Configuration panel, type ``org.netbeans.modules.showxmlstructure`` in Code Name Base.
[start=4]
1. Select "Generate XML Layer". Leave the locations of both the localizing bundle and the XML layer file so that they will be stored in a package with the name ``org/netbeans/modules/showxmlstructure`` . Click Finish.
The IDE creates the ``ShowXMLStructure`` 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 subclass several classes that belong to the NetBeans APIs. Each is declared as a module dependency. Use the Project Properties dialog box for this purpose, as described below.
[start=1]
1. In the Projects window, right-click the ``ShowXMLStructure`` project and choose Properties.
[start=2]
1. For each of the following APIs, click "Add..." in the Libraries panel, select the name from the Module list, and then click OK to confirm it:
* ``I/O APIs``
* ``Nodes API``
* ``Text API``
* ``Utilities API``
* ``Window System API``
Click OK to exit the Project Properties dialog box.
In the Projects window, expand the Important Files node and double-click Project Metadata and notice that the APIs you selected have been declared as module dependencies.
== Coding the Module
=== Creating the Action
[start=1]
1. Right-click the project node and choose New > Other. Under Categories, select Module Development. Under Projects, select Action, as shown below:
image::images/taghandler_69-action-1.png[]
Click Next.
[start=2]
1. In the Action Type panel and click Conditionally Enabled. Select ``EditorCookie`` , which is the name of the class that lets the Source Editor access the action, as shown below:
image::images/taghandler_69-action-2.png[]
Click Next.
[start=3]
1. In the GUI Registration panel, select the 'Edit' category in the Category drop-down list. The Category drop-down list controls where an action is shown in the Keyboard Shortcuts editor in the IDE. Next, select Editor Contect Menu Item and then select the ``text/xml`` MIME type, as shown below:
image::images/taghandler_69-action-3.png[]
Notice that you can set the position of the menu item and that you can separate the menu item from the item before it and after it. Click Next.
[start=4]
1. In the Name and Location panel, type ``ShowXMLStructureAction`` as the Class Name and type ``Show XML Structure`` as the Display Name. You should now see the following:
image::images/taghandler_69-action-4.png[]
Menu items provided by contextual menus do not display icons. Therefore, click Finish and ``ShowXMLStructureAction.java`` is added to the package. The content of the file is as follows:
[source,java]
----
package org.netbeans.modules.showxmlstructure;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import org.openide.cookies.EditorCookie;
public final class ShowXMLStructureAction implements ActionListener {
private final EditorCookie context;
public ShowXMLStructureAction(EditorCookie context) {
this.context = context;
}
public void actionPerformed(ActionEvent ev) {
// TODO use context
}
}
----
[start=5]
1. In the Source Editor, write the ``actionPerformed`` method as follows, after reading and understanding the comments in the code:
[source,java]
----
public void actionPerformed(ActionEvent ev) {
EditorCookie editorCookie = context;
*//Get the tab name from the Bundle.properties file:*
String tabName = NbBundle.getMessage(ShowXMLStructureAction.class, "LBL_tabName");
*// "XML Structure" tab is created in Output Window for writing the list of tags:*
InputOutput io = IOProvider.getDefault().getIO(tabName, false);
io.select(); *//"XML Structure" tab is selected*
try {
*//Get the InputStream from the EditorCookie:*
InputStream is = ((org.openide.text.CloneableEditorSupport) editorCookie).getInputStream();
*//Use the NetBeans org.openide.xml.XMLUtil class to create a org.w3c.dom.Document:*
Document doc = XMLUtil.parse(new InputSource(is), true, true, null, null);
*//Create a list of nodes, for all the elements:*
NodeList list = doc.getElementsByTagName("*");
*//Iterate through the list:*
for (int i = 0; i < list.getLength(); i++) {
*//For each node in the list, create a org.w3c.dom.Node:*
org.w3c.dom.Node mainNode = list.item(i);
*//Create a map for all the attributes of the org.w3c.dom.Node:*
NamedNodeMap map = mainNode.getAttributes();
*//Get the name of the node:*
String nodeName = mainNode.getNodeName();
*//Create a StringBuilder for the Attributes of the Node:*
StringBuilder attrBuilder = new StringBuilder();
*//Iterate through the map of attributes:*
for (int j = 0; j < map.getLength(); j++) {
*//Each iteration, create a new Node:*
org.w3c.dom.Node attrNode = map.item(j);
*//Get the name of the current Attribute:*
String attrName = attrNode.getNodeName();
*//Add the current Attribute to the StringBuilder:*
attrBuilder.append("*").append(attrName).append(" ");
}
*//Print the element and its attributes to the Output window:*
io.getOut().println("ELEMENT: " + nodeName +
" --> ATTRIBUTES: " + attrBuilder.toString());
}
*//Close the InputStream:*
is.close();
} catch (SAXException ex) {
Exceptions.printStackTrace(ex);
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
}
----
[start=6]
1. You will need these import statements:
[source,java]
----
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.InputStream;
import org.openide.cookies.EditorCookie;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.openide.windows.IOProvider;
import org.openide.windows.InputOutput;
import org.openide.xml.XMLUtil;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
----
[start=7]
1. Add the display names to the ``Bundle.properties`` file:
[source,java]
----
LBL_tabName=XML Structure
----
== Building and Installing the Module
The IDE uses an Ant build script to build and install your module. The build script is created for you when you create the module project.
=== Installing the Module
In the Projects window, right-click the ``ShowXMLStructure`` project and choose Run.
The module is built and installed in the target IDE or Platform. The target IDE or Platform opens so that you can try out your new module. The default target IDE or Platform is the installation used by the current instance of the development IDE. Note that when you run your module, you will be using a temporary test user directory, not the development IDE's user directory.
=== Using the Module
[start=1]
1. Choose File > New Project (Ctrl-Shift-N) and create a new project.
[start=2]
1. In the Files window (Ctrl-2), expand the project node and then expand the ``nbproject`` node. Double-click ``build-impl.xml`` so that it opens in the Source Editor
[start=3]
1. Right-click anywhere in the Source Editor and notice the new popup menu item called "Show XML Structure". Choose the menu item and notice that the tag handler prints all the elements and attributes to the Output window, which is at at the bottom of the IDE, as shown below:
image::images/taghandler_69-result-1.png[]
[start=4]
1. Open a different file type in the Source Editor. For example, open a Java class. Right-click anywhere in the Source Editor and notice that the new popup menu item is not included in the contextual menu. That is because the New Action wizard created the following entries for you, which cause the action to be available for XML files only:
[source,xml]
----
<folder name="Actions">
<folder name="Edit">
<file name="org-netbeans-modules-showxmlstructure-ShowXMLStructureAction.instance">
<attr name="delegate" methodvalue="org.openide.awt.Actions.inject"/>
<attr name="displayName" bundlevalue="org.netbeans.modules.showxmlstructure.Bundle#CTL_ShowXMLStructureAction"/>
<attr name="injectable" stringvalue="org.netbeans.modules.showxmlstructure.ShowXMLStructureAction"/>
<attr name="instanceCreate" methodvalue="org.openide.awt.Actions.context"/>
<attr name="noIconInMenu" boolvalue="false"/>
<attr name="selectionType" stringvalue="EXACTLY_ONE"/>
<attr name="type" stringvalue="org.openide.cookies.EditorCookie"/>
</file>
</folder>
</folder>
<folder name="Editors">
<folder name="text">
<folder name="xml">
<folder name="Popup">
<file name="org-netbeans-modules-showxmlstructure-ShowXMLStructureAction.shadow">
<attr name="originalFile" stringvalue="Actions/Edit/org-netbeans-modules-showxmlstructure-ShowXMLStructureAction.instance"/>
<attr name="position" intvalue="1100"/>
</file>
</folder>
</folder>
</folder>
</folder>
----
=== Creating a Shareable Module Binary
[start=1]
1. In the Projects window, right-click the ``ShowXMLStructure`` project and choose Create NBM.
The NBM file is created and you can view it in the Files window (Ctrl-2):
image::images/taghandler_69-result-2.png[]
[start=2]
1. Make it available to others via, for example, the link:http://plugins.netbeans.org/PluginPortal/[Plugin Portal].
link:http://netbeans.apache.org/community/mailing-lists.html[Send Us Your Feedback]
== Next Steps
For more information about creating and developing NetBeans modules, see the following resources:
* link:https://netbeans.apache.org/kb/docs/platform.html[Other Related Tutorials]
* link:https://bits.netbeans.org/dev/javadoc/[NetBeans API Javadoc]