<!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> |