<!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>File Type Integration 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 using the DataLoader API, as well as other APIs | |
relating to file support."/> | |
<!-- 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>File Type Integration Tutorial</h1> | |
<p>This tutorial shows you how to write a module that lets the IDE, | |
or any other application built on the NetBeans Platform, recognize a new file type.</p> | |
<p><b class="notes">Note:</b> This document uses NetBeans IDE 8.0 or above and NetBeans Platform 8.0 or above. If you | |
are using an earlier version, see <a href="74/nbm-filetype.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="#intro">Introduction to File Type Integration</a></li> | |
<li><a href="#creating">Creating the Module Project</a></li> | |
<li><a href="#recognizing">Recognizing Abc Files</a></li> | |
<li><a href="#install">Installing and Trying Out the Functionality</a></li> | |
<li><a href="#adding">Creating Features for Abc Files</a> | |
<ul> | |
<li><a href="#action">Adding a Context-Sensitive Action</a></li> | |
<li><a href="#multiview">Creating Additional Multiview Windows</a></li> | |
<li><a href="#parse">Parsing the File</a></li> | |
<li><a href="#properties">Extending the Properties Window</a></li> | |
<li><a href="#synchronized">Creating Synchronized Views</a></li> | |
</ul></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/AbcFileType">completed tutorial source code</a>.</p> | |
<h2 class="tutorial"><a name="intro"></a>Introduction to File Type Integration</h2> | |
<p>File types that are recognized in the IDE have their own icons, menu items, and behavior. | |
The "files" being shown are <tt>FileObjects</tt>—wrappers | |
around <tt>java.io.File</tt> or, in the case of configuration files, typically wrappers around data stored in some other way, | |
such as inside XML files in modules. What you actually <i>see</i> are <tt>Nodes</tt>, which provide functionality like actions | |
and localized names to objects like files. In between <tt>Nodes</tt> and <tt>FileObjects</tt> are <tt>DataObjects</tt>. | |
A <tt>DataObject</tt> is like a <tt>FileObject</tt>, except that it knows what kind of file is being shown, and there are | |
usually different types of <tt>DataObject</tt> for files with different extensions and XML files with different namespaces. | |
Each <tt>DataObject</tt> is provided by a different module, each implementing support for one or more file types—for example, | |
the Image module makes it possible to recognize and open <tt>.gif</tt> and <tt>.png</tt> files.</p> | |
<p>A module that recognizes a file type installs a <tt>DataLoader</tt>—a factory for a file-type-specific <tt>DataObject</tt>. | |
When a folder is expanded, the IDE asks each known <tt>DataLoader</tt>, "Do you know what this is?" The first one that says | |
"Yes" creates the <tt>DataObject</tt> for the file. In order to actually display something for each file, the system calls | |
<tt>DataObject.getNodeDelegate()</tt> for each <tt>DataObject</tt> and the <tt>Nodes</tt> are what you actually see in the IDE.</p> | |
<p>Below, the diagram on the left shows what each item mentioned above makes available:</p> | |
<p><img src="../images/tutorials/filetype/diagram-dataobject2.png" alt="Diagram."/></p> | |
<p>In this tutorial, you create a module that installs a <tt>DataLoader</tt> for imaginary "Abc" files | |
(<tt>.abc</tt> file extension). By default, a file with the "abc" extension is treated as any other file that | |
the IDE does not recognize—it is treated as a text file and, as a result, the IDE provides the same functionality for | |
Abc files as it does for text files. Once you have created the module, you will be shown how to enhance it | |
with functionality that will be available to Abc files only. When you complete the development cycle, you can easily let others make use of | |
your module—the IDE lets you create a binary that you can share with others, who can then install it through the | |
Plugin Manager of their application.</p> | |
<!-- ===================================================================================== --> | |
<h2 class="tutorial"><a name="creating"></a>Creating the Module Project</h2> | |
<p>In this section, we use a wizard to create the source structure that every NetBeans module requires. The | |
source structure consists of certain folders in specific places and a set of files that are | |
always needed. For example, every NetBeans module requires a <tt>nbproject</tt> folder, which holds | |
the project's metadata, such as a <tt>build.xml</tt> file with Ant targets for building and running the module.</p> | |
<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><p>In the Name and Location panel, type <tt>AbcFileType</tt> in Project Name. | |
Change the | |
Project Location to any directory on your computer. Click Next.</p></li> | |
<li><p>In the Basic Module Configuration panel, type <tt>org.myorg.abcfiletype</tt> | |
as the Code Name Base. Click Finish.</p></li> | |
</ol> | |
</div> | |
<p> The IDE creates the <tt>AbcFileType</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> | |
<!-- ===================================================================================== --> | |
<h2><a name="recognizing"></a>Recognizing Abc Files</h2> | |
<p>In this section, we use the New File Type wizard to create the classes and other files necessary for | |
recognizing Abc files as being distinct from all other files.</p> | |
<div class="indent"> | |
<ol> | |
<li>Right-click the project node and | |
choose New > Other > Module Development > File Type:<br/><br/> | |
<p><img src="../images/tutorials/filetype/72/new-filetype-1.png" alt="Step 1 of New File wizard."/></p> | |
</li> | |
<li>In the File Recognition panel, do the following:<br/><br/> | |
<ul> | |
<li>In the MIME Type field, type <tt>text/x-abc</tt>.</li> | |
<li>In the Filename Extension field, type <tt>abc ABC</tt>.</li> | |
</ul> | |
<p>The File Recognition panel should now look as follows:</p><br/> | |
<p><img src="../images/tutorials/filetype/72/new-filetype-2.png" alt="Step 1 of New File wizard."/></p> | |
<p class="tips">Note the following about the fields in the File Recognition panel:</p> | |
<ul> | |
<li><b>MIME Type.</b> Specifies the data object's unique MIME type.</li> | |
<li>by | |
<ul><li><b>Filename Extension.</b> Specifies one or more file extensions that the IDE will recognize | |
as belonging to the specified MIME type. Separators are commas, spaces, or both. Therefore, all of the following are valid: | |
<ul><li><tt>abc,def</tt></li> | |
<li><tt>abc def</tt></li> | |
<li><tt>abc def</tt></li> | |
<li><tt>abc, def ghi, wow</tt></li></ul> | |
<p>Let's imagine that Abc files can be case-sensitive. For | |
this reason, you specify <i>two</i> MIME types in this tutorial—<tt>abc</tt> and <tt>ABC</tt>.</p></li> | |
<li><b>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. You can use this to, for example, distinguish | |
between a JBoss deployment descriptor and a WebLogic deployment descriptor. Once you have made | |
this distinction, you can ensure that menu items added to the JBoss deployment descriptor's contextual menu | |
are not available to the WebLogic deployment descriptor. For an example, see | |
the <a href="nbm-palette-api2.html">NetBeans Component Palette Module Tutorial</a>.</li></ul></li> | |
</ul> | |
<p>Click Next.</p></li> | |
<li><p>In the Name, Icon and Location panel, type <tt>Abc</tt> as the Class Name Prefix | |
and browse to any 16x16 pixel image file as the new file type's icon, as shown below:</p><br/> | |
<p><img src="../images/tutorials/filetype/72/new-filetype-3.png" alt="Step 2 of New File wizard."/></p> | |
<p><b>Note:</b> You can use any icon of a 16x16 pixel dimension. If you like, you can | |
right-click on this one and save it locally, and then | |
specify it in the wizard step above: <img src="../images/tutorials/filetype/Datasource.gif" alt="Datasource.gif"/></p></li> | |
<li>Click Finish.</li> | |
</ol> | |
</div> | |
<p>The Projects window should now look as follows:</p> | |
<p><img src="../images/tutorials/filetype/72/new-filetype-4.png" alt="Final Projects window."/></p> | |
<p>Each of the newly generated files is briefly introduced:</p> | |
<ul> | |
<li><b>AbcDataObject.java.</b> Wraps a <tt>FileObject</tt>. DataObjects are produced by DataLoaders. | |
For more information, see <a href="http://wiki.netbeans.org/wiki/view/DevFaqDataObject">What is a DataObject?</a>.</li> | |
<li><b>AbcTemplate.abc.</b> Provides the basis of a file template that is registered | |
in the <tt>layer.xml</tt> via an annotation defined in the <tt>package-info.java</tt> file, | |
such that it will be installed in the New File dialog | |
as a new template.</li> | |
<li><b>AbcVisualElement.java.</b> Sample visual tab in multiview editor.</li> | |
</ul> | |
<!-- ======================================================================================= --> | |
<h2><a name="install"></a>Installing and Trying Out the Functionality</h2> | |
<p>Let's now install the module and then use the basic | |
functionality we've created so far.</p> | |
<div class="indent"> | |
<ol> | |
<li><p>In the Projects window, right-click the <tt>AbcFileType</tt> project and choose Run. | |
A new instance of the IDE starts, installing your module into itself.</p></li> | |
<li><p>Choose File | New Project and create a new Java application.</p></li> | |
<li><p>Once you have a new application, go to the New File dialog and you will | |
see your new file template:</p> | |
<br/> | |
<p><img style="border: 1px solid #0e1b55" src="../images/tutorials/filetype/72/trying-out-1.png" alt="Dummy template."/></p> | |
<p>Click Next, choose a folder to store the template, and click Finish.</p> | |
</li> | |
<li><p>Open the file and you see a text editor:</p> | |
<p><img style="border: 1px solid #0e1b55" src="../images/tutorials/filetype/72/trying-out-2.png" alt="Dummy template."/></p> | |
<p>Click the "Visual" tab and notice that you have a starting point for | |
creating a visual page in a multiview editor:</p> | |
<p><img style="border: 1px solid #0e1b55" src="../images/tutorials/filetype/72/trying-out-3.png" alt="Dummy template."/></p> | |
</li> | |
</ol> | |
</div> | |
<!-- ===================================================================================== --> | |
<h2><a name="adding"></a>Creating Features for Abc Files</h2> | |
<p>Now that the NetBeans Platform is able to distinguish Abc files from all other types of files, | |
it is time to add features specifically for these types of files. In this section, we add a menu | |
item on the right-click contextual menu of the file's node in the explorer windows, such as in | |
the Projects window, and we enable the file to open into a window, instead of into an editor.</p> | |
<div class="indent"> | |
<h3 class="tutorial"><a name="action"></a>Adding a Context-Sensitive Action</h3> | |
<p>In this subsection, we use the New Action wizard to create a Java class that | |
will perform an action for our file type.</p> | |
<div class="indent"> | |
<ol> | |
<li>Right-click the <tt>org.myorg.abcfiletype</tt> package and | |
choose New > Action.</li> | |
<li><p>In the Action Type panel, click Conditionally Enabled. Type <tt>AbcDataObject</tt>, which | |
is the fully qualified name of the data object generated above by the New File Type wizard, as shown below:</p> | |
<br/> | |
<p><img src="../images/tutorials/filetype/72/new-action-1.png" alt="Step 1 of New Action wizard."/></p> | |
<p>Click Next.</p></li> | |
<li><p>In the GUI Registration panel, select the 'File' 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, Unselect Global Menu Item and then select File Type Contect Menu Item. | |
In the Content Type drop-down list, select the MIME type you specified above in the New File Type | |
wizard, as shown below:</p> | |
<br/> | |
<p><img src="../images/tutorials/filetype/72/new-action-2.png" alt="Step 2 of New Action wizard."/></p> | |
<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>StartAnalyzerActionListener</tt> as the Class Name | |
and type <tt>Start Analyzer</tt> as the Display Name. Optionally, provide an icon | |
to be displayed.</p> | |
<br/> | |
<p><img src="../images/tutorials/filetype/72/new-action-3.png" alt="Step 3 of New Action wizard."/></p> | |
<p>Click Finish and <tt>StartAnalyzerActionListener.java</tt> is added to the <tt>org.myorg.abcfiletype</tt> package.</p> | |
<pre class="examplecode">package org.myorg.abcfiletype; | |
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.util.NbBundle.Messages; | |
@ActionID( | |
category = "File", | |
id = "org.myorg.abcfiletype.StartAnalyzerActionListener") | |
@ActionRegistration( | |
displayName = "#CTL_StartAnalyzerActionListener") | |
@ActionReference(path = "Loaders/text/x-abc/Actions", position = 0) | |
@Messages("CTL_StartAnalyzerActionListener=Start Analyzer") | |
public final class StartAnalyzerActionListener implements ActionListener { | |
private final AbcDataObject context; | |
public StartAnalyzerActionListener(AbcDataObject context) { | |
this.context = context; | |
} | |
@Override | |
public void actionPerformed(ActionEvent ev) { | |
// TODO use context | |
} | |
}</pre> | |
</li> | |
<li>In the Source Editor, add some code to the action's <tt>actionPerformed</tt> method: | |
<pre class="examplecode">@Override | |
public void actionPerformed(ActionEvent ev) { | |
FileObject f = context.getPrimaryFile(); | |
String displayName = FileUtil.getFileDisplayName(f); | |
String msg = "I am " + displayName + ". Hear me roar!"; | |
NotifyDescriptor nd = new NotifyDescriptor.Message(msg); | |
DialogDisplayer.getDefault().notify(nd); | |
}</pre> | |
<p>Press Ctrl-Shift-I. The IDE automatically adds import statements to the top of the class.</p> | |
</li> | |
<li>Run the module again, as you did in the previous section.</li> | |
<li><p>Create an Abc file, using the template shown | |
in the previous section, and right-click the file's node in one of the | |
explorer views, such as in the Projects window or Favorites window.</p> | |
<br/> | |
<p><img src="../images/tutorials/filetype/72/new-action-4.png" alt="Final Projects window."/></p></li> | |
<li><p>Choose the new menu item, the Abc file's name and location are shown:</p><br/> | |
<p><img src="../images/tutorials/filetype/72/new-action-5.png" alt="Information."/></p></li> | |
</ol> | |
</div> | |
<p>You now know how to create a new context-sensitive action that appears in the context | |
menu of a file of the given type, in the Projects window, Files window | |
or the Favorites window.</p> | |
<h3 class="tutorial"><a name="multiview"></a>Creating Additional Multiview Windows</h3> | |
<p>Let's create a new multiview window. The first tab of | |
a multiview window is typically used to display the source view | |
of the file, while the second and subsequent tabs typically show various visual views. More | |
than two tabs can also be provided, each tab providing further levels | |
of detail about the opened file.</p> | |
<div class="indent"> | |
<ol> | |
<li>For each tab that you want to create in the multiview window, create a class that | |
implements JPanel and MultiViewElement. | |
For purposes of this tutorial, start by creating a class called | |
<tt>AbcVisualElement2</tt>, implementing the specified classes: | |
<pre class="examplecode">import javax.swing.Action; | |
import javax.swing.JComponent; | |
import javax.swing.JPanel; | |
import javax.swing.JToolBar; | |
import org.netbeans.core.spi.multiview.CloseOperationState; | |
import org.netbeans.core.spi.multiview.MultiViewElement; | |
import org.netbeans.core.spi.multiview.MultiViewElementCallback; | |
import org.openide.awt.UndoRedo; | |
import org.openide.util.Lookup; | |
import org.openide.util.NbBundle; | |
import org.openide.windows.TopComponent; | |
@MultiViewElement.Registration(displayName = "#LBL_Abc_VISUAL2", | |
iconBase = "org/myorg/abcfiletype/Datasource.gif", | |
mimeType = "text/x-abc", | |
persistenceType = TopComponent.PERSISTENCE_NEVER, | |
preferredID = "AbcVisual2", | |
position = 3000) | |
@NbBundle.Messages({ | |
"LBL_Abc_VISUAL2=Visual2" | |
}) | |
public class AbcVisualElement2 extends JPanel implements MultiViewElement { | |
private AbcDataObject obj; | |
private JToolBar toolbar = new JToolBar(); | |
private transient MultiViewElementCallback callback; | |
public AbcVisualElement2(Lookup lkp) { | |
obj = lkp.lookup(AbcDataObject.class); | |
assert obj != null; | |
} | |
@Override | |
public String getName() { | |
return "AbcVisualElement2"; | |
} | |
@Override | |
public JComponent getVisualRepresentation() { | |
return this; | |
} | |
@Override | |
public JComponent getToolbarRepresentation() { | |
return toolbar; | |
} | |
@Override | |
public Action[] getActions() { | |
return new Action[0]; | |
} | |
@Override | |
public Lookup getLookup() { | |
return obj.getLookup(); | |
} | |
@Override | |
public void componentOpened() { | |
} | |
@Override | |
public void componentClosed() { | |
} | |
@Override | |
public void componentShowing() { | |
} | |
@Override | |
public void componentHidden() { | |
} | |
@Override | |
public void componentActivated() { | |
} | |
@Override | |
public void componentDeactivated() { | |
} | |
@Override | |
public UndoRedo getUndoRedo() { | |
return UndoRedo.NONE; | |
} | |
@Override | |
public void setMultiViewCallback(MultiViewElementCallback callback) { | |
this.callback = callback; | |
} | |
@Override | |
public CloseOperationState canCloseElement() { | |
return CloseOperationState.STATE_OK; | |
} | |
}</pre> | |
</li> | |
<li><p>Install and open the file again. Now you have a multiview window with an additional visual tab.</p> | |
</li> | |
</ol> | |
</div> | |
<p>You now have two visual tabs in a multiview window. For each additional tab, | |
create a new class just like the above.</p> | |
<!-- ======================================================================================= --> | |
<h3 class="tutorial"><a name="parse"></a>Parsing the File</h3> | |
<p>A <tt>DataObject</tt> is like a <tt>FileObject</tt>, except that it | |
knows what kind of file is being shown. The "New File Type" wizard | |
created a <tt>DataObject</tt> for our file type, so let's now use it | |
to parse the underlying file and expose its content as new nodes | |
in the explorer views, e.g., the Projects window, Files window, | |
and the Favorites window.</p> | |
<p class="tips">For background to this section and | |
complete details on support for nodes | |
on the NetBeans Platform, see <a href="https://platform.netbeans.org/tutorials/nbm-nodesapi2.html">NetBeans Nodes API Tutorial</a>.</p> | |
<div class="indent"> | |
<ol> | |
<li>Open the <tt>AbcDataObject</tt> class and add this method: | |
<pre class="examplecode">@Override | |
protected Node createNodeDelegate() { | |
return new DataNode(this, Children.LEAF, getLookup()); | |
}</pre> | |
<p>The method above provides a default Node for the underlying file. The default | |
Node has no child nodes, which is evident by the "Children.LEAF" parameter | |
that you see above.</p> | |
<p>Instead of passing in "Children.LEAF", let's now use the <tt>ChildFactory</tt> | |
class to create new child nodes of our Node class:</p> | |
<pre class="examplecode">@Override | |
protected Node createNodeDelegate() { | |
return new DataNode( | |
this, | |
<b>Children.create(new AbcChildFactory(this), true),</b> | |
getLookup()); | |
}</pre> | |
</li> | |
<li>Define the <tt>ChildFactory</tt> as an inner class, as follows: | |
<pre class="examplecode">private static class AbcChildFactory extends ChildFactory<String> { | |
private final AbcDataObject dObj; | |
public AbcChildFactory(AbcDataObject dObj) { | |
this.dObj = dObj; | |
} | |
@Override | |
protected boolean createKeys(List list) { | |
FileObject fObj = dObj.getPrimaryFile(); | |
try { | |
List<String> dObjContent = fObj.asLines(); | |
list.addAll(dObjContent); | |
} catch (IOException ex) { | |
Exceptions.printStackTrace(ex); | |
} | |
return true; | |
} | |
@Override | |
protected Node createNodeForKey(String key) { | |
Node childNode = new AbstractNode(Children.LEAF); | |
childNode.setDisplayName(key); | |
return childNode; | |
} | |
}</pre></li> | |
<li>In your module sources, open <tt>AbcTemplate.abc</tt> and enter the following text, or something like it, | |
i.e., add several lines of text to your template file: | |
<pre class="examplecode">hello | |
world | |
how are things | |
today</pre></li> | |
<li><p>Run the module again, create an Abc file from | |
the template again, and then notice that you can expand the generated file:</p> | |
<br/> | |
<p><img src="../images/tutorials/filetype/72/new-action-6.png" alt="Parse"/></p> | |
</li> | |
</ol> | |
</div> | |
<!-- ======================================================================================= --> | |
<h3 class="tutorial"><a name="properties"></a>Extending the Properties Window</h3> | |
<p>Our Node now has child Nodes. In this section, we also assign properties to our Node. | |
The properties are displayed in the Properties window.</p> | |
<p class="tips">For background to this section and | |
complete details on support for properties | |
on the NetBeans Platform, see <a href="https://platform.netbeans.org/tutorials/nbm-property-editors.html">NetBeans Property Editor Tutorial</a>.</p> | |
<p>By default, the following properties are shown in the Properties window | |
for our new file:</p> | |
<p><img src="../images/tutorials/filetype/72/new-action-9.png" alt="Parse"/></p> | |
<p>We will now change the default properties to show a custom property instead.</p> | |
<div class="indent"> | |
<ol> | |
<li>Open the <tt>AbcDataObject</tt> class and change the <tt>createNodeDelegate</tt> | |
method so that our own <tt>AbcNode</tt> will be created instead | |
of the generic <tt>DataNode</tt>: | |
<pre class="examplecode">@Override | |
protected Node createNodeDelegate() { | |
return new <b>AbcNode</b>( | |
this, | |
Children.create(new AbcChildFactory(this), true), | |
getLookup()); | |
}</pre> | |
<p>The <tt>AbcNode</tt> does not exist yet, you will create it in the | |
next step.</p></li> | |
<li>Define the <tt>AbcNode</tt> as an inner class, as follows: | |
<pre class="examplecode">class AbcNode extends DataNode { | |
public AbcNode(AbcDataObject aThis, Children kids, Lookup lookup) { | |
super(aThis, kids, lookup); | |
} | |
@Override | |
protected Sheet createSheet() { | |
Sheet sheet = super.createSheet(); | |
Sheet.Set set = Sheet.createPropertiesSet(); | |
sheet.put(set); | |
set.put(new LineCountProperty(this)); | |
return sheet; | |
} | |
private class LineCountProperty extends ReadOnly<Integer> { | |
private final AbcNode node; | |
public LineCountProperty(AbcNode node) { | |
super("lineCount", Integer.class, "Line Count", "Number of Lines"); | |
this.node = node; | |
} | |
@Override | |
public Integer getValue() throws IllegalAccessException, InvocationTargetException { | |
int lineCount = 0; | |
DataObject abcDobj = node.getDataObject(); | |
FileObject abcFo = abcDobj.getPrimaryFile(); | |
try { | |
lineCount = abcFo.asLines().size(); | |
} catch (IOException ex) { | |
Exceptions.printStackTrace(ex); | |
} | |
return lineCount; | |
} | |
} | |
}</pre></li> | |
<li><p>Run the module again, open the Properties window, and notice | |
your property is displayed:</p> | |
<p><img src="../images/tutorials/filetype/72/new-action-7.png" alt="Parse"/></p> | |
</li> | |
</ol> | |
</div> | |
<!-- ======================================================================================= --> | |
<h3 class="tutorial"><a name="synchronized"></a>Creating Synchronized Views</h3> | |
<p>Let's now illustrate via a small example how the various views can be synchronized.</p> | |
<p class="tips">For background to this section and | |
complete details on the Visual Library | |
in the NetBeans Platform, see "NetBeans APIs for Visualizing Data" | |
in the <a href="https://netbeans.org/kb/trails/platform.html">NetBeans Platform Learning Trail</a>, especially | |
the <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-api-visual/org/netbeans/api/visual/widget/doc-files/documentation.html">official Visual Library documentation</a>.</p> | |
<div class="indent"> | |
<ol> | |
<li>Right-click the Libraries node, choose Add Module Dependency, | |
and add a dependency on the Visual Library API.</li> | |
<li>Create a new Java class named "AbcVisualElementPanel".</li> | |
<li>Define the class as follows: | |
<pre class="examplecode">package org.myorg.abcfiletype; | |
import java.awt.BorderLayout; | |
import java.awt.Point; | |
import java.util.List; | |
import javax.swing.JPanel; | |
import org.netbeans.api.visual.action.ActionFactory; | |
import org.netbeans.api.visual.widget.LabelWidget; | |
import org.netbeans.api.visual.widget.LayerWidget; | |
import org.netbeans.api.visual.widget.Scene; | |
import org.openide.filesystems.FileChangeAdapter; | |
import org.openide.filesystems.FileEvent; | |
public class AbcVisualElementPanel extends JPanel { | |
public AbcVisualElementPanel(final AbcDataObject dobj) { | |
setLayout(new BorderLayout()); | |
final Scene scene = new Scene(); | |
final LayerWidget layer = new LayerWidget(scene); | |
refresh(scene, layer, dobj); | |
dobj.getPrimaryFile().addFileChangeListener(new FileChangeAdapter() { | |
@Override | |
public void fileChanged(FileEvent fe) { | |
layer.removeChildren(); | |
refresh(scene, layer, dobj); | |
scene.validate(); | |
} | |
}); | |
scene.addChild(layer); | |
add(scene.createView(), BorderLayout.CENTER); | |
} | |
private void refresh(Scene scene, LayerWidget layer, AbcDataObject dobj) { | |
try { | |
List<String> lines = dobj.getPrimaryFile().asLines(); | |
for (int i = 0; i < lines.size(); i++) { | |
String line = lines.get(i); | |
LabelWidget widget = new LabelWidget(scene, line); | |
widget.getActions().addAction(ActionFactory.createMoveAction()); | |
widget.setPreferredLocation(new Point(20, 90 * i)); | |
layer.addChild(widget); | |
} | |
} catch (Exception e) { | |
} | |
} | |
}</pre></li> | |
<li><p>In "AbcVisualElement", return the <tt>JPanel</tt> created | |
above, as follows:</p> | |
<pre class="java"> | |
@Override | |
public JComponent getVisualRepresentation() { | |
return new AbcVisualElementPanel(obj); | |
}</pre> | |
</li> | |
<li><p>Run the module again and notice that the first tab is synchronized | |
with the second tab:</p> | |
<p><img style="border: 1px solid #0e1b55" src="../images/tutorials/filetype/72/new-action-8.png" alt="Parse"/></p> | |
<p class="tips">Make a change in the source view, save the change, switch to this visual view, and notice | |
that the visual view reflects the changed source view.</p> | |
</li> | |
</ol> | |
</div> | |
</div> | |
<!-- ======================================================================================= --> | |
<p></p> | |
<div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&subject=Feedback:%20File%20Type%208.0%20Tutorial">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://platform.netbeans.org/index.html">NetBeans Platform Homepage</a></li> | |
<li><a href="https://netbeans.org/download/dev/javadoc/">NetBeans API List (Current Development Version)</a></li> | |
<li><a href="https://netbeans.org/kb/trails/platform.html">Other Related Tutorials</a></li></ul> | |
<!-- ======================================================================================== --> | |
<!-- | |
<h2><a name="version"></a>Versioning </h2> | |
<p> | |
<table width="76%" > | |
<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> | |
</tr> | |
<tr> | |
<td> | |
1 | |
</td> | |
<td> | |
25 August 2005 | |
</td> | |
<td> | |
<ul><li>Initial version. | |
<li>To do: | |
<ul><li>Add post-creation customizations (i.e., the "Extending Support for the New File Type" section). | |
<li>Explain what the generated files are for (placeholders currently). | |
<li>Explain the layer file's entries. | |
<li>Explain the first File Type panel (placeholders currently). | |
<li>Maybe create a separate tutorial for recognizing XML files.</ul></ul> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
2 | |
</td> | |
<td> | |
23 September 2005 | |
</td> | |
<td> | |
<ul><li>A lot of info added from the FAQ and added the Action wizard and System Filesystem Browser. | |
<li>To do: | |
<ul><li>Explain <tt>LoaderBeanInfo.java</tt> and <tt>Resolver.xml</tt> (one line each) | |
<li>Maybe create a separate tutorial for recognizing XML files. | |
<li>Using Tomcat GIF maybe not good idea. | |
<li>Maybe the action should do something useful. | |
<li>Maybe direct links to FAQ not good idea. | |
<li>Probably more needed on <tt>layer.xml</tt> file. | |
<li>Maybe other useful apisupport functionality could be added to this scenario. | |
<li>More info needed on MIME types. | |
<li>The introductory paragraphs should be illustrated with a graphic. A diagram to | |
show relationship between node, dataobject, fileobject, dataloader, etc.</ul></ul> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
3 | |
</td> | |
<td> | |
28 September 2005 | |
</td> | |
<td> | |
<ul><li>Integrated comments from Jesse Glick. | |
<li>To do: | |
<ul> <li>More info needed on MIME types. | |
<li>The introductory paragraphs should be illustrated with a graphic. A diagram to | |
show relationship between node, dataobject, fileobject, dataloader, etc. | |
<li>Many Javadoc links to be added (also for <tt>performAction</tt>. | |
<li>Info on cookies, cookie actions, cookie classes needed. | |
<li>Action ended up in text-html even though I chose my own mime type. | |
<li>Need to explain or link to explanation for instance, shadow, etc. | |
<li>Platform Manager needs to be mentioned in the context of installing | |
in target platform. | |
<li>Show how to add properties to the property sheet.</ul></ul> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
4 | |
</td> | |
<td> | |
4 October 2005 | |
</td> | |
<td> | |
<ul><li>Added two diagrams in the introductory paragraphs, from Tim Boudreau's JavaOne presentation. | |
<li>To do: | |
<ul> <li>More info needed on MIME types. | |
<li>Many Javadoc links to be added (also for <tt>performAction</tt>). | |
<li>Need to create section near the start: "Related FAQs": | |
<ul><li>Info on cookies, cookie actions, cookie classes needed. | |
<li>Need to explain or link to explanation for instance, shadow, etc. | |
<li>DataLoader, DataObject, etc.</ul> | |
<li>Platform Manager needs to be mentioned in the context of installing | |
in target platform. | |
<li>Show how to add properties to the property sheet. | |
<li>Mention the dummy template that you get, how to modify it, | |
and how to set the description in the New File wizard.</ul></ul> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
4 | |
</td> | |
<td> | |
4 November 2005 | |
</td> | |
<td> | |
<ul><li>Added downloadable source code, new 'Installing the Sample' section, and link to | |
Syntax Highlighting tutorial at the end. | |
<li>To do: | |
<ul> <li>Same items as on 4 October still to be done.</ul> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
5 | |
</td> | |
<td> | |
29 November 2005 | |
</td> | |
<td> | |
<ul><li>Added links to brand new Component Palette tutorial. | |
<li>To do: | |
<ul> <li>Same items as on 4 October still to be done.</ul> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
6 | |
</td> | |
<td> | |
21 April 2006 | |
</td> | |
<td> | |
<ul><li>Changed the title from "DataLoader Module Tutorial" to "Recognizing a File Type Tutorial". | |
<li>To do: | |
<ul> <li>Same items as on 4 October still to be done.</ul> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
7 | |
</td> | |
<td> | |
17 November 2007 | |
</td> | |
<td> | |
<ul><li>Updated the whole tutorial to 6.0, replaced all screenshots, and | |
now [because the 6.0 IDE already provides support for manifest files], the | |
tutorial focuses on imaginary Abc files. | |
<li>To do: | |
<ul> <li>Need to replace the download, which is the same as before, dealing with manifest files. | |
<li>Same items as on 4 October still to be done. | |
<li>Added OpenSupport into TopComponent, with a reference to Visual Library.</ul> | |
<li>Changed title to File Type Integration Tutorial | |
<li>Tweaked several places throughout tutorial, for 6.0 | |
</td> | |
</tr> | |
<tr> | |
<td> | |
8 | |
</td> | |
<td> | |
15 April 2008 | |
</td> | |
<td> | |
Updated the styles (badge, table of contents, required software table) | |
to the new format. | |
</td> | |
</tr> | |
<tr> | |
<td> | |
9 | |
</td> | |
<td> | |
16 July 2008 | |
</td> | |
<td> | |
Created new version for 6.5, because of changes to the | |
way file type recognition is done in that release. To do: | |
<ul> | |
<li>6.5-specific badge | |
<li>Required software table | |
<li>Search for DataNode, BeanInfo, DataLoader and reword | |
<li>Check screenshots | |
<li>Make sure all the sections work as before | |
</ul> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
10 | |
</td> | |
<td> | |
4 April 2009 | |
</td> | |
<td> | |
Worked through everything and added the multiview section. | |
</td> | |
</tr> | |
<tr> | |
<td> | |
11 | |
</td> | |
<td> | |
9 Feb 2010 | |
</td> | |
<td> | |
Changed JPanel to TopComponent in multiview section. | |
</td> | |
</tr> | |
<tr> | |
<td> | |
12 | |
</td> | |
<td> | |
10 Feb 2010 | |
</td> | |
<td> | |
Added links to javadoc for the MultiView classes. | |
</td> | |
</tr> | |
<tr> | |
<td> | |
13 | |
</td> | |
<td> | |
18 Feb 2010 | |
</td> | |
<td> | |
Added style for borders and fixed action instructions. | |
</td> | |
</tr> | |
<tr> | |
<td> | |
14 | |
</td> | |
<td> | |
20 November 2010 | |
</td> | |
<td> | |
Going through everything for 6.9, updating, changing screenshots everywhere, Nimbus. | |
Added the "Parsing the File" section, need to add Javadoc links and explanations. | |
Added the "Extending the Properties Window" section, need to add Javadoc links and explanations. | |
</td> | |
</tr> | |
<tr> | |
<td> | |
15 | |
</td> | |
<td> | |
20 October 2011 | |
</td> | |
<td> | |
Going through everything for 7.1, updating, changing screenshots everywhere. | |
Need to update MultiView section for 7.1. | |
</td> | |
</tr> | |
<tr> | |
<td> | |
16 | |
</td> | |
<td> | |
5 July 2012 | |
</td> | |
<td> | |
Updated everything for 7.2. No dot is accepted in front of file extensions anymore. | |
</td> | |
</tr> | |
<tr> | |
<td> | |
17 | |
</td> | |
<td> | |
13 August 2012 | |
</td> | |
<td> | |
Added link to Visual Library documentation. | |
</td> | |
</tr> | |
<tr> | |
<td> | |
17 | |
</td> | |
<td> | |
30 June 2014 | |
</td> | |
<td> | |
Updating for 8.0. | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
--> | |
</body> | |
</html> |