<!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>Introduction to the NetBeans APIs</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="author" content="gwielenga@netbeans.org"> | |
<meta name="indexed" content="y"> | |
<meta name="description" | |
content="A short guide to creating, installing, modifying, and reloading a simple NetBeans Plug-in Module."> | |
<!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. --> | |
<!-- Use is subject to license terms.--> | |
</head> | |
<body> | |
<h1>Introduction to the NetBeans APIs</h1> | |
<p><small><a href="mailto:nbdocs_feedback@usersguide.netbeans.org?subject=Feedback:%20NetBeans%20IDE%20Introduction%20to%20NetBeans%20APIs">Feedback</a></small></p> | |
<p>API stands for "Application Programming Interface". | |
The word "interface" indicates that the API lives between at least two different subjects. | |
For example, the internal structure of the application could be seen on one side, while the foreign applications that make | |
calls into it are found on the other. Or there is the programmer (or team) developing the application and its API on one side and | |
on the other side are the the programmers using it. The important observation is that in both cases these two sides are | |
<i>separated</i> - either compiled separately or developed in completely different groups with their own schedules, goals and needs. | |
<p>An API is everything that another team or application can depend on: | |
<ul> | |
<p><li><b>Method and field signatures.</b> Communication between applications | |
is usually about calling functions and passing data structures between | |
each other. If there is a change in the names of the methods, in their | |
arguments or in structure of exchanged data, the whole program often | |
does not even link well, nor it can run. | |
<p><li><b>Files and their content.</b> Many applications read various files | |
and their content can influence their behaviour. Imagine one application | |
relying on another to read its configuration file and modifying | |
its content prior to invoking the application. If the format of the file | |
changes or the file is completely ignored, the communication between | |
those applications gets broken. | |
<p><li><b>Environment variables.</b> For example, the behavior of CVS | |
can be influenced by the variable <tt>CVSEDITOR</tt>. | |
<p><li><b>Protocols.</b> Opening a socket and being prepared to interpret | |
streams sent there, or putting or reading a data to clipboard or during | |
drag and drop again, establishes an API that others can depend on. | |
<p><li><b>Behavior.</b> What the program flow | |
looks like - what is the order of execution, what locks are being held | |
during calls, in which threads a call can happen, etc. | |
<p><li><b>L10N messages.</b> Because the localization to a certain language is usually developed and | |
distributed by somebody other than the person that writes the code, yet both of | |
them have to use the same keys (<tt>NbBundle.getMessage | |
("CTL_SomeKey")</tt>), there is inherently a contract between | |
the writer of the code and the translator - an API of sorts.</ul> | |
<p> | |
<p>This document provides an overview of the NetBeans APIs, together with related resources | |
that you can use to get to know them better. | |
<h2 class="tutorial">Actions API</h2> | |
<p>This API is a standard representation of the actions a user can invoke. It provides | |
an interface to such IDE elements as toolbars, menus, and keyboard shortcuts - | |
allowing third parties to create actions that are sensitive to context and invocable in | |
more than one way. Special superclasses are sensitive to selected nodes and cookie | |
sets - the module author decides if these apply. The Actions API offers the ability to | |
write the action once, and have it automatically apply as appropriate. For example, a | |
user action might show up in both a toolbar, and be selected by a keyboard shortcut, | |
all from the same implementation. | |
<p>All actions in the IDE are subclasses of SystemAction, which extends the Swing | |
action API to interact smoothly with the IDE. The Actions API provides abilities | |
such as context sensitivity, callback support, automatic presentation devices in | |
menus and toolbars, and a few other features used by the IDE. | |
<p>Actions are typically presented in popup menus, or attached to a component such as | |
a window, node, or data object. | |
<p> | |
<br /> | |
<h2 class="tutorial">DataSystems API</h2> | |
<p>Developers use this API primarily to cause the IDE to recognize new data types, | |
such as UML model files, add user-visible actions to nodes representing a custom | |
or standard type, implement templates, and so on. Data objects may also represent | |
logical groupings of physical files where appropriate. <tt>org.openide.loaders</tt> | |
associates files together into groups and assigns types to data, creates data | |
objects from files, and defines how cookies attach behavior to these objects. | |
<tt>org.openide.cookies</tt> provides a design pattern for attachable behaviors | |
for data objects and nodes. | |
<p>The loader mechanism is responsible for scanning files in a directory on disk, | |
ignoring files irrelevant to the IDE, and grouping the rest into logical chunks. The | |
loaders also determine what type of data each file represents. This scanning is | |
performed by asking each registered data loader whether or not the given file(s) | |
should be handled. The first loader to recognize a file takes ownership of it, and | |
creates a matching data object to represent it to the rest of the IDE. | |
<p>Loaders are used in the IDE to group associated files together into a data object. | |
Within the IDE, a data object is represented by a single node, and has a single set | |
of actions applicable to it. Unlike a bare file object, a data object holds a number | |
of behaviors. For example, it can hold cookies providing various behaviors, have | |
an associated opened editor, be specified as a template, and may provide special | |
procedures to be run when it is moved or renamed. | |
<div class="indent"> | |
<h3 class="tutorial">MultiFileLoaders and UniFileLoaders</h3> | |
<p>Multifile loaders are able to recognize multiple files at once and create a data object | |
from them. All data objects have a primary file that is representative of the data | |
object and is often used to identify it. As well, these multifile loaders may have | |
any number of secondary files. The basic mechanism used is that the loader pool | |
will pass file objects to it in an arbitrary order; the loader may get a primary or | |
secondary file first. Either way, it must recognize that it belongs to a cluster; find | |
the primary file if it got a secondary one; and create a new <tt>MultiDataObject</tt> | |
containing the supplied file as an entry. When other files in the cluster are passed to | |
the loader, it must create new entries in the same multidata object, to indicate their | |
association. | |
<p>Of course, a single-file loader is simpler, and is likely to be more commonly | |
used since the majority of file types make sense by themselves. The default | |
implementation simplifies the creation of a subclass that recognizes only certain file | |
extensions. Note that the standard UniFileLoader is actually a special type of | |
MultiFileLoader in that it recognizes only one file. UniFileLoader actually | |
creates a MultiDataObject when it recognizes its file. Normally the | |
UniFileLoader is used for most purposes, and the behaviors in | |
MultiDataObject are generally available as defaults. | |
<h3 class="tutorial">Cookies</h3> | |
<p>A cookie is a design pattern that separates the presentation of implementation of | |
some interface from the actual object that implementation ought to be associated | |
with. It is a convenient way of removing the requirement that all interfaces | |
presented by the cookie holder - usually a data object or node - must be | |
actually implemented by the Java class of the object. | |
<p>When cookies are attached to a data object, they define what properties and | |
behaviors are available. For example, if a data object is editable, attaching an editor | |
cookie defines editable actions. EditorCookie deals only with opening the | |
contents of a file as text within the window. Cutting and copying text within the | |
window is a function of the editor, as opened by the editor cookie. Note that the | |
more general OpenCookie could be added to a file to open something else, such | |
as a thumbnail (as is done in the standard IDE for image files). | |
<p>For purposes of marking a cookie as such, the cookie interface (or an abstract class) | |
should extend <tt>Node.Cookie</tt>. Other than that, there are no requirements as to what | |
makes a valid cookie. Typically a cookie provides a small set of abstract operations, | |
such as "opening", "compiling", "searching" and so on. Using cookie sets, it | |
is convenient to dynamically add and remove cookies from a holder. This is | |
appropriate for holders of cookie types whose applicability may vary over time. | |
<h3 class="tutorial">Cookie Supports</h3> | |
<p>While it is possible for any data object or node to offer ad hoc support for any given | |
cookie if it has a special way of doing so, more commonly there is a standard way | |
(or set of ways) that a particular cookie is likely to be implemented. It is the primary | |
job of the holders to declare that they want to use a cookie. In this case, the standard | |
implementing class is called a support, and typically its constructor will provide an | |
association to the holder in some fashion. The support itself will determine what to | |
do with the holder object when invoked. | |
<p>This is why the IDE has supports - implementations of cookies - that provide the | |
IDEs standard way of handling something and which anyone is free to reuse. For | |
example, the editor cookie has the corresponding support "editor support." The | |
editor cookie says this document can be opened, this object can produce a document, | |
and so on. The concrete class <tt>EditorSupport</tt> actually deals with the details of | |
telling what is modified when it should be saved, loading the object from disk, etc. | |
<tt>EditorSupport</tt> is physically contained in the Editor API. Most of the others are | |
contained in the DataSystems API under <tt>org.openide.loaders</tt>. | |
<p>OpenSupport is another important support. It is an implementation of OpenCookie, and provides some of the | |
infrastructure necessary to open the object in a window. EditorSupport extends | |
this. The editor support is a special case that handles opening a text file. In most | |
other cases, for example when providing an image editor, the module author | |
would directly extend OpenSupport. It provides some of the required functions | |
needed, such as handling the opening of a file, cloning the resulting window, and | |
so on. This is an abstract class - some details need to be implemented by the | |
module author. For example, how to actually paint the pane that is going to be | |
opened. | |
<p>Supports and cookies typically are paired off in this manner. The outer API uses | |
cookies in a high-level, nonspecific way, while the inner API (which is comprised of | |
the supports) is a concrete, useful implementation. If the support does what is needs, | |
extra code is not required. If the supports do not know what is needed, the cookie | |
may be implemented any way that obtains the desired control. | |
<p>Most of the standard cookies exist in the org.openide.cookies package. Many of | |
these have standard supports as well, frequently in org.openide.loaders. Using | |
the Javadoc, the most efficient way to find cookies and supports is to look at | |
Node.Cookie and browse the subinterfaces for implementing classes, which | |
are usually supports. | |
<h3 class="tutorial">Transferables</h3> | |
<p>org.openide.util.datatransfer is often grouped in the DataSystems API. | |
This class is an extension of things that are already in the core Java platform API. | |
The basic system of Java data transfer offers cut, copy, paste, drag-and-drop, | |
clipboards - everything typically used in authoring modules and applications. | |
<p>Extended transferables contain many classes. One special edition makes it easy to | |
support different types of data flavors at once. A data flavor is defined by the Java | |
specification as a type of data that can be can transferred - a string of text, file, or | |
image. Also, there is a provision for transferring a cluster of objects such as multiple | |
strings of text at once. An automatic clipboard converter, installed only by the | |
manifest, converts one flavor to another. It acts as a middleman between the thing | |
that is producing the data and the thing that is using it. Cutting, copying, pasting, | |
and dragging nodes between two parent nodes is supported. The module author can | |
cut a node in the Explorer, select another node that can accept children, and paste. | |
Both the source and the target may arbitrarily add extra behavior by this operation. | |
<p>Copying and pasting with the IDE is very configurable and flexible. It is not | |
necessary that both sides actually be nodes - if you write a node, you can enable | |
copying it as a text string. For example, if there is a RMI connection in the RMI | |
module, selecting that node in the runtime tab, copying, moving to the Editor and | |
selecting paste, will insert the code to re-create the connection in an application. This | |
process is bi-directional. To produce a new child node, text can be selected from | |
within the editor and pasted onto a node, though it is up to the developer to create | |
the appropriate working code for this. | |
</ol> | |
</div> | |
<br /> | |
<h2 class="tutorial">FileSystems API</h2> | |
<p>This API represents an abstraction of the file system in the IDE. It is made up of | |
objects and classes that represent files, and is used to display files and directories. | |
It can also display the file entries contained in JAR and ZIP archives, and contains | |
full capabilities for version control support. | |
<p>The FileSystems API permits module authors to access files in a uniform manner. | |
For example, you may access a file and be unaware of whether a file you are using | |
is stored on local disk in the user's repository, in an auxiliary directory, or in a JAR | |
archive. Alternately, you may have reason to implement a custom file system. For | |
example, a vendor tool being integrated into the IDE may handle its own local or | |
remote storage of files in a special fashion; using this API, the rest of the IDE will | |
be able to seamlessly work with your files. | |
<p>The FileSystems API is used only to manipulate files on disk - or whatever storage | |
mechanism a file system may use - and makes no reference to the nature of their | |
contents nor how they are being used elsewhere in the IDE - beyond whether or | |
not they are locked. From the perspective of this API, all files consist of byte streams | |
(albeit with MIME types). | |
<p> | |
<br /> | |
<h2 class="tutorial">Nodes API</h2> | |
The Nodes API controls the usage and creation of nodes, which are a variant of | |
JavaBeans that may have adjustable property sets. The Nodes API also provides | |
cookies and actions. | |
The functionality in the Nodes API includes operations such as browsing of nodes; | |
cut, copy, paste, and reordering; display characteristics, both icon and available | |
properties; and actions that may be taken on the node, such as in a context menu. | |
A rich API deals with children of nodes, and access to changes of information is | |
provided. | |
Using the Nodes API: | |
<ul> | |
<p><li> | |
The icon for a node can be defined, including the display name, behavior on a | |
rename attempt, copy, drag, and so on. There is also a pop-up dialog customizer. | |
<p><li> | |
Properties may be displayed as shown in the property sheet. Every node can | |
define what properties to present.</ul> | |
Each data object can designate a single node to represent it. For example, a Java | |
source file node displays the source name and properties, as well as configured | |
items on the execution tab. The interaction of the node to the DataSystems API | |
is responsible for all these capabilities and representations. | |
Nodes are not static data - they are live components of the IDE. So actions taken | |
in one part of the system will frequently cause open Explorer views to refresh to | |
display the new node structure. For example, typing in a new method in a class, | |
after a moments delay to reparse, will cause a new method node to appear in the | |
tree for that class (if it was already expanded). | |
A node is an extension to the JavaBeans concept, adding some features that were | |
necessary for the full functioning of the IDE: | |
<ul><p><li>Full hierarchy support, including special support for various kinds of child | |
containment policies. | |
<p> <li>Actions and other IDE-specific interfaces are placed as direct Java technologylevel | |
API requirements - casts or introspection are not needed to determine their | |
availability. | |
<p><li>Certain basic operations on nodes, such as creating a serializable form of the | |
node, or cut-and-paste support, are implemented as an abstract base class. | |
Concrete subclasses then provide the easiest and most common implementations | |
of these operations.</ul> | |
</ol> | |
</div> | |
<br /> | |
</body> | |
</html> |