What is a DataObject?
DataObjects wrap FileObjects. (If you do not want to visualize files on disk in an explorer view or create a text editor [with syntax coloring, etc] for files, then you will never need to touch DataObjects.) A FileObject is just a container
for data; it happens to have a MIME type, but like java.io.File
, it doesn’t know or care what kind
of file it represents, or what data it contains. DataObject is part of the Loaders API - a good overview of this API can be found here.
A DataObject represents one or more (typically only one) FileObjects. A DataObject knows what kind of a file it represents. It may represent the parsed contents of a file such as a .java
file. Or,
as in the case of InstanceDataObject, the file name may have semantic meaning. For example, a file with the name org-netbeans-modules-speech-SpeakAction.instance
literally is an instruction to "Load the class org.netbeans.modules.speech.SpeakAction
, and create an instance of it using its default (no argument) constructor" (this technique is commonly used in the system filesystem to register Java objects installed by modules - more about that here).
DataObjects are produced by DataLoaders, which modules register for specific file types. For each file type, there is (usually) one DataLoader. For each file of that type, there is one DataObject.
DataObjects are seldom referred to by Java subclass. If you are casting a DataObject to its implementation class, you are probably doing something wrong. This is a general rule for which there can be exceptions, but is especially true if you’re doing the cast from code in a different module than the one in which the DataObject was defined. Instead, the usage pattern is to ask a DataObject for instances of interfaces that are the things your code will actually interact with, by calling DataObject.getLookup().lookup(SomeType.class)
(more about Lookup).
As a simple example, the NetBeans APIs define an interface org.netbeans.api.actions.Openable
. It has
one method, open()
. That method will open the file in the editor.
What exactly will happen when open()
is called is entirely up to the module that implements the DataObject and Openable. The rest of the system does not need to know any of the implementation details - it just needs to know if the DataObject has an Openable. If it does, then the Open action on its context menu can be enabled, and that action will call
theDataObject.getLookup().lookup(Openable.class).open()
.
As suggested above, a DataObject may actually represent more than one file - so when you expand a folder
in the UI, there may actually be fewer DataObjects in that folder than there are files. This is why, in the
NetBeans IDE, a Swing form is represented by a .java
file and a corresponding .form
file, but the .form
file is not visible in the UI. .properties
files have also used
this mechanism to present multiple resource bundles in diverse languages as a single node in the files tree.
However, this ability to represent multiple files with a single DataObject is strongly discouraged for new code and will probably eventually be deprecated - it has serious negative implications for scalability.