| <!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>NetBeans Multiview Editor Module Tutorial</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 using the Multiview API."> | |
| <!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. --> | |
| <!-- Use is subject to license terms.--> | |
| </head> | |
| <body> | |
| <h1>NetBeans Multiview Editor Module Tutorial</h1> | |
| <p><small><a href="mailto:nbdocs_feedback@usersguide.netbeans.org?subject=Feedback:%20NetBeans%20IDE%20Multiview%20Editor%20Module%20Tutorial">Feedback</a></small></p> | |
| <p>This tutorial walks you through an implementation of the <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-core-multiview/overview-summary.html">MultiView API</a>. A multiview displays multiple views on data in the IDE. For example, the <tt>web.xml</tt> file can be edited in a <i>source</i> view | |
| as well as in a <i>design</i> view—in the former, you work with XML tags; in the latter, you use user interface | |
| components such as drop-down lists and checkboxes. | |
| <p>The multiview that you create in this tutorial is an editor for a subset of the data in the JBoss deployment descriptor (<tt>jboss-web.xml</tt>). | |
| The multiview editor that you create in this tutorial will only be visible when an XML file with the <tt>jboss-web.xml</tt> namespace | |
| is open in the IDE's Source Editor. (However, since the JBoss deployment descriptor does not officially have a namespace, the placeholder <tt>jbosstype</tt> is | |
| used instead.) Specifically for these files, the user will have two views for editing, as shown below. | |
| <p>This is the Source view: | |
| <p><img src="../images/tutorials/multiview/final_pic1.png" alt="Source view."> | |
| <p>And this is the Design view: | |
| <p><img src="../images/tutorials/multiview/final_pic2.png" alt="Design view."> | |
| <p>When a change is made in one of the views, it is immediately synchronized with the other view. So when, for example, | |
| the value of the 'Description' field above is modified in the Design view, the Source view is changed at the same time. | |
| <p>The following topics are covered below:</p> | |
| <ul> | |
| <li><a href="#installing-software">Installing the Software</a> | |
| <ul> | |
| <li><a href="#installing-sample">Installing the Sample</a></li> | |
| </ul> | |
| </li> | |
| <li><a href="#setting-up-module-project">Setting Up the Module Project</a> | |
| <li><a href="#recognizing-new-file-type">Recognizing the New File Type</a> | |
| <li><a href="#creating-design-view">Creating the Design View</a> | |
| <ul> | |
| <li><a href="#creating-window-component">Creating the Window Component</a> | |
| <li><a href="#specifying-module-dependencies">Specifying the Module's Dependencies</a> | |
| <li><a href="#designing-design-view">Designing the Design View</a> | |
| <li><a href="#adding-editor-support">Adding Editor Support</a> | |
| <li><a href="#enabling-multiview-editor">Enabling the Multiview Editor</a> | |
| </ul> | |
| <li><a href="#registering-module">Registering the Module</a> | |
| <li><a href="#building-and-installing-module">Building and Installing the Module</a> | |
| <ul> | |
| <li><a href="#installing-and-using-nodule">Installing and Using the Module</a> | |
| <li><a href="#creating-shareable-module-library">Creating a Shareable Module Binary</a> | |
| </ul> | |
| </ul> | |
| <p><a name="top"></a>Once the software is installed, this tutorial can be completed in 45 minutes. | |
| <p>For more information on working with modules, see the <a href="https://platform.netbeans.org/index.html"> | |
| NetBeans Development Project home</a> on the NetBeans website. If you have questions, visit the | |
| <a href="http://wiki.netbeans.org/wiki/view/NetBeansDeveloperFAQ">NetBeans Developer FAQ</a> or use the feedback link | |
| at the top of this page.</p> | |
| <br /> | |
| <!-- ===================================================================================== --> | |
| <h2 class="tutorial"><a name="installing-software"></a>Installing the Software</h2> | |
| <p>Before you begin, you need to install the following software on your | |
| computer:</p> | |
| <ul> | |
| <li>NetBeans IDE 5.x (<a href="http://www.netbeans.info/downloads/download.php?a=n&p=1">download</a>)</li> | |
| <li>Java Standard Development Kit (JDK™) version | |
| 1.4.2 (<a href="http://java.sun.com/j2se/1.4.2/download.html">download</a>) | |
| or 5.0 (<a href="http://java.sun.com/j2se/1.5.0/download.jsp">download</a>)</li> | |
| </ul> | |
| <br /> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="installing-sample"></a>Installing the Sample</h3> | |
| <p>Take the following steps to install the sample: | |
| <ol><p><li>Unzip the <a href="https://netbeans.org/files/documents/4/657/jbossVisualEditor.zip">attached file</a>. | |
| <p><li>In the IDE, choose File > Open Project and browse to the folder that contains the unzipped file. | |
| Open the module project. It should look as follows: | |
| <p><img src="../images/tutorials/multiview/projects_window_final.png" alt="Completed projects window."> | |
| <p>In the illustration above, the two selected files provide the implementation of the <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-core-multiview/overview-summary.html">MultiView API</a>. | |
| <p><li>Right-click the project node and choose Install/Reload in Target Platform. When the new instance of the IDE | |
| opens, create a new web application, right-click it, choose New > File/Folder, and select the new <tt>jboss-web.xml</tt> file: | |
| <p><img src="../images/tutorials/multiview/newfile.png" alt="Test file."> | |
| <p>Click Next. Name the file whatever you like and store it in a folder of your choice. | |
| When you complete the wizard and the new file opens in the Source Editor, | |
| notice that you now have two views on your data—a Design view and | |
| a Source view: | |
| <p><img src="../images/tutorials/multiview/jboss-web-xml2.png" alt="Test file."> | |
| </ol> | |
| <p>Now that you know what the end result looks like, you will create the module from scratch and learn about each part | |
| while creating it. | |
| </div> | |
| <br /> | |
| <!-- ===================================================================================== --> | |
| <h2 class="tutorial"><a name="setting-up-module-project"></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. <a href="http://www.netbeans.info/downloads/download.php?a=n&p=1">NetBeans IDE 5.x</a> provides a wizard that sets up all the basic files | |
| needed for a module.</p> | |
| <ol> | |
| <p><li>Choose File > New Project (Ctrl-Shift-N). Under Categories, select NetBeans Plug-in Modules. Under projects, | |
| select Module Project and click Next.</li> | |
| <p><li>In the Name and Location panel, type <tt>jbossVisualEditor</tt> in Project Name. | |
| Change the | |
| Project Location to any directory on your computer. Leave the Standalone Module radio button | |
| and the Set as Main Project checkbox selected. | |
| Click Next. | |
| <p><li>In the Basic Module Configuration panel, replace <tt>yourorghere</tt> in Code Name Base with <tt>org.netbeans</tt>, | |
| so that the whole code name base is <tt>org.netbeans.jbossvisualeditor</tt>. | |
| Leave the display name unchanged. Do not change the location of the localizing bundle and the location of the XML layer, so that they will be stored in a | |
| package with the name <tt>org/netbeans/jbossvisualeditor</tt>. Click Finish.</ol> | |
| <p> The IDE creates the <tt>jbossVisualEditor</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). For example, this is what the projects window should | |
| look like right now: | |
| <p align="left"><img src="../images/tutorials/multiview/projects_window_zero.png" alt="projects window zero"></ol> | |
| <br /> | |
| <!-- ===================================================================================== --> | |
| <h2><a name="recognizing-new-file-type"></a>Recognizing the New File Type</h2> | |
| <p>Since you are making a multiview editor for JBoss deployment descriptors, you need to make sure that | |
| the IDE knows how to recognize one. In principle, the JBoss deployment descriptor is an XML file like most | |
| other XML files—it's <tt>.xml</tt> file extension is non-distinctive. In these cases, a distinction can | |
| be made via the file's first element, its namespace, or its doctype. In this tutorial, you will distinguish JBoss deployment | |
| descriptors via their namespace. | |
| <ol> | |
| <p><li>Right-click the project node and | |
| choose New > File Type. </li> | |
| <p><li>In the File Recognition panel, do the following: | |
| <p><ul><li>Type <tt>text/x-jboss+xml</tt> in the MIME Type edit box. | |
| <li>Type <tt>jbosstype</tt> in the by XML Root Element edit box.</ul> | |
| <p>The File Recognition panel should now look as follows: | |
| <p align="left"><img src="../images/tutorials/multiview/filewizard1.png" alt="Step 1 of New File wizard."> | |
| <p>Note the following about the fields in the File Recognition panel: | |
| <ul> | |
| <li><b>MIME Type.</b> Specifies the data object's unique MIME type. | |
| <p><ul><li><b>by Filename Extension.</b> Specifies one or more file extensions that the IDE will recognize | |
| as belonging to the specified MIME type. The file extension can optionally be preceded | |
| by a dot. Separators are commas, spaces, or both. Therefore, all of the following are valid: | |
| <p><ul><li><tt>.abc,.def</tt> | |
| <li><tt>.abc .def</tt> | |
| <li><tt>abc def</tt> | |
| <li><tt>abc,.def ghi, .wow</ul></tt> | |
| <p>Note that manifests in JAR files are "MANIFEST.MF" and can be case-sensitive (at least on Unix). For | |
| this reason, you specify <i>two</i> MIME types in this tutorial—<tt>.mf</tt> and <tt>.MF</tt>. | |
| <li><b>by XML Root Element.</b> Specifies a unique namespace that distinguishes the XML file | |
| type from all other XML file types. Since many XML files have the same extension (<tt>xml</tt>), | |
| the IDE distinguishes between | |
| XML files via their XML root elements. More specifically, the IDE can distinguish between namespaces and | |
| the first XML element in XML files. In this tutorial, the distinction will be based on an imaginary namespace, <tt>jbosstype</tt>. | |
| </ul></ul> | |
| <p>Click Next. | |
| <p><li>In the Name and Location panel, do the following: | |
| <ul><p><li>In Class Name Prefix, type <tt>jbossdd</tt>. | |
| <p><li>In Icon, browse to any 16x16 pixel image file as the new file type's icon. Several | |
| 16x16 pixel image files are found within your NetBeans installation directory, for example, in this | |
| location: | |
| <p><tt>enterprise2\jakarta-tomcat-5.5.7\server\webapps\admin\images.</tt> | |
| <p>For example, you could use the <tt>Datasource.gif</tt> image in the above directory. | |
| This is what it looks like: <img src="../images/tutorials/filetype/Datasource.gif" alt="Datasource.gif"> | |
| <p><li>In Package, change <tt>org.netbeans.jbossvisualeditor</tt> to <tt>org.netbeans.jbossvisualeditor.dataloader</tt>.</ul> | |
| <p><li>Click Finish. | |
| <p>The Projects window should now look as follows: | |
| <p align="left"><img src="../images/tutorials/multiview/projects_window_first.png" alt="Final Projects window."></ol> | |
| <p>Each of the newly generated files (highlighted above) is briefly introduced: | |
| <ul> | |
| <p><li><b><tt>jbossddDataLoader.java</tt>.</b> Recognizes the <tt>text/x-jboss+xml</tt> MIME type. Functions as a factory for | |
| the <tt>DataObject</tt>. For more information, see <a href="http://wiki.netbeans.org/wiki/view/DevFaqDataLoader">What is a DataLoader?</a>. | |
| <p><li><b><tt>jbossddResolver.xml</tt>.</b> Maps the MIME type to an <tt><xml-rule></tt> that restricts the <tt>DataLoader</tt> | |
| to only recongize XML files that match the <tt><xml-rule></tt>. In this tutorial, the rule specifes that only files that have <tt>jbosstype</tt> as | |
| their namespace will be recognized by the <tt>DataLoader</tt>. | |
| <p><li><b><tt>jbossddDataObject.java</tt>.</b> Wraps a <tt>FileObject</tt>. <tt>DataObjects</tt> are produced by <tt>DataLoaders</tt>. | |
| For more information, see <a href="http://wiki.netbeans.org/wiki/view/DevFaqDataObject">What is a DataObject?</a>. | |
| <p><li><b><tt>jbossddDataNode.java</tt>.</b> Provides what you <i>see</i> in the IDE—functionality like actions, icons, and localized names. | |
| <p><li><b><tt>jbossddDataLoaderBeanInfo.java</tt>.</b> Controls the appearance of the <tt>DataLoader</tt> in the Object Types section | |
| of the Options window. | |
| <p><li><b><tt>jbossddTemplate.xml</tt>.</b> Provides a dummy template that the <tt>layer.xml</tt> file registers in the New File wizard. Change the | |
| default content of this file to the following: | |
| <p><pre class="examplecode"><?xml version="1.0" encoding="UTF-8"?> | |
| <jboss-web xmlns="jbosstype"> | |
| <context-root>/hello</context-root> | |
| <resource-ref> | |
| <description>The default DS</description> | |
| <res-ref-name>jdbc/DefaultDS</res-ref-name> | |
| <res-type>javax.sql.DataSource</res-type> | |
| <res-auth>Container</res-auth> | |
| </resource-ref> | |
| </jboss-web></pre> | |
| </ul> | |
| </p> | |
| <br /> | |
| <!-- ===================================================================================== --> | |
| <h2 class="tutorial"><a name="creating-design-view"></a>Creating the Design View</h2> | |
| <p>The multiview editor is actually already halfdone before you begin—the <i>source</i> view is there by default. | |
| So, all you need to do is create the <i>design</i> view, which is built up out of components such as <tt>JTextFields</tt> | |
| and <tt>JComboBoxes</tt>. Components such as these are used to set values for the JBoss deployment desciptor. Creating | |
| the <i>design</i> view is what this section is all about. | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="specifying"></a>Creating the Window Component</h3> | |
| <ol> | |
| <p><li>Right-click the <tt>jbossVisualEditor</tt> project node and | |
| choose New > Window Component. </li> | |
| <p><li>In the Basic Settings panel, choose <tt>editor</tt> from the Window Position drop-down list. | |
| This positions the Design view in the <tt>editor</tt> mode of the IDE, where the Source | |
| Editor, containing the Source view, is also found. <p>Do not select the | |
| Open on Application Start checkbox, because you want the Design view to be displayed only when the JBoss deployment descriptor is | |
| open in the Source Editor, instead of whenever the IDE opens. Click Next. | |
| <p><li>In the Name and Location panel, do the following: | |
| <ul><p><li>In Class Name Prefix, type <tt>designView</tt>. | |
| <p><li>In Icon, browse to any 16x16 pixel image file as the new file type's icon. | |
| <p><li>In Package, change <tt>org.netbeans.jbossvisualeditor</tt> to <tt>org.netbeans.jbossvisualeditor.editor</tt>.</ul> | |
| <p><li>Click Finish. | |
| <p>The Projects window should now look as follows: | |
| <p align="left"><img src="../images/tutorials/multiview/projects_window_second.png" alt="Final Projects window."></ol> | |
| <p>Each of the newly generated files (highlighted above) is briefly introduced: | |
| <ul> | |
| <p><li><b><tt>designViewTopComponent.java</tt>.</b> Implements the <a href="https://netbeans.org/download/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html">TopComponent</a> class. | |
| <p><li><b><tt>designViewAction.java</tt>.</b> Provides an action for opening <tt>designViewTopComponent.java</tt>. | |
| <p><li><b><tt>designViewTopComponentSettings.xml</tt>.</b> Specifies... | |
| <p><li><b><tt>designViewTopComponentWstcref.xml</tt>.</b> Specifies... | |
| </ul> | |
| <h3 class="tutorial"><a name="specifying-module-dependencies"></a>Specifying the Module's Dependencies</h3> | |
| <p>You will need to subclass several classes that belong to the <a href="https://netbeans.org/download/dev/javadoc/">NetBeans APIs</a>. | |
| Each has to be declared as a Module dependency. Use the Project Properties dialog box for this purpose. | |
| <ol> | |
| <li>In the Projects window, right-click the <tt>jbosswebxml</tt> project node and choose Properties. | |
| In the Project Properties dialog box, click Libraries. | |
| <p>You should see that the following libraries have been declared for you by the IDE. The IDE did | |
| this when you used the New File wizard and the New Window Component wizard. Here is what you should see: | |
| <p><img src="../images/tutorials/multiview/proj_props2.png" alt="All source files."> | |
| <p>Now you need to add some more for the tasks that follow. | |
| </li> | |
| <p><li>For each of the following APIs, click "Add...", | |
| select the name from the Module list, and then click OK to confirm it: | |
| <ul><p><li>UI Utilities API | |
| <p><li>Core - MultiView Windows | |
| </ul> | |
| <p><li>Click OK to exit the Project Properties dialog box. | |
| <p><li>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. | |
| </ol> | |
| <h3 class="tutorial"><a name="designing-design-view"></a>Designing the Design View</h3> | |
| <ol><li>In the <tt>org.netbeans.jbossvisualeditor.editor</tt> package, double-click <tt>designViewTopComponent.java</tt>. The implementation of <tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html">TopComponent</a></tt> | |
| opens in the Design view of the Source Editor. | |
| <p><li>Drag and drop <tt>JPanels</tt>, <tt>JLabels</tt>, <tt>JTextFields</tt>, and <tt>JComboBoxes</tt> onto the <tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html">TopComponent</a></tt>. Name the | |
| <tt>JLabels</tt> however you like. | |
| <p>Make sure that you change the names of the <tt>JTextFields</tt> and <tt>JComboBoxes</tt> as follows: | |
| <ul><p><li><tt>JTextField: contextroot | |
| <p><li>JTextField: description | |
| <p><li>JTextField: name | |
| <p><li>JComboBox: type | |
| <p><li>JCombobox: authority</tt></ul> | |
| <p>You can also add bordered titles to the <tt>JPanels</tt> and put some values in the <tt>JComboBoxes</tt>. At the end of | |
| this subsection, your <tt><a href="https://netbeans.org/download/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html">TopComponent</a></tt> should look something like this: | |
| <p><img src="../images/tutorials/multiview/description_being_named.png" alt="multi design view"> | |
| <p>In the illustration above, you see that the name of one of the <tt>JTextFields</tt> is set to <tt>description</tt>. | |
| </ol> | |
| <h3 class="tutorial"><a name="designing-design-view"></a>Coding the Design View</h3> | |
| <p>This is where the real work begins! Till now, you have used wizards and the GUI Builder. From now until the end of this tutorial, | |
| you are entering uncharted territory—the IDE currently does not provide specific assistance for the MultiView API in the way that, for | |
| example, the | |
| <a href="https://netbeans.org/download/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html">TopComponent</a> class is supported by the Window Component wizard. However, you | |
| will be shown how to use many of the Source Editor's features while building the multiview editor for the JBoss deployment descriptor. | |
| Throughout this subsection, you will be coding <tt>designViewTopComponent.java</tt> in the Source Editor's Source view. | |
| <ol> | |
| <p><li>By default, this is the <tt>designViewTopComponent.java</tt> class's class declaration: | |
| <p><pre class="examplecode">final class designViewTopComponent extends <a href="https://netbeans.org/download/dev/javadoc/org-openide-windows/org/openide/windows/TopComponent.html">TopComponent</a> {</pre> | |
| <p>Change it to the following in the Source Editor: | |
| <p><pre class="examplecode">final class designViewTopComponent extends CloneableTopComponent implements MultiViewElement, Serializable {</pre> | |
| <p>Red wavy lines appear under the class declaration, indicating an error. | |
| Put the cursor in the line and press Alt-Enter. The IDE suggests a solution: | |
| <p><img src="../images/tutorials/multiview/alt-enter-1.png" alt="alt-enter-1"> | |
| <p>Select the suggestion. Several import statements are generated for you. | |
| <p>Continue pressing Alt-Enter in the class declaration. Accept any suggestions the IDE gives you, such as the following: | |
| <p><img src="../images/tutorials/multiview/alt-enter-2.png" alt="alt-enter-2"> | |
| <p>Now you have several new methods and import statements, all required by the NetBeans APIs that you will be using later. | |
| <p><li>The red wavy lines have not disappeared, indicating that there are still errors. When you hover | |
| your mouse over the red error icon, you see the cause of the error: | |
| <p><img src="../images/tutorials/multiview/alt-enter-4.png" alt="alt-enter-4"> | |
| <p>To fix this, and similar errors that follow after you fix this specific error, paste the following code | |
| into <tt>designViewTopComponent.java</tt>, right at the end after the final method: | |
| <p><pre class="examplecode">// <editor-fold defaultstate="collapsed" desc=" Boilerplate code "> | |
| public void componentActivated() { | |
| try { | |
| loadData(); | |
| } catch (SAXException ex) { | |
| ex.printStackTrace(); | |
| } catch (IOException ex) { | |
| ex.printStackTrace(); | |
| } catch (ParserConfigurationException ex) { | |
| ex.printStackTrace(); | |
| } | |
| } | |
| public void componentDeactivated() { | |
| } | |
| public void componentShowing() { | |
| } | |
| public void componentHidden() { | |
| }// </editor-fold></pre> | |
| <p>Notice that a red wavy line appears under <tt>loadData()</tt>. This is because you have not defined | |
| this method yet. Press Alt-Enter in this line and the IDE displays a suggestion: | |
| <p><img src="../images/tutorials/multiview/alt-enter-5.png" alt="alt-enter-5"> | |
| <p>Accept the suggestion. The <tt>loadData()</tt> method is created. (Red wavy lines will still be present, but you | |
| will solve those later.) The IDE will use | |
| this method to load the values of the XML tags into the <tt>JTextFields</tt> and <tt>JComboBoxes</tt> in the Design view. Doing this means, in turn, | |
| using the <tt>loadData()</tt> method to traverse the <tt>Document</tt> object. Before going further, | |
| declare the following variables at the top of the class: | |
| <p><pre class="examplecode">private MultiViewElementCallback callback; | |
| private CloseOperationState cos; | |
| private jbossddEditorSupport support; | |
| private Node contextrootNode; | |
| private Node descriptionNode; | |
| private Node nameNode; | |
| private Node typeNode; | |
| private Node authorityNode; | |
| private Document xmldoc; | |
| private NodeListener listener; | |
| private MultiDataObject.Entry entry;</pre> | |
| <p>Right-click in the IDE and choose Fix Imports (Alt-Shift-F) to let the IDE generate the required import statements. In the | |
| Fix Imports dialog box, choose <tt>org.w3c.dom.Document</tt> and <tt>org.w3c.dom.Node</tt>. No imports will be found for | |
| <tt>jbossddEditorSupport</tt>, because you have not created this class yet. | |
| <p>Now fill out the new <tt>loadData()</tt> method so that its content is as follows: | |
| <p><pre class="examplecode">private void loadData() throws IOException, ParserConfigurationException, SAXException{ | |
| jbossddEditorSupport support = (jbossddEditorSupport) entry.getDataObject().getCookie(jbossddEditorSupport.class); | |
| if(null != support){ | |
| InputStream is = support.getInputStream(); | |
| DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); | |
| xmldoc = builder.parse(is); | |
| NodeList list = xmldoc.getElementsByTagName("context-root"); | |
| if(list.getLength() > 0){ | |
| Node current = list.item(0); | |
| //Set the context-root textfield with the content of the node | |
| contextrootNode = current.getFirstChild(); | |
| this.contextroot.setText(contextrootNode.getNodeValue()); | |
| //Set the the description textfield with the content of node | |
| descriptionNode = xmldoc.getElementsByTagName("description").item(0).getFirstChild(); | |
| this.description.setText(descriptionNode.getNodeValue()); | |
| //Set the resource reference name textfield with the content of node | |
| nameNode = xmldoc.getElementsByTagName("res-ref-name").item(0).getFirstChild(); | |
| this.name.setText(nameNode.getNodeValue()); | |
| //Set the resource type textfield with the content of node | |
| typeNode = xmldoc.getElementsByTagName("res-type").item(0).getFirstChild(); | |
| this.type.setSelectedItem(typeNode.getNodeValue()); | |
| //Set the resource authority textfield with the content of node | |
| authorityNode = xmldoc.getElementsByTagName("res-auth").item(0).getFirstChild(); | |
| this.authority.setSelectedItem(authorityNode.getNodeValue()); | |
| } | |
| is.close(); | |
| } | |
| }</pre> | |
| <p>New red wavy lines appear, because your code refers to <tt>jbossddEditorSupport.java</tt>, which | |
| you have not created yet. You will do this in the <a href="#adding-editor-support">Adding Editor Support</a> section. | |
| <p><li>Next, specify what should happen when the user types values in the Design view. For each component (in the case of this tutorial, | |
| that means for each <tt>JTextField</tt> and <tt>JComboBox</tt>), add a <tt>KeyListener</tt>, as shown below. When the <tt>keyReleased</tt> event | |
| for each component is invoked, the content of the related component is put in a specified node in the <tt>Document</tt> object. | |
| <p><pre class="examplecode">private void addSupport(){ | |
| contextroot.addKeyListener(new KeyListener() { | |
| public void keyPressed(KeyEvent e) { | |
| } | |
| public void keyReleased(KeyEvent e) { | |
| contextrootNode.setNodeValue(contextroot.getText()); | |
| ByteArrayOutputStream os = new ByteArrayOutputStream(); | |
| try { | |
| XMLUtil.write(xmldoc, os, "UTF-8"); | |
| StyledDocument doc = support.getDocument(); | |
| doc.remove(0, doc.getLength()); | |
| doc.insertString(0, os.toString(), null); | |
| os.close(); | |
| } catch (IOException ex) { | |
| ex.printStackTrace(); | |
| }catch (BadLocationException ex) { | |
| ex.printStackTrace(); | |
| } | |
| entry.getDataObject().setModified(true); | |
| } | |
| public void keyTyped(KeyEvent e) { | |
| } | |
| }); | |
| description.addKeyListener(new KeyListener() { | |
| public void keyPressed(KeyEvent e) { | |
| } | |
| public void keyReleased(KeyEvent e) { | |
| descriptionNode.setNodeValue(description.getText()); | |
| ByteArrayOutputStream os = new ByteArrayOutputStream(); | |
| try { | |
| XMLUtil.write(xmldoc, os, "UTF-8"); | |
| StyledDocument doc = support.getDocument(); | |
| doc.remove(0, doc.getLength()); | |
| doc.insertString(0, os.toString(), null); | |
| os.close(); | |
| } catch (IOException ex) { | |
| ex.printStackTrace(); | |
| }catch (BadLocationException ex) { | |
| ex.printStackTrace(); | |
| } | |
| } | |
| public void keyTyped(KeyEvent e) { | |
| } | |
| }); | |
| name.addKeyListener(new KeyListener() { | |
| public void keyPressed(KeyEvent e) { | |
| } | |
| public void keyReleased(KeyEvent e) { | |
| nameNode.setNodeValue(name.getText()); | |
| ByteArrayOutputStream os = new ByteArrayOutputStream(); | |
| try { | |
| XMLUtil.write(xmldoc, os, "UTF-8"); | |
| StyledDocument doc = support.getDocument(); | |
| doc.remove(0, doc.getLength()); | |
| doc.insertString(0, os.toString(), null); | |
| os.close(); | |
| } catch (IOException ex) { | |
| ex.printStackTrace(); | |
| }catch (BadLocationException ex) { | |
| ex.printStackTrace(); | |
| } | |
| } | |
| public void keyTyped(KeyEvent e) { | |
| } | |
| }); | |
| type.addKeyListener(new KeyListener() { | |
| public void keyPressed(KeyEvent e) { | |
| } | |
| public void keyReleased(KeyEvent e) { | |
| typeNode.setNodeValue(type.getSelectedItem().toString()); | |
| ByteArrayOutputStream os = new ByteArrayOutputStream(); | |
| try { | |
| XMLUtil.write(xmldoc, os, "UTF-8"); | |
| StyledDocument doc = support.getDocument(); | |
| doc.remove(0, doc.getLength()); | |
| doc.insertString(0, os.toString(), null); | |
| os.close(); | |
| } catch (IOException ex) { | |
| ex.printStackTrace(); | |
| }catch (BadLocationException ex) { | |
| ex.printStackTrace(); | |
| } | |
| } | |
| public void keyTyped(KeyEvent e) { | |
| } | |
| }); | |
| authority.addKeyListener(new KeyListener() { | |
| public void keyPressed(KeyEvent e) { | |
| } | |
| public void keyReleased(KeyEvent e) { | |
| authorityNode.setNodeValue(authority.getSelectedItem().toString()); | |
| ByteArrayOutputStream os = new ByteArrayOutputStream(); | |
| try { | |
| XMLUtil.write(xmldoc, os, "UTF-8"); | |
| StyledDocument doc = support.getDocument(); | |
| doc.remove(0, doc.getLength()); | |
| doc.insertString(0, os.toString(), null); | |
| os.close(); | |
| } catch (IOException ex) { | |
| ex.printStackTrace(); | |
| }catch (BadLocationException ex) { | |
| ex.printStackTrace(); | |
| } | |
| } | |
| public void keyTyped(KeyEvent e) { | |
| } | |
| }); | |
| }</pre> | |
| <p><li>Somewhere in <tt>designViewTopComponent.java</tt> the following methods are defined: | |
| <p><pre class="examplecode">public JComponent getVisualRepresentation() { | |
| } | |
| public JComponent getToolbarRepresentation() { | |
| } | |
| public void setMultiViewCallback(MultiViewElementCallback multiViewElementCallback) { | |
| } | |
| public CloseOperationState canCloseElement() { | |
| }</pre> | |
| <p>Replace these methods with the following (and then press Alt-Shift-F to fix the import statements): | |
| <p><pre class="examplecode">public JComponent getVisualRepresentation() { | |
| return this; | |
| } | |
| public JComponent getToolbarRepresentation() { | |
| return new JToolBar(); | |
| } | |
| public void setMultiViewCallback(MultiViewElementCallback multiViewElementCallback) { | |
| this.callback = callback; | |
| } | |
| public CloseOperationState canCloseElement() { | |
| if (entry.getDataObject().isModified()) { | |
| return this.cos; | |
| } else { | |
| return CloseOperationState.STATE_OK; | |
| } | |
| }</pre> | |
| <p><li><i>Below</i> the existing constructor in <tt>designViewTopComponent.java</tt>, add the following methods: | |
| <p><pre class="examplecode">public designViewTopComponent(MultiDataObject.Entry entry, CloseOperationState cos){ | |
| this(); | |
| this.entry = entry; | |
| this.cos = cos; | |
| this.support = (jbossddEditorSupport) entry.getDataObject().getCookie(jbossddEditorSupport.class); | |
| addSupport(); | |
| try { | |
| loadData(); | |
| } catch (SAXException ex) { | |
| ex.printStackTrace(); | |
| } catch (IOException ex) { | |
| ex.printStackTrace(); | |
| } catch (ParserConfigurationException ex) { | |
| ex.printStackTrace(); | |
| } | |
| init(); | |
| } | |
| protected void updateNameAndIcon(DataObject o, org.openide.nodes.Node n) { | |
| String displayName = n.getDisplayName(); | |
| if (o.isModified()) { | |
| setName(NbBundle.getMessage(designViewTopComponent.class, "LBL_modified_name", displayName)); | |
| } else { | |
| setName(displayName); | |
| } | |
| setIcon(n.getIcon(BeanInfo.ICON_COLOR_16x16)); | |
| } | |
| private void init(){ | |
| final DataObject o = entry.getDataObject(); | |
| final org.openide.nodes.Node n = o.getNodeDelegate(); | |
| updateNameAndIcon(o, n); | |
| listener = new NodeAdapter() { | |
| public void propertyChange(PropertyChangeEvent ev) { | |
| String prop = ev.getPropertyName(); | |
| if (prop == null || | |
| prop.equals(org.openide.nodes.Node.PROP_DISPLAY_NAME) || | |
| prop.equals(org.openide.nodes.Node.PROP_ICON) || | |
| prop.equals(DataObject.PROP_MODIFIED)) { | |
| updateNameAndIcon(o, n); | |
| } | |
| } | |
| }; | |
| n.addNodeListener(NodeOp.weakNodeListener(listener, n)); | |
| o.addPropertyChangeListener(WeakListeners.propertyChange(listener, o)); | |
| }</pre> | |
| </ol> | |
| <h3 class="tutorial"><a name="adding-editor-support"></a>Adding Editor Support</h3> | |
| <ol><li>Inner class: | |
| <p><pre class="examplecode">private class DesignView implements <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-core-multiview/org/netbeans/core/spi/multiview/MultiViewDescription.html">MultiViewDescription</a>, Serializable{ | |
| private static final long serialVersionUID = 0L; | |
| private <a href="https://netbeans.org/download/dev/javadoc/org-openide-loaders/org/openide/loaders/MultiDataObject.Entry.html">MultiDataObject.Entry</a> entry; | |
| private <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-core-multiview/org/netbeans/core/spi/multiview/CloseOperationState.html">CloseOperationState</a> cos; | |
| public DesignView(MultiDataObject.Entry entry, CloseOperationState cos){ | |
| this.cos = cos; | |
| this.entry = entry; | |
| } | |
| public int <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-core-multiview/org/netbeans/core/spi/multiview/MultiViewDescription.html#getPersistenceType()">getPersistenceType()</a> { | |
| return TopComponent.PERSISTENCE_ONLY_OPENED; | |
| } | |
| public String <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-core-multiview/org/netbeans/core/spi/multiview/MultiViewDescription.html">getDisplayName()</a> { | |
| return "Design"; | |
| } | |
| public Image <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-core-multiview/org/netbeans/core/spi/multiview/MultiViewDescription.html#getIcon()">getIcon()</a> { | |
| return entry.getDataObject().getNodeDelegate().getIcon(BeanInfo.ICON_COLOR_16x16); | |
| } | |
| public HelpCtx <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-core-multiview/org/netbeans/core/spi/multiview/MultiViewDescription.html#getHelpCtx()">getHelpCtx()</a> { | |
| return entry.getDataObject().getHelpCtx(); | |
| } | |
| public String <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-core-multiview/org/netbeans/core/spi/multiview/MultiViewDescription.html#preferredID()">preferredID()</a> { | |
| return ".design"; | |
| } | |
| public MultiViewElement <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-core-multiview/org/netbeans/core/spi/multiview/MultiViewDescription.html#createElement()">createElement()</a> { | |
| designViewTopComponent component = new designViewTopComponent(entry, cos); | |
| return component; | |
| } | |
| }</pre> | |
| <li>Inner class: | |
| <p><pre class="examplecode">private class SourceView implements MultiViewDescription, Serializable{ | |
| private static final long serialVersionUID = 0L; | |
| private jbossddDataObject object; | |
| private CloseOperationState cos; | |
| public SourceView(jbossddDataObject object, CloseOperationState cos){ | |
| this.cos = cos; | |
| this.object = object; | |
| } | |
| public int getPersistenceType() { | |
| return TopComponent.PERSISTENCE_ONLY_OPENED; | |
| } | |
| public String getDisplayName() { | |
| return "Source"; | |
| } | |
| public Image getIcon() { | |
| return object.getNodeDelegate().getIcon(BeanInfo.ICON_COLOR_16x16); | |
| } | |
| public HelpCtx getHelpCtx() { | |
| return object.getHelpCtx(); | |
| } | |
| public String preferredID() { | |
| return ".source"; | |
| } | |
| public MultiViewElement createElement() { | |
| return new XMLElement(object, cos); | |
| } | |
| public class XMLElement extends CloneableEditor | |
| implements MultiViewElement, Serializable{ | |
| private static final long serialVersionUID = 0L; | |
| private transient MultiViewElementCallback _multiViewObserver; | |
| jbossddDataObject object; | |
| CloseOperationState cos; | |
| /** Creates a new instance of MetaViewXMLElement */ | |
| public XMLElement(jbossddDataObject object, CloseOperationState cos) { | |
| super((jbossddEditorSupport)object.getCookie(jbossddEditorSupport.class)); | |
| this.cos = cos; | |
| this.object = object; | |
| } | |
| public JComponent getVisualRepresentation() { | |
| return this; | |
| } | |
| public JComponent getToolbarRepresentation() { | |
| return new javax.swing.JToolBar(); | |
| } | |
| public void setMultiViewCallback(MultiViewElementCallback multiViewElementCallback) { | |
| _multiViewObserver = multiViewElementCallback; | |
| } | |
| public CloseOperationState canCloseElement() { | |
| if (this.object.isModified()) { | |
| return this.cos; | |
| } else { | |
| return CloseOperationState.STATE_OK; | |
| } | |
| } | |
| public void componentDeactivated() { | |
| super.componentDeactivated(); | |
| } | |
| public void componentActivated() { | |
| super.componentActivated(); | |
| } | |
| public void componentHidden() { | |
| super.componentHidden(); | |
| } | |
| public void componentShowing() { | |
| super.componentShowing(); | |
| } | |
| public void componentOpened() { | |
| super.componentOpened(); | |
| } | |
| public void componentClosed() { | |
| super.componentClosed(); | |
| } | |
| } | |
| }</pre> | |
| </ol> | |
| <h3 class="tutorial"><a name="enabling-multiview-editor"></a>Enabling the Multiview Editor</h3> | |
| <ol><li>a | |
| </ol> | |
| </div> | |
| <br /> | |
| <h2><a name="registering-module"></a>Registering the Module</h2> | |
| <p>The <tt>layer.xml</tt> file registers everything that you want to make available to the NetBeans system. | |
| However, in this tutorial you do not need to register anything manually yourself | |
| because the New File wizard and the New Window Component wizard did that for you automatically. For example, when you | |
| created the new file type, the New File wizard added XML tags to the <tt>layer.xml</tt> file to register the | |
| new file type's dummy template in the New File wizard. | |
| <br /> | |
| <!-- ======================================================================================= --> | |
| <h2><a name="building-and-installing-module"></a>Building and Installing the Module</h2> | |
| <p>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.</p> | |
| <div class="indent"> | |
| <h3 class="tutorial"><a name="install-plugin"></a>Installing and Using the Module</h3> | |
| <ol> | |
| <li>In the Projects window, right-click the <tt>jbossVisualEditor</tt> project node and choose Install/Reload | |
| in Target Platform. | |
| <p>The module is built and installed in the target platform. The target platform opens so that you | |
| can try out your new module. The default target platform is the | |
| installation used by the current instance of the development IDE. | |
| <p><li>Verify that the module is correctly installed by using it as | |
| shown in <a href="#installing-sample">Installing the Sample</a>. | |
| </ol> | |
| <h3 class="tutorial"><a name="creating-shareable-module-binary"></a>Creating a Shareable Module Binary</h3> | |
| <ol> | |
| <li>In the Projects window, right-click the <tt>jbossVisualEditor</tt> project and choose Create NBM. | |
| <p>The NBM file is created and you can view it in the Files window (Ctrl-2): | |
| <p align="left"><img src="../images/tutorials/multiview/create-nbm.png" alt="Shareable NBM."> | |
| <li>Make the module available to others via, for example, e-mail. | |
| <p><li>The recipient can install the module by using the Update Center. Choose Tools > Update Center | |
| from the main menu. | |
| </ol> | |
| </div> | |
| <br /> | |
| <!-- ======================================================================================== --> | |
| <h2><a name="nextsteps"></a>Next Steps</h2> | |
| <p>For more information about creating and developing NetBeans modules, see the following resources: | |
| <ul> | |
| <p><li><a href="https://platform.netbeans.org/index.html">Module Developer's Resources</a></li> | |
| <p><li><a href="https://netbeans.org/download/dev/javadoc/">NetBeans API List (Current Development Version)</a></li> | |
| <p><li><a href="http://apisupport.netbeans.org/new-apisupport.html">New API Support-Proposal</a></li></ul> | |
| </p> | |
| <hr> | |
| <!-- ======================================================================================== --> | |
| <h2><a name="version"></a>Versioning </h2> | |
| <p> | |
| <table width="76%" border="1"> | |
| <tbody> | |
| <tr> | |
| <td> | |
| <div align="left"><b>Version</b></div> | |
| </td> | |
| <td> | |
| <div align="left"><b>Date</b></div> | |
| </td> | |
| <td> | |
| <div align="left"><b>Changes</b></div> | |
| </td> | |
| <td> | |
| <div align="left"><b>Open Issues</b></div> | |
| </td> | |
| </tr> | |
| <tr> | |
| <td> | |
| 1 | |
| </td> | |
| <td> | |
| 14 December 2005 | |
| </td> | |
| <td> | |
| Initial version | |
| </td> | |
| <td><ul><li>Maybe find out and use the <i>real</i> namespace instead of my made up one. | |
| <li>Find out why the DOCTYPE resolver didn't work. | |
| <li>Maybe redesign the Design view using correct Matisse approach and official u.i. specs. | |
| <li>Find out why the menu-item doesn't produce the Design view with all the values filled in. | |
| <li>More info needed on the <tt>addSupport()</tt> method. | |
| <li>Many more code explanations needed. | |
| <ul> | |
| </ul> | |
| </td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| </body> | |
| </html> |