| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
| <html xmlns="http://www.w3.org/1999/xhtml"> | |
| <head> | |
| <!-- -*- xhtml -*- --> | |
| <title>XML Editor Extension Module Tutorial for the NetBeans Platform</title> | |
| <link rel="stylesheet" type="text/css" href="https://netbeans.org/netbeans.css"/> | |
| <meta name="AUDIENCE" content="NBUSER"/> | |
| <meta name="TYPE" content="ARTICLE"/> | |
| <meta name="EXPIRES" content="N"/> | |
| <meta name="developer" content="gwielenga@netbeans.org"/> | |
| <meta name="indexed" content="y"/> | |
| <meta name="description" | |
| content="A short guide to extending the NetBeans XML Editor."/> | |
| <!-- Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Oracle and/or its affiliates. All rights reserved. --> | |
| <!-- Use is subject to license terms.--> | |
| </head> | |
| <body> | |
| <h1>NetBeans XML Editor Extension Module Tutorial</h1> | |
| <p>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.</p> | |
| <p>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: </p> | |
| <p><img src="../images/tutorials/taghandler/72/result.png" alt="New Output window."/></p> | |
| <p><strong class="notes">Note: </strong>This document uses | |
| NetBeans Platform 8.0 and above with NetBeans IDE 8.0 and above. If you | |
| are using an earlier version of NetBeans IDE or the NetBeans Platform, | |
| see <a href="74/nbm-xmleditor.html">the previous version | |
| of this document</a>.</p> | |
| <p><b>Contents</b></p> | |
| <p><img src="../images/articles/81/netbeans-stamp.png" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 8.0" title="Content on this page applies to NetBeans IDE 8.0"/></p> | |
| <ul class="toc"> | |
| <li><a href="#creatingthemoduleproject">Setting Up the Module Project</a> | |
| <ul><li><a href="#create-plug-in">Creating the Module Project the Sample</a></li> | |
| <li><a href="#specify-dependencies">Specifying the Module's Dependencies</a></li></ul></li> | |
| <li><a href="#create-tag-handler">Coding the Module</a></li> | |
| <li><a href="#building">Building and Installing the Module</a></li> | |
| </ul> | |
| <p><b>To follow this tutorial, you need the software and resources listed in the following | |
| table.</b></p> | |
| <table> | |
| <tbody> | |
| <tr> | |
| <th class="tblheader" scope="col">Software or Resource</th> | |
| <th class="tblheader" scope="col">Version Required</th> | |
| </tr> | |
| <tr> | |
| <td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td> | |
| <td class="tbltd1">version 8.0 or above</td> | |
| </tr> | |
| <tr> | |
| <td class="tbltd1"><a href="http://java.sun.com/javase/downloads/index.jsp">Java Developer Kit (JDK)</a></td> | |
| <td class="tbltd1">version 7 or above</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <p class="tips">For troubleshooting purposes, you are welcome to download the <a href="http://java.net/projects/nb-api-samples/sources/api-samples/show/versions/8.0/tutorials/ShowXMLStructure">completed tutorial source code</a>.</p> | |
| <h2 class="tutorial"><a name="creatingthemoduleproject"></a>Setting up the Module Project</h2> | |
| <p>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.</p> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="create-plug-in"></a>Creating the Module Project</h3> | |
| <div class="indent"> | |
| <ol> | |
| <li>Choose File > New Project (Ctrl+Shift+N). Under Categories, select NetBeans Modules. | |
| Under Projects, select Module. Click Next.</li> | |
| <li>In the Name and Location panel, type <tt>ShowXMLStructure</tt> in the Project Name field. | |
| Change the Project Location to any directory on your computer. Click Next.</li> | |
| <li>In the Basic Module Configuration panel, type <tt>org.netbeans.modules.showxmlstructure</tt> | |
| in Code Name Base. Click Finish.</li> | |
| </ol> | |
| </div> | |
| <p> The IDE creates the <tt>ShowXMLStructure</tt> | |
| 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).</p> | |
| <h3 class="tutorial"><a name="specify-dependencies"></a>Specifying the Module's Dependencies</h3> | |
| <p>You will need to subclass several classes that belong to the NetBeans APIs. | |
| Each is declared as a module dependency.</p> | |
| <div class="indent"> | |
| <ol> | |
| <li><p>In the Projects window, right-click the Libraries node and choose Add Module Dependency:</p><br/> | |
| <p><img src="../images/tutorials/taghandler/72/add-dep.png" alt="add module dependency"/></p> | |
| </li> | |
| <li>Search for each of the following APIs in the Add Module Dependency dialog, | |
| select the API, and then click OK to confirm it: | |
| <p></p> | |
| <ul> | |
| <li><tt>I/O APIs</tt></li> | |
| <li><tt>Nodes API</tt></li> | |
| <li><tt>Text API</tt></li> | |
| <li><tt>Utilities API</tt></li> | |
| <li><tt>Window System API</tt></li></ul> | |
| </li> | |
| </ol> | |
| </div> | |
| <p>In the Projects window, you should see the following list of dependencies:</p> | |
| <p><img src="../images/tutorials/taghandler/72/add-dep-1.png" alt="add module dependency"/></p> | |
| </div> | |
| <!-- ===================================================================================== --> | |
| <h2><a name="create-tag-handler"></a>Coding the Module</h2> | |
| <p>In this section, you use the New Action wizard to create a new Java class, which is annotated such that the user | |
| will be able to invoke it after right-clicking within the XML Editor.</p> | |
| <div class="indent"> | |
| <ol> | |
| <li><p>Right-click the project node and | |
| choose New > Other. Under Categories, select Module Development. Under Projects, | |
| select Action.</p> <br/> | |
| <img src="../images/tutorials/taghandler/72/new-action-1.png" alt="Step 1 of New Action wizard."/> | |
| <p>Click Next.</p></li> | |
| <li><p>In the Action Type panel, click Conditionally Enabled. Select | |
| <tt><a href="http://bits.netbeans.org/dev/javadoc/org-openide-text/org/openide/cookies/EditorCookie.html">EditorCookie</a></tt>. | |
| Because of this selection, the Action will be enabled when | |
| an EditorCookie is available in the Lookup. That will be the | |
| case whenever a document is open in the Source Editor. You | |
| should now see the following:</p><br/> | |
| <p><img src="../images/tutorials/taghandler/72/new-action-2.png" alt="Step 2 of New Action wizard."/></p> | |
| <p>Click Next.</p></li> | |
| <li><p>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. | |
| </p> | |
| <p>Next, select Editor Context Menu Item and then select the <tt>text/xml</tt> MIME type, as shown below:</p> | |
| <br/> | |
| <img src="../images/tutorials/taghandler/72/new-action-3.png" alt="Step 3 of New Action wizard."/> | |
| <p>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.</p></li> | |
| <li><p>In the Name and Location panel, type <tt>ShowXMLStructureActionListener</tt> as the Class Name | |
| and type <tt>Show XML Structure</tt> as the Display Name. You should now see the following:</p> | |
| <br/> | |
| <img src="../images/tutorials/taghandler/72/new-action-4.png" alt="Step 4 of New Action wizard."/> | |
| <p>Menu items provided by contextual menus | |
| do not display icons. Therefore, click Finish and <tt>ShowXMLStructureActionListener.java</tt> is added to the package. | |
| The content of the file is as follows:</p> | |
| <pre class="examplecode">package org.netbeans.modules.showxmlstructure; | |
| import java.awt.event.ActionEvent; | |
| import java.awt.event.ActionListener; | |
| import org.openide.awt.ActionID; | |
| import org.openide.awt.ActionReference; | |
| import org.openide.awt.ActionRegistration; | |
| import org.openide.cookies.EditorCookie; | |
| import org.openide.util.NbBundle.Messages; | |
| <a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionID.html">@ActionID</a>( | |
| category = "Edit", | |
| id = "org.netbeans.modules.showxmlstructure.ShowXMLStructureActionListener") | |
| <a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionRegistration.html">@ActionRegistration</a>( | |
| displayName = "#CTL_ShowXMLStructureActionListener") | |
| <a href="http://bits.netbeans.org/dev/javadoc/org-openide-awt/org/openide/awt/ActionReference.html">@ActionReference</a>(path = "Editors/text/xml/Popup", position = 1100) | |
| <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/util/NbBundle.Messages.html">@Messages</a>("CTL_ShowXMLStructureActionListener=Show XML Structure") | |
| public final class ShowXMLStructureActionListener implements ActionListener { | |
| private final EditorCookie context; | |
| public ShowXMLStructureActionListener(EditorCookie context) { | |
| this.context = context; | |
| } | |
| @Override | |
| public void actionPerformed(ActionEvent ev) { | |
| // TODO use context | |
| } | |
| }</pre> | |
| </li> | |
| <li>In the Source Editor, fill out the <tt>actionPerformed</tt> method as follows, | |
| after reading and understanding the comments in the code: | |
| <pre class="examplecode">@Override | |
| public void actionPerformed(ActionEvent ev) { | |
| // "XML Structure" tab is created in Output Window for writing the list of tags: | |
| <a href="http://bits.netbeans.org/dev/javadoc/org-openide-io/org/openide/windows/InputOutput.html">InputOutput</a> io = <a href="http://bits.netbeans.org/dev/javadoc/org-openide-io/org/openide/windows/IOProvider.html">IOProvider</a>.getDefault().getIO(Bundle.CTL_ShowXMLStructureActionListener(), false); | |
| io.select(); //"XML Structure" tab is selected | |
| try { | |
| //Get the InputStream from the EditorCookie: | |
| InputStream is = ((org.openide.text.CloneableEditorSupport) context).getInputStream(); | |
| //Use the NetBeans org.openide.xml.XMLUtil class to create a org.w3c.dom.Document: | |
| Document doc = <a href="http://bits.netbeans.org/dev/javadoc/org-openide-util/org/openide/xml/XMLUtil.html">XMLUtil.parse(new InputSource(is), true, true, null, null)</a>; | |
| //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); | |
| } | |
| }</pre> | |
| </li> | |
| <li>You will need these import statements: | |
| <pre class="examplecode">import java.awt.event.ActionEvent; | |
| import java.awt.event.ActionListener; | |
| import java.io.IOException; | |
| import java.io.InputStream; | |
| import org.openide.awt.ActionID; | |
| import org.openide.awt.ActionReference; | |
| import org.openide.awt.ActionRegistration; | |
| import org.openide.cookies.EditorCookie; | |
| import org.openide.util.Exceptions; | |
| import org.openide.util.NbBundle.Messages; | |
| 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;</pre></li> | |
| </ol> | |
| </div> | |
| <!-- ======================================================================================= --> | |
| <h2><a name="building"></a>Building and Installing the Module</h2> | |
| <p>In the Projects window, right-click the <tt>ShowXMLStructure</tt> project and choose Run.</p> | |
| <p>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.</p> | |
| <div class="indent"> | |
| <ol> | |
| <li>Open an XML file and | |
| right-click anywhere in the Source Editor. | |
| Notice the new popup menu item called "Show XML Structure".</li> | |
| <li><p>Choose the menu item and notice that the tag handler prints all the elements | |
| and attributes to the Output window (Ctrl-4), | |
| which is at at the bottom of the IDE, as shown below:</p><br/> | |
| <p><img src="../images/tutorials/taghandler/72/result.png" alt="New Output window."/></p></li> | |
| </ol> | |
| </div> | |
| <div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&subject=Feedback:%20XML%20Editor%20Extension%20Tutorial%208.0">Send Us Your Feedback</a></div> | |
| <!-- ======================================================================================== --> | |
| <h2><a name="nextsteps"></a>Next Steps</h2> | |
| <p>For more information about creating and developing NetBeans modules, see the following resources: </p> | |
| <ul> | |
| <li><a href="https://netbeans.org/kb/trails/platform.html">Other Related Tutorials</a></li> | |
| <li><a href="https://netbeans.org/download/dev/javadoc/">NetBeans API Javadoc</a></li> | |
| </ul> | |
| <!-- ======================================================================================== --> | |
| <!-- | |
| <h2><a name="version"></a>Versioning </h2> | |
| <table width="76%" border="1"> | |
| <tbody> | |
| <tr> | |
| <td> | |
| <div><b>Version</b></div> | |
| </td> | |
| <td> | |
| <div><b>Date</b></div> | |
| </td> | |
| <td> | |
| <div><b>Changes</b></div> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 1 | |
| </td> | |
| <td> | |
| 11 July 2005 | |
| </td> | |
| <td> | |
| Initial version | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 2 | |
| </td> | |
| <td> | |
| 27 September 2005 | |
| </td> | |
| <td> | |
| <ul><li>Added Action wizard</li> | |
| <li>Renamed from "NetBeans Tag Handler Plug-in Tutorial" | |
| to "NetBeans Source Editor Extension Module Tutorial".</li> | |
| <li>Added issue 7 below.</li></ul> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 3 | |
| </td> | |
| <td> | |
| 28 September 2005 | |
| </td> | |
| <td> | |
| <ul><li>Renamed the tutorial, because 'Source Editor' doesn't | |
| cover the SQL editor, which could also be extended using the steps in this tutorial.</li> | |
| <li>Rewrote the introductory paragraph.</li></ul> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 4 | |
| </td> | |
| <td> | |
| 11 June 2007 | |
| </td> | |
| <td> | |
| Worked through whole tutorial, and cleaned up, for 6.0, | |
| also changed screenshots. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 5 | |
| </td> | |
| <td> | |
| 17 November 2007 | |
| </td> | |
| <td> | |
| Fixed spacing between steps. Tried out the attached sample, | |
| and it works as described. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 6 | |
| </td> | |
| <td> | |
| 1 November 2008 | |
| </td> | |
| <td> | |
| Updated to 6.5: badge, table, etc. But also vastly simplified | |
| the tutorial, by using the NetBeans XMLUtil class, thus was | |
| able to remove a whole section and a lot of code. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 7 | |
| </td> | |
| <td> | |
| 21 November 2010 | |
| </td> | |
| <td> | |
| Went through and made sure no red error marks are shown in editor. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 8 | |
| </td> | |
| <td> | |
| 21 December 2010 | |
| </td> | |
| <td> | |
| Changed the open angle brackets in the code to entities. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 9 | |
| </td> | |
| <td> | |
| 4 January 2011 | |
| </td> | |
| <td> | |
| Updated to 6.9. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 10 | |
| </td> | |
| <td> | |
| 13 November 2011 | |
| </td> | |
| <td> | |
| Updated to 7.1. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 11 | |
| </td> | |
| <td> | |
| 7 July 2012 | |
| </td> | |
| <td> | |
| Updated to 7.2. | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <p></p> | |
| <table width="76%" border="1"> | |
| <tbody> | |
| <tr> | |
| <td> | |
| <b>Issue Number</b> | |
| </td> | |
| <td> | |
| <b>Description</b> | |
| </td> | |
| <td> | |
| <b>Status</b> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 1 | |
| </td> | |
| <td> | |
| Code and tutorial itself need to be reviewed. | |
| </td> | |
| <td> | |
| To be fixed. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 2 | |
| </td> | |
| <td> | |
| Tutorial needs to be updated once Phase III and IV are complete. | |
| </td> | |
| <td> | |
| Done. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 3 | |
| </td> | |
| <td> | |
| Some APIs used in this tutorial have deprecated methods. This will | |
| produce errors in the Output window, but should not impact functioning | |
| of module. | |
| </td> | |
| <td> | |
| To be fixed. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 4 | |
| </td> | |
| <td> | |
| Clear explanations and links to Javadoc to be added for all APIs, classes, and methods. | |
| Also Javadoc links for each of the dependencies and why they are needed in this tutorial. | |
| </td> | |
| <td> | |
| To be fixed. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 5 | |
| </td> | |
| <td> | |
| Maybe other identifiers for JSP editor, HTML editor, etc. should be mentioned. | |
| For example, instead of "xml" (in layer.xml), use "html", "x-properties", "base" etc. | |
| </td> | |
| <td> | |
| To be fixed. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 6 | |
| </td> | |
| <td> | |
| Explain what a cookie is. Explain what a cookie action is. | |
| </td> | |
| <td> | |
| To be fixed. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 7 | |
| </td> | |
| <td> | |
| Need to change downloadable, because currently | |
| the tag handler and the show XML action are separate files | |
| while in the downloadable code, they're in the same file. | |
| For the same reason, must change screenshots where one file | |
| instead of two are shown. | |
| </td> | |
| <td> | |
| Done. | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 8 | |
| </td> | |
| <td> | |
| 3 July 2014 | |
| </td> | |
| <td> | |
| Update to 8.0. | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table>--> | |
| </body> | |
| </html> |