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