blob: d248815868422c09cbe762c1b9b16b6d130bf78c [file] [log] [blame]
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>How to use certain NetBeans APIs</title>
<link rel="stylesheet" href="netbeans.css" type="text/css">
<link REL="icon" href="http://www.netbeans.org/favicon.ico" type="image/ico">
<link REL="shortcut icon" href="http://www.netbeans.org/favicon.ico">
</head>
<body>
<center>
<h1>How to use certain NetBeans APIs</h1>
</center>
This page contains extracted usecases for some of the NetBeans modules
that <a href="overview-summary.html">offer an API</a>.
<hr>
<h2>
<a name="usecase-Ant">How to use </a><a href="overview-summary.html#def-api-Ant">Ant</a>?
</h2>
<description>
The Ant integration module recognizes Ant build scripts, facilitates
editing them as text or structurally, lets the user run targets or
create shortcuts to them, etc.
</description>
<p></p>
<p>
The principal use cases for the API are covered in the overall API architecture.
</p>
<hr>
<h2>
<a name="usecase-Common Annotations">How to use </a><a href="overview-summary.html#def-api-Common Annotations">Common Annotations</a>?
</h2>
<description>
Provides common annotations serving as a documentation element and for
static code analysis.
</description>
<p></p>
<h4>CheckReturnValue annotated method</h4>
<p>
When the method return value is important value to check (or the only effect
the method has) the method can be annotated with
<a href="org-netbeans-api-annotations-common/org/netbeans/api/annotations/common/CheckReturnValue.html" shape="rect">CheckReturnValue</a>.
Annotation servers as documentation as well as a hint for static code analysis.
</p>
<h4>CheckForNull annotated method</h4>
<p>
Method annotated with
<a href="org-netbeans-api-annotations-common/org/netbeans/api/annotations/common/CheckForNull.html" shape="rect">CheckForNull</a>
may return <code>null</code> value. Annotation servers as documentation
as well as a hint for static code analysis.
</p>
<h4>NonNull annotated element</h4>
<p>
When the field, parameter, local variable or return value of the method
must not be <code>null</code> the
<a href="org-netbeans-api-annotations-common/org/netbeans/api/annotations/common/NonNull.html" shape="rect">NonNull</a>
annotation can be used to clearly express this. It servers as documentation
as well as a hint for static code analysis.
</p>
<h4>NullAllowed annotated element</h4>
<p>
Field, parameter or local variable annotated with
<a href="org-netbeans-api-annotations-common/org/netbeans/api/annotations/common/NullAllowed.html" shape="rect">NullAllowed</a>
can contain <code>null</code> value so <code>null</code> check should
occur before any dereference. Annotation servers as documentation
as well as a hint for static code analysis.
</p>
<h4>NullUnknown annotated element</h4>
<p>
Annotation
<a href="org-netbeans-api-annotations-common/org/netbeans/api/annotations/common/NullUnknown.html" shape="rect">NullUnknown</a>
complementing other nullness annotations servers for cases where
the element may or may not be <code>null</code> under certain
<i>defined</i> circumstances (usage).
</p>
<h4>SuppressWarnings annotated element</h4>
<p>
When the analysis tool report false warning it is possible to use
<a href="org-netbeans-api-annotations-common/org/netbeans/api/annotations/common/SuppressWarnings.html" shape="rect">SuppressWarning</a>
annotation to suppress the warning.
</p>
<hr>
<h2>
<a name="usecase-Debugger Core API">How to use </a><a href="overview-summary.html#def-api-Debugger Core API">Debugger Core API</a>?
</h2>
<description>
The debuggercore/api module (Debugger Core API) allows to install different debugger implementation to one IDE.
It allows to share some common UI components.
</description>
<p></p>
<h2>UseCase I. - Install
and use CPP debugger plug-in to NetBeans + Java Debugger.</h2>
<span style="font-style: italic;">CPP debugger plug-in installs support
for debugging of some new language to the NetBeans IDE, and some new
debugging engine. This implementation of debugger should share UI
components (actions, Debugger Views, ...) with default NB Java
Debugger. It should share basic debugger model too - notion of current
context, current session, thread, call stack line, ...</span>
<br>
<br>
CPP debugger plug-in installs:<br>
<ul>
<li>New set of breakpoint types - CPPLineBreakpointType,
CPPMethodBreakpointType...
<ul>
<li>This set of breakpoint types will have special cathegory in Add
Breakpoint Dialog called "CPP". Each breakpoint type will install a new
JPanel to Add Breakpoint Dialog.</li>
<li>ToggleBreakpointAction on CPP files will create / remove a
instance of CPPLineBreakpointType.</li>
</ul>
</li>
<li>Install some watches evaluator for CPP language.</li>
<li>Some new View to Debugger Window</li>
<li>Use Termilnal Emulator in Output Window as command line interface
to CPP debugger plug-in.</li>
<li>Install / uninstall a columns to / from standard Debugger Window
Views.</li>
<li>Redefine Nodes used for representation of CPP threads, watches,
variables, callstacks, sessions and breakpoints
<ul>
<li>Add / remove some properties<br>
</li>
<li>Add / remove some actions</li>
<li>change icons</li>
<li>change display names</li>
</ul>
</li>
<li>Register CPP Actions for:
<ul>
<li>Step Into, Over, Out, Continue, Pause, Start, Kill, Restart,
Finish</li>
</ul>
</li>
<li>Some new CPP specific actions.</li>
</ul>
<br>
<h2>UseCase II. -
Install and use JSP debugger plug-in to NetBeans + Java Debugger.</h2>
<span style="font-style: italic;">JSP debugger plug-in installs support
for debugging of some new language to the NetBeans Java Debugger. It
does not contain a new debugger engine, but it delegates to standard NB
Java debugger. So it does not depends on Debugger Core API only, but it
depends on JavaDebugger API too.<br>
<br>
JSP debugger plug-in installs:<br>
</span>
<ul>
<li>New set of breakpoint types - JSPLineBreakpointType, ...
<ul>
<li>This set of breakpoint types will have special cathegory in Add
Breakpoint Dialog called "JSP". Each breakpoint type will install a new
JPanel to Add Breakpoint Dialog.</li>
<li>ToggleBreakpointAction on JSP files will create / remove a
instance of JSPLineBreakpointType.</li>
<li>JSPLineBreakpointType delegates all functionality to
JPDAClassBreakpoint and JPDALineBreakpoint<br>
</li>
</ul>
</li>
<li>Some watches evaluator for JSP language expression. This
evaluator delegates evaluation of Java expressions to standard
JavaExpressionEvaluator.<br>
</li>
<li>Redefine Nodes used for representation of JSP callstacks and
breakpoints
<ul>
<li>Add / remove some properties<br>
</li>
<li>Add / remove some actions</li>
<li>change icons</li>
<li>change display names</li>
</ul>
</li>
<li>Register JSP Actions for:
<ul>
<li>Step Into, Over, Out</li>
<li>Implementation of this actions delegates to standard Java Step
actions - it redefines Java stepping functionality.</li>
</ul>
</li>
<li>JSP debugger plug in adds support for new programming language
(JSP) to already running Java Session.<br>
</li>
</ul>
<br>
<h2>UseCase III. -
Install and use J2EE debugger plug-in to NetBeans + Java Debugger.</h2>
<span style="font-style: italic;">J2EE debugger plug-in installs some
enhancements to the standard Java Debugger. It
does not contain a new debugger engine or language support. So it does
not depends on Debugger Core API only, but it
depends on JavaDebugger API too.<br>
<br>
J2EE debugger plug-in installs:<br>
</span>
<ul>
<li>New set of breakpoint types</li>
<li>Filter for Threads and Callstack Views. This filter should allow
to:<br>
<ul>
<li>Add / remove / modify nodes in this views.</li>
</ul>
</li>
<li>Redefine Stepping (Smart Stepping) behaviour of default Java
Debugger.</li>
<li>Some new View to Debugger Window</li>
</ul>
<br>
<h2>UseCase IV. -
Install and use DBX debugger plug-in to NetBeans.</h2>
<span style="font-style: italic;">DBX debugger plug-in installs support
for debugging of some new language (CPP) to the NetBeans IDE, and some
new
debugging engine. But it contains debugger engine for Java debugging
too. DBX debugger engine has its own session management (or will have
in the next versions). One debugger engine can manage more than one
sessions. One engine supports debugging in more than one language.<br>
<br>
</span>
<h2>UseCase V. -
Implement Debugger Core UI module on top of Debugger Core API / SPI.</h2>
<span style="font-style: italic;">Debugger Core UI needs:<br>
</span>
<ul>
<li>List all breakpoint types and all breakpoint cathegories.</li>
<li>Visually customize all breakpoints - some panel.</li>
<li>Add / remove breakpoints.</li>
<li>Add / remove watches.<br>
</li>
<li>Represent breakpoints, threads, thread groups, watches, sessions,
call stack frames, locales, and fields as Nodes in NB Explorer View.</li>
<li>List all threads, thread groups, locales, watches, breakpoints,
callstack frames, and fields.</li>
<li>Listen on changes of hierarchy of threads, thread groups,
locales, watches, breakpoints, callstack frames, and fields.</li>
<li>Some current context definition. Current contet should define
current session, language, thread, and call stack line.</li>
</ul>
<br>
<hr>
<h2>
<a name="usecase-JPDA Debugger API">How to use </a><a href="overview-summary.html#def-api-JPDA Debugger API">JPDA Debugger API</a>?
</h2>
<description>
The debuggerjpda/api (Debugger JPDA API) defines API for NetBeans Java Debugger.
</description>
<p></p>
<h2>UseCase I. - Install
and use CPP debugger plug-in to NetBeans + Java Debugger.</h2>
<span style="font-style: italic;">CPP debugger plug-in installs support
for debugging of some new language to the NetBeans IDE, and some new
debugging engine. This implementation of debugger should share UI
components (actions, Debugger Views, ...) with default NB Java
Debugger. It should share basic debugger model too - notion of current
context, current session, thread, call stack line, ...</span>
<br>
<br>
CPP debugger plug-in installs:<br>
<ul>
<li>New set of breakpoint types - CPPLineBreakpointType,
CPPMethodBreakpointType...
<ul>
<li>This set of breakpoint types will have special cathegory in Add
Breakpoint Dialog called "CPP". Each breakpoint type will install a new
JPanel to Add Breakpoint Dialog.</li>
<li>ToggleBreakpointAction on CPP files will create / remove a
instance of CPPLineBreakpointType.</li>
</ul>
</li>
<li>Install some watches evaluator for CPP language.</li>
<li>Some new View to Debugger Window</li>
<li>Use Termilnal Emulator in Output Window as command line interface
to CPP debugger plug-in.</li>
<li>Install / uninstall a columns to / from standard Debugger Window
Views.</li>
<li>Redefine Nodes used for representation of CPP threads, watches,
variables, callstacks, sessions and breakpoints
<ul>
<li>Add / remove some properties<br>
</li>
<li>Add / remove some actions</li>
<li>change icons</li>
<li>change display names</li>
</ul>
</li>
<li>Register CPP Actions for:
<ul>
<li>Step Into, Over, Out, Continue, Pause, Start, Kill, Restart,
Finish</li>
</ul>
</li>
<li>Some new CPP specific actions.</li>
</ul>
<br>
<h2>UseCase II. -
Install and use JSP debugger plug-in to NetBeans + Java Debugger.</h2>
<span style="font-style: italic;">JSP debugger plug-in installs support
for debugging of some new language to the NetBeans Java Debugger. It
does not contain a new debugger engine, but it delegates to standard NB
Java debugger. So it does not depends on Debugger Core API only, but it
depends on JavaDebugger API too.<br>
<br>
JSP debugger plug-in installs:<br>
</span>
<ul>
<li>New set of breakpoint types - JSPLineBreakpointType, ...
<ul>
<li>This set of breakpoint types will have special cathegory in Add
Breakpoint Dialog called "JSP". Each breakpoint type will install a new
JPanel to Add Breakpoint Dialog.</li>
<li>ToggleBreakpointAction on JSP files will create / remove a
instance of JSPLineBreakpointType.</li>
<li>JSPLineBreakpointType delegates all functionality to
JPDAClassBreakpoint and JPDALineBreakpoint<br>
</li>
</ul>
</li>
<li>Some watches evaluator for JSP language expression. This
evaluator delegates evaluation of Java expressions to standard
JavaExpressionEvaluator.<br>
</li>
<li>Redefine Nodes used for representation of JSP callstacks and
breakpoints
<ul>
<li>Add / remove some properties<br>
</li>
<li>Add / remove some actions</li>
<li>change icons</li>
<li>change display names</li>
</ul>
</li>
<li>Register JSP Actions for:
<ul>
<li>Step Into, Over, Out</li>
<li>Implementation of this actions delegates to standard Java Step
actions - it redefines Java stepping functionality.</li>
</ul>
</li>
<li>JSP debugger plug in adds support for new programming language
(JSP) to already running Java Session.<br>
</li>
</ul>
<br>
<h2>UseCase III. -
Install and use J2EE debugger plug-in to NetBeans + Java Debugger.</h2>
<span style="font-style: italic;">J2EE debugger plug-in installs some
enhancements to the standard Java Debugger. It
does not contain a new debugger engine or language support. So it does
not depends on Debugger Core API only, but it
depends on JavaDebugger API too.<br>
<br>
J2EE debugger plug-in installs:<br>
</span>
<ul>
<li>New set of breakpoint types</li>
<li>Filter for Threads and Callstack Views. This filter should allow
to:<br>
<ul>
<li>Add / remove / modify nodes in this views.</li>
</ul>
</li>
<li>Redefine Stepping (Smart Stepping) behaviour of default Java
Debugger.</li>
<li>Some new View to Debugger Window</li>
</ul>
<br>
<h2>UseCase IV. -
Install and use DBX debugger plug-in to NetBeans.</h2>
<span style="font-style: italic;">DBX debugger plug-in installs support
for debugging of some new language (CPP) to the NetBeans IDE, and some
new
debugging engine. But it contains debugger engine for Java debugging
too. DBX debugger engine has its own session management (or will have
in the next versions). One debugger engine can manage more than one
sessions. One engine supports debugging in more than one language.<br>
<br>
</span>
<hr>
<h2>
<a name="usecase-HTML UI API">How to use </a><a href="overview-summary.html#def-api-HTML UI API">HTML UI API</a>?
</h2>
<description>
NetBeans Platform specific bindings over
standard HTML for Java API.
</description>
<p></p>
<p>
Primary purpose of this API is to allow smooth use of HTML based UI
in NetBeans Platform. To achieve that it provides specific annotatations
like <a href="org-netbeans-api-htmlui/org/netbeans/api/htmlui/OpenHTMLRegistration.html" shape="rect">@OpenHTMLRegistration</a>,
but otherwise it builds on the same usecases as the
<a href="http://bits.netbeans.org/html+java/" onclick="target='_blank'" shape="rect">HTML for Java</a> API.
</p>
<h4>Portable HTML based Window</h4>
<a name="use-window" shape="rect"></a>
Want to open a live HTML page as a
<a href="./org-openide-windows/org/openide/windows/TopComponent.html" shape="rect">
NetBeans window component</a>? Do you want
to use Java to control enabled/disabled state of various HTML elements?
Then have a look at
<a href="org-netbeans-api-htmlui/org/netbeans/api/htmlui/OpenHTMLRegistration.html" shape="rect">@OpenHTMLRegistration</a>
annotation.
<h4>Portable HTML based Dialog</h4>
<a name="use-dialog" shape="rect"></a>
Want to open a modal dialog filled with an HTML page and block until user
makes his choice?
Then have a look at
<a href="org-netbeans-api-htmlui/org/netbeans/api/htmlui/HTMLDialog.html" shape="rect">@HTMLDialog</a>
annotation.
<h4>Embedding an HTML UI Component</h4>
Are you satisfied with your HTML UI as used in
<a href="org-netbeans-api-htmlui/architecture-summary.html#use-window" shape="rect">windows</a> and
<a href="org-netbeans-api-htmlui/architecture-summary.html#use-dialog" shape="rect">dialogs</a>, but you'd like to use it
at a different part of the overall NetBeans UI? Then check
<a href="org-netbeans-api-htmlui/org/netbeans/api/htmlui/HTMLComponent.html" shape="rect">@HTMLComponent</a>
annotation.
<h4>HTML and Java Wizard</h4>
It is possible to use this technology to
create a wizard. See
<a href="./org-netbeans-api-templates/overview-summary.html#html-and-java" shape="rect">
HTML and Java Wizard
</a> howto.
<hr>
<h2>
<a name="usecase-Intent API">How to use </a><a href="overview-summary.html#def-api-Intent API">Intent API</a>?
</h2>
<description>
This module provides a contract between API clients that can express
some intention to invoke an operation and SPI providers that can
handle that intention.
This is useful in client-server environments, where the intention
can be constructed on server-side, but handled on client-side. The
objects that describe the intention should be easy to construct,
transfer and interpret.
</description>
<p></p>
<h4>Create an Intent, execute it and wait for result</h4>
<pre xml:space="preserve">
Future&lt;Object&gt; result = new <a href="org-netbeans-api-intent/org/netbeans/api/intent/Intent.html" shape="rect">Intent</a>(Intent.ACTION_VIEW, new URI("scheme://path/")).execute();
Object value = result.get();
</pre>
<h4>Create an Intent and execute it with callback</h4>
<pre xml:space="preserve">
new <a href="org-netbeans-api-intent/org/netbeans/api/intent/Intent.html" shape="rect">Intent</a>(Intent.ACTION_VIEW, new URI("scheme://path/")).execute(new <a href="org-netbeans-api-intent/org/netbeans/api/intent/Callback.html" shape="rect">Callback</a>() {
void success(Object result) {
// use the result somehow
}
void failure(Exception exception) {
// report the failure somehow
}
});
</pre>
<h4>Handle some Intent</h4>
<pre xml:space="preserve">
&nbsp;@<a href="org-netbeans-api-intent/org/netbeans/spi/intent/IntentHandlerRegistration.html" shape="rect">IntentHandlerRegistration</a>(
displayName = "Show my item in MyEditor",
position = 800,
uriPattern = "myscheme://.*",
actions = {Intent.ACTION_VIEW, Intent.ACTION_EDIT}
)
public static Object handleIntent(<a href="org-netbeans-api-intent/org/netbeans/api/intent/Intent.html" shape="rect">Intent</a> intent) {
SomeType result = parseAndPerformIntentSomehow(intent);
return result;
}
</pre>
<h4>Handle some Intent using Result object</h4>
<pre xml:space="preserve">
&nbsp;@<a href="org-netbeans-api-intent/org/netbeans/spi/intent/IntentHandlerRegistration.html" shape="rect">IntentHandlerRegistration</a>(
displayName = "Show my item in MyEditor",
position = 800,
uriPattern = "myscheme://.*",
actions = "*"
)
public static void handleIntent(final <a href="org-netbeans-api-intent/org/netbeans/api/intent/Intent.html" shape="rect">Intent</a> intent, final <a href="org-netbeans-api-intent/org/netbeans/spi/intent/Result.html" shape="rect">Result</a> result) {
// Move the execution to another thread. Do not wait for the result
// here, just pass the result object.
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Object result = doSomethingInEDT(intent);
result.setResult(e);
} catch (Exception e) {
result.setException(e);
}
}
});
}
</pre>
<hr>
<h2>
<a name="usecase-I/O API and SPI">How to use </a><a href="overview-summary.html#def-api-I/O API and SPI">I/O API and SPI</a>?
</h2>
<description>
The Input/Output API and SPI is a small module
which contains InputOutput and related interfaces used in
driving the Output Window.
The normal implementation is org.netbeans.core.output2.
</description>
<p></p>
<h4>Print a simple output to a new output tab</h4>
<p>
The basic use-case is printing a simple text, e.g. text output of an application,
into a dedicated pane in the UI, e.g. a tab in Output Window in the IDE.
</p>
<pre xml:space="preserve">
InputOutput io = InputOutput.get("UseCase1", true);
io.getOut().println("This is a simple output");
io.getOut().close();
</pre>
<h4>Print a line with hyperlink for invocation of arbitrary code</h4>
<p>
Hyperlinks can be also used to invoke some code when clicked.
</p>
<pre xml:space="preserve">
InputOutput io = InputOutput.get("UseCase3", true);
io.getOut().print("A line containing a ");
io.getOut().print("hyperlink", Hyperlink.from(new Runnable() {
public void run() {
System.gc();
}
}));
io.getOut().println(" for invocation of custom code.");
io.getOut().close();
</pre>
<h4>Print color text</h4>
<p>
Print a color text. Users can select a predefined color for
common cases (debug, warning, failure, success), or custom
color specified as RGB value.
</p>
<pre xml:space="preserve">
InputOutput io = InputOutput.get("UseCase4", true);
io.getOut().println("Let's print some info", OutputColor.debug());
io.getOut().println("or warning with appropriate color", OutputColor.warning());
io.getOut().println("Maybe also text with custom reddish color", OutputColor.rgb(255, 16, 16));
io.getOut().close();
</pre>
<h4>Reset an InputOutput to clear all previosly printed text</h4>
<p>
It is possible to reuse already created output pane and clear
all the previously printed text if it is not needed any more.
</p>
<pre xml:space="preserve">
InputOutput io = InputOutput.get("UseCase5", true);
io.getOut().println("Let's print some text");
io.getErr().println("and reset the pane immediately.");
io.reset();
io.getOut().println("The pane is now empty and we can reuse it simply");
io.getOut().close();
</pre>
<hr>
<h2>
<a name="usecase-Java Support APIs">How to use </a><a href="overview-summary.html#def-api-Java Support APIs">Java Support APIs</a>?
</h2>
<description>
Provides java specific queries (javadc, source level) used by other modules like java language infrastructure.
More information in the Javadoc.
</description>
<p></p>
<p>
The API is widely used by all sorts of IDE modules which need to work with
Java sources. They can find Javadoc, unit tests, source level, etc.
The SPI is intended mainly for Java platform and
library providers, and project type providers, to declare all of this
information.
</p>
<hr>
<h2>
<a name="usecase-Classpath APIs">How to use </a><a href="overview-summary.html#def-api-Classpath APIs">Classpath APIs</a>?
</h2>
<description>
Models basic aspects of the metadata surrounding list of source roots, such as
the classpath. More information in the Javadoc.
</description>
<p></p>
<p>
The API is widely used by all sorts of IDE modules which need to work with
sources. The SPI is intended mainly for (java) platforms and
library providers, and project type providers, to declare all of this
information.
</p>
<hr>
<h2>
<a name="usecase-Maven API">How to use </a><a href="overview-summary.html#def-api-Maven API">Maven API</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
Start exploring use-cases related to Maven archetypes
at the <a href="org-netbeans-api-maven/org/netbeans/api/maven/archetype/ArchetypeWizards.html" shape="rect">ArchetypeWizards</a> class.
</p>
<hr>
<h2>
<a name="usecase-Progress API">How to use </a><a href="overview-summary.html#def-api-Progress API">Progress API</a>?
</h2>
<description>
The progress API is good for tracking progress of long lasting tasks in the IDE.
</description>
<p></p>
<h4>Basic usage</h4>
<p>There are 3 types of progress indication:</p>
<ul>
<li>1. indefinite when it's not known how much time will be needed to complete</li>
<li>2. definite with time estimate for completion (UI shows time that remains)</li>
<li>3. definite without time estimate where the UI shows percentage completed.</li>
</ul>
<p>
The default location of the progress indication is the status bar which aggregates all
tasks running in the IDE that show progress. However it's possible to exclude the task from the default location
and show the progress in one's custom dialog component. In such a case the same task should not appear in the status line component as well.
</p>
<p>
It's possible to request cancelling the task from status line progress aggregator if the task allows cancelling.
</p>
<p>
Progress tasks that get started as a result of explicit user action takes precedence in the status line
docked component over tasks that are triggered by the system. (say filesystem refresh for example)
</p>
<p> The most common usecase of the API looks like this: </p>
<pre xml:space="preserve">
ProgressHandle handle = ProgressHandleFactory.creatHandle("My custom task");
...
// we have 100 workunits
// at this point the task appears in status bar.
handle.start(100);
...
handle.progress(10);
...
handle.progress("half way through", 50);
...
handle.progress(99);
// at this point the task is finished and removed from status bar
// it's not realy necessary to count all the way to the limit, finish can be called earlier.
// however it has to be called at the end of the processing.
handle.finish();
</pre>
<h4>Advanced Usage</h4>
<p>In case your usage of the API </p>
<ul>
<li>spans across multiple independent modules, </li>
<li>requires adjusting of number of workunits or </li>
<li>triggers additional action based on the current progress</li>
</ul>
<p>
then you should consider using the aggregating version of APIs which is similar to the
simple APIs but has distinctive differences and additions that allow for more complex scenarios.
</p>
<p>
It allows to compose the progress bar from 1+ independent sources, all sharing proportional piece
of the progress bar. Additionally you can monitor the task's overall progress from one central place and possibly
add more contributing sources of the progress during processing.
</p>
<pre xml:space="preserve">
// let's have a factory for client code that performs some part of the job to be done..
Lookup.Result res = Lookup.getDefault().lookup(new LookupTemplate(MyWorkerFactory.class));
Iterator it = res.allInstances().iterator();
ProgressContributor[] contribs = new ProgressContributor[res.allInstances().size()];
int i = 0;
while (it.hasNext()) {
MyWorkerFactory prov = (MyWorkerFactory)it.next();
contribs[i] = AggregateProgressFactory.createProgressContributor("Module X contribution");
MyWorker worker = prov.createWorker(contribs[i]);
//... snip ... do something with the worker..
i = i + 1;
}
AggregateProgressHandle handle = AggregateProgressFactory.createHandle("My Task", contribs, null, null);
// non-cancellable and with out output link.
// calling start() at the time when the actual long running task starts processing
handle.start("here we go");
// ...snip...
// now the individual MyWorker instances log their progress.
// possibly in other threads too..
// ... snip...
//
if (myConditionThatSpawnsAnotherContributor()) {
ProgressContributor cont = AggregateProgressFactory.createProgressContributor("Additional exceptional contribution");
handle.addContributor(cont);
// ... snip ...
}
// the task is finished when all the ProgressContributors finish..
</pre>
<hr>
<h2>
<a name="usecase-Progress API - Swing">How to use </a><a href="overview-summary.html#def-api-Progress API - Swing">Progress API - Swing</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-Search API">How to use </a><a href="overview-summary.html#def-api-Search API">Search API</a>?
</h2>
<description>
This project is good for implementators of nodes to define how files
under this node should be searched. For example, if you implement a
custom project type, you can define which folders should be searched
when the project is in the current search scope.
It is also good for people who want to add a custom tab into the
"Search in projects" dialog. For example, implementators of platform
applications can add form with criteria for searching in a database.
</description>
<p></p>
<h4>Search History</h4>
<p>
<code><a href="org-netbeans-api-search/org/netbeans/api/search/SearchHistory.html" shape="rect">SearchHistory</a></code>
is synchronising history content through netbeans modules and it saves history to preferences.
</p>
<p>
There are two separate histories. One for search and another for replace.
When you add your propertyListener to
<code><a href="org-netbeans-api-search/org/netbeans/api/search/SearchHistory.html" shape="rect">SearchHistory</a></code>
- you can listen for changes in histories.
</p>
<p>
<code><a href="org-netbeans-api-search/org/netbeans/api/search/SearchHistory.html" shape="rect">SearchHistory</a></code>
has methods for adding new entries and getting whole history list.
</p>
<h4>SearchInfo API &amp; SPI</h4>
<p>
This use-case was formerly covered by module
org.openidex.search.
</p>
<p>
The SearchInfo API+SPI allows other modules to specify whether
and how should nodes they define be searched.
</p>
<p>
The definition is represented by objects extending class
<code>
<a href="org-netbeans-api-search/org/netbeans/spi/search/SearchInfoDefinition.html" shape="rect">
SearchInfoDefinition</a>
</code>. To customize searching on a custom node, a
<code>SearchInfoDefinition</code> object must be added to the node's lookup.
In most cases, there is no need to define own class extending the
class - one can use factory methods of class
<code>
<a href="org-netbeans-api-search/org/netbeans/spi/search/SearchInfoDefinitionFactory.html" shape="rect">
SearchInfoDefinitionFactory</a>
</code>.
</p>
<p>
In some cases implementators may need to apply the same set
of SearchFilterDefinitions in the whole subtree of a node.
If so, it is not needed to put <code>SearchInfoDefinition</code> to all
nodes' lookups, but only one instance of <code>
<a href="org-netbeans-api-search/org/netbeans/spi/search/SubTreeSearchOptions.html" shape="rect">
SubTreeSearchOptions</a>
</code> have to be put into the lookup of the root node.
</p>
<api category="stable" group="java" name="SearchInfoSPI" type="export" url="org-netbeans-api-search/org/netbeans/spi/search/package-summary.html">
Defines abstract classes
<code><a href="org-netbeans-api-search/org/netbeans/spi/search/SearchInfoDefinition.html" shape="rect">SearchInfoDefinition</a></code>,
<code><a href="org-netbeans-api-search/org/netbeans/spi/search/SearchFilterDefinition.html" shape="rect">SearchFilterDefinition</a></code>,
<code><a href="org-netbeans-api-search/org/netbeans/spi/search/SubTreeSearchOptions.html" shape="rect">SubTreeSearchOptions</a></code>
and a factory class
<code><a href="org-netbeans-api-search/org/netbeans/spi/search/SearchInfoDefinitionFactory.html" shape="rect">SearchInfoDefinitionFactory</a></code>
</api>
<h4>Enhance IDE searching features</h4>
<p>
People that want to enhance IDE searching features (with custom
search criteria or specialized algorithms) can add a new tab to
the "Search in Projects" dialog.
</p>
<p>
They need to implement several classes:
</p>
<ul>
<li>
<code><a href="org-netbeans-api-search/org/netbeans/spi/search/provider/SearchProvider.html" shape="rect">SearchProvider</a></code>
to register the new search feature to the IDE or platform application.
</li>
<li>
<code><a href="org-netbeans-api-search/org/netbeans/spi/search/provider/SearchProvider.Presenter.html" shape="rect">SearchProvider.Presenter</a></code>
that creates visual component for adding to the search dialog and that can interact with dialog buttons.
</li>
<li>
<code><a href="org-netbeans-api-search/org/netbeans/spi/search/provider/SearchResultsDisplayer.html" shape="rect">SearchResultsDisplayer</a></code>
to show search results to the user.
</li>
<li>
<code><a href="org-netbeans-api-search/org/netbeans/spi/search/provider/SearchComposition.html" shape="rect">SearchComposition</a></code>
that encapsulates setting and state of searches, provide access to result displayer, and is able to start
and terminate the search.
</li>
</ul>
<api category="stable" group="java" name="SearchProviderSPI" type="export" url="org-netbeans-api-search/org/netbeans/spi/search/provider/package-summary.html">
Defines abstract classes that need to be implemented when
creating custom providers:
<code><a href="org-netbeans-api-search/org/netbeans/spi/search/provider/SearchProvider.html" shape="rect">SearchProvider</a></code>,
<code><a href="org-netbeans-api-search/org/netbeans/spi/search/provider/SearchProvider.Presenter.html" shape="rect">SearchProvider.Presenter</a></code>,
<code><a href="org-netbeans-api-search/org/netbeans/spi/search/provider/SearchResultsDisplayer.html" shape="rect">SearchResultsDisplayer</a></code>,
<code><a href="org-netbeans-api-search/org/netbeans/spi/search/provider/SearchComposition.html" shape="rect">SearchComposition</a></code>
and relative classes.
</api>
<api category="stable" group="java" name="SearchProviderAPI" type="export" url="org-netbeans-api-search/org/netbeans/api/search/provider/package-summary.html">
Classes usually used by search providers.
Contains class <code><a href="org-netbeans-api-search/org/netbeans/api/search/provider/SearchInfo.html" shape="rect">SearchInfo</a></code>,
that defines which files should be searched (it can be retrieved from methods in
<code><a href="org-netbeans-api-search/org/netbeans/api/search/provider/SearchInfoUtils.html" shape="rect">SearchInfoUtils</a></code>,
or UI component controller <code><a href="org-netbeans-api-search/org/netbeans/api/search/ui/ScopeController.html" shape="rect">ScopeController</a></code>),
<code><a href="org-netbeans-api-search/org/netbeans/api/search/provider/SearchListener.html" shape="rect">SearchListener</a></code>
that you should inform about events that happen during searching, and helper classes
<code><a href="org-netbeans-api-search/org/netbeans/api/search/provider/SearchInfoUtils.html" shape="rect">SearchInfoUtils</a></code>
(getting SearchInfo objects for nodes) and
<code><a href="org-netbeans-api-search/org/netbeans/api/search/provider/FileNameMatcher.html" shape="rect">FileNameMatcher</a></code>
(filtering files by file name).
</api>
<api category="stable" group="java" name="SearchProviderUIAPI" type="export" url="org-netbeans-api-search/org/netbeans/api/search/ui/package-summary.html">
Several UI components that can be used in presenters of search
providers, and factory method for creating them.
</api>
<h4>Search in Projects API</h4>
<p>
This API enables other modules to open Find in Projects dialog
with some pre-defined criteria and to start searching
programatically.
</p>
<api category="stable" group="java" name="SearchAPI" type="export" url="org-netbeans-api-search/org/netbeans/api/search/package-summary.html">
Contains classes for controlling search, passing search
criteria, and some helper classes.
</api>
<hr>
<h2>
<a name="usecase-File Templates">How to use </a><a href="overview-summary.html#def-api-File Templates">File Templates</a>?
</h2>
<description>
This utility standardizes the process to use files as blueprints to create new files.
</description>
<p></p>
<h4>Use boilerplates</h4>
<p>
An existing file can be used as a boilerplate for creation of a new file.
The boiler plate can contain necessary skeleton, comments, content. As the
boilerplate resides on config filesystem, it is also customizable by the user
and the user can eventually develop custom templates.
</p>
<p>
In previous NetBeans versions, templating system was built into
<api category="official" group="java" name="DataSystemsAPI" type="export" url="./org-openide-loaders/index.html"></api>.
</p>
<h4>Custom template handlers</h4>
<p>
Often many people require ability to create a "clever" template - e.g.
write piece of simple text and at the time of its
<a href="org-netbeans-api-templates/org/netbeans/api/templates/FileBuilder.html#createFromTemplate-org.openide.filesystems.FileObject-org.openide.filesystems.FileObject-java.lang.String-java.util.Map-org.netbeans.api.templates.FileBuilder.Mode-" shape="rect">
processing
</a>
do some advanced changes to it using either
<a name="scripting" shape="rect">scripting or templating</a> languages.
</p>
<p>
This traditionally used to be a bit complicated task (hacking into DataObject implementation), however since
version 6.1 there are interface in
<api category="deprecated" group="lookup" name="org.openide.loaders.CreateFromTemplateHandler" type="export" url="./org-openide-loaders/org/openide/loaders/CreateFromTemplateHandler.html">
DataSystem API
</api>
and finally
<api category="official" group="lookup" name="org.netbeans.api.templates.CreateFromTemplateHandler" type="export" url="org-netbeans-api-templates/org/netbeans/api/templates/CreateFromTemplateHandler.html">
that can be registered as a services in a lookup and it is reponsible
for handling the whole copy of the template file(s) to the destination
folder.
</api>
</p>
<h4>Custom attributes for processing</h4>
<p>
Runtime or project-related values may be supplied by
<api category="official" group="lookup" name="org.openide.loaders.CreateFromTemplateAttributes" type="export" url="org-netbeans-api-templates/org/netbeans/api/templates/CreateFromTemplateAttributes.html">
that can be registered as a services in a lookup and it is reponsible
for providing "hints" - e.g. map mapping strings to various objects.
</api> and these interfaces allow anyone to extend the behaviour during
creation of new files.
</p>
<p>
The <a href="org-netbeans-api-templates/org/netbeans/api/templates/CreateFromTemplateAttributes.html" shape="rect">CreateFromTemplateAttribute</a> implementation
knows which template is being used, where the outcome should be placed, so it can derive appropriate values for both
the template and the target location.
</p>
<h4>Using Scripting and Templating Languages</h4>
<p>
There is a built in support for scripting languages in
the standard NetBeans IDE. If a template is annotated with
<api category="official" group="property" name="javax.script.ScriptEngine" type="export">
a property that can be associated to templates that either should
return real instance of <code>ScriptEngine</code> interface or
a <code>String</code> name of the engine that is then used to
search for it in the <code>javax.script.ScriptEngineManager</code>.
Usually the <a href="http://freemarker.sourceforge.net/" shape="rect">freemarker</a> engine is the one that is
supported by the NetBeans IDE - if your module wants to use it
then include a token dependency <code>OpenIDE-Module-Needs: javax.script.ScriptEngine.freemarker</code>
in your manifest file (also accessible through project customizer GUI)
to indicate to the system that you need it.
</api>
then the scripting engine is then used to process the template and
generate the output file. While running the engine one can rely
on few predefined properties:
</p>
<ul>
<li>
<api category="stable" group="property" name="name" type="export"> contains the name of the <a href="./org-openide-loaders/org/openide/loaders/DataObject.html" shape="rect">DataObject</a> that is being created</api>
</li>
<li>
<api category="stable" group="property" name="user" type="export"> contains the name the user</api>
</li>
<li>
<api category="stable" group="property" name="nameAndExt" type="export"> contains the name and extension of the file that is being created</api>
</li>
<li>
<api category="stable" group="property" name="date" type="export"> contains <code>String</code> representing the current day like <code>23. 3. 2007</code>
</api>
</li>
<li>
<api category="stable" group="property" name="time" type="export"> contains <code>String</code> the current time like <code>17:18:30</code>
</api>
</li>
<li>
<api category="stable" group="property" name="dateTime" type="export"> contains <code>java.util.Date</code> representing current data and time like</api>
</li>
<li>
<api category="stable" group="property" name="encoding" type="export"> contains <code>String</code> the file encoding of the template instance</api>
</li>
</ul>
<p>
Other properties can indeed be provided by
<a href="org-netbeans-api-templates/org/netbeans/api/templates/CreateFromTemplateAttributes.html" shape="rect">CreateFromTemplateAttributes</a>s.
After processing, the output is also sent to appropriate
<code>org.openide.text.IndentEngine</code> associated
with the mime type of the template, for formating.
</p>
<p style="margin-left: 0.2in; margin-right: 0.2in; margin-top: 0.2in; margin-bottom: 0.2in; border: 1.00pt solid #9999cc; padding: 0.1in; color: #666699">
<b>Smart Templating Quick How-To</b>
<br>
First of all create a file in your module layer located somewhere
under the <code>Templates/</code> folder. Make it a template by
adding &lt;attr name="template" boolvalue="true"/&gt;. Associate
this template with a scripting language, for example by
&lt;attr name="javax.script.ScriptEngine" stringvalue="freemarker"/&gt;.
Now make sure that the scripting language integration is also available
by requesting a token in standard format, for freemarker just put
<code>OpenIDE-Module-Needs: javax.script.ScriptEngine.freemarker</code>
in your manifest. This tells the NetBeans module system that a
module providing integration with such scripting engine has to be
enabled. Now you can use regular script language tags inside of
your template file. When you write your <code>instantiate</code>
method in your wizard, you can create a Map&lt;String,Object&gt; and
fill it with parameters collected from your wizard and then pass it
to
<a href="./org-openide-loaders/org/openide/loaders/DataObject.html" shape="rect">
createFromTemplate(targetFolder, targetName, mapWithParameters)
</a>. This will invoke the scripting language and make the
<code>mapWithParameters</code> values available to it. Beyond this
there is few standard parameters predefined including <code>name</code>, <code>user</code>, <code>date</code>, <code>time</code>, etc.
and also additional parameters are collected from all registered
<a href="./org-openide-loaders/org/openide/loaders/CreateFromTemplateAttributesProvider.html" shape="rect">CreateFromTemplateAttributesProvider</a>s.
</p>
<h4>Create sets of files</h4>
<p>
A <a href="org-netbeans-api-templates/org/netbeans/api/templates/CreateFromTemplateHandler.html" shape="rect">CreateFromTemplateHandler</a>
should be able to create multiple files, one of them <i>important</i> so it will open after user
initiates the creation action. The template of set of related files may be represented by a folder with
a handler attached, and the operation deploys multiple files in the target directory.
</p>
<h4>Use HTML and JavaScript</h4>
<a name="html-and-js" shape="rect"></a>
<p>
There is a way to create a portable wizard (e.g. one that can
be executed inside of NetBeans as well as in a browser). The
most portable UI these days is written in HTML. To
register such HTML based wizard with your file template,
use <a href="org-netbeans-api-templates/org/netbeans/api/templates/TemplateRegistration.html" shape="rect">@TemplateRegistration</a>
annotation and include <code>page()</code> attribute referencing
your own HTML page:
</p>
<pre xml:space="preserve">
<b>public class</b> X {
{@code @TemplateRegistration}(
page = "x.html",
scriptEngine = "freemarker",
displayName = "JS Wizard",
folder = "Other",
content = "x.fmk"
)
<b>public static</b> String jsWizard() {
<b>return</b> "yourInitializationCode();";
}
}
</pre>
<p>
the return value of the annotated method (named <code>jsWizard</code>)
should be of type String and its content should be snippet of
JavaScript code to execute inside of your specified HTML page
(e.g. <code>x.html</code>) to create an instance of
<a href="http://knockoutjs.com" shape="rect">KnockoutJS model</a> to
drive the wizard. Here is a sample code for the model:
</p>
<pre xml:space="preserve">
<b>function</b> yourInitializationCode() {
<b>var</b> ok = ko.observable(false);
<b>var</b> msg = ko.observable('');
<b>var</b> current = ko.observable('Init');
<b>var</b> data = {
'errorCode': ko.computed(function() {
if ('Init' == current()) <b>return</b> 0;
if (!ok()) <b>return</b> 1;
if (msg()) <b>return</b> 0;
<b>return</b> 2;
}),
'current': current,
'ok': ok,
'msg' : msg
}
ko.applyBindings(data);
<b>return</b> data;
}
</pre>
<p>
The model defines wizard composed of few panels (defined in following
HTML file) and a verification function (registered as <code>errorCode</code>)
to check if everything is OK. In addition to that it defines
proprietary text value <code>msg</code> which is
going to be filled by the wizard and cannot be empty. Each
page of the wizard is registered using a custom
<a href="http://knockoutjs.com" shape="rect">Knockout.js</a> binding called
<code>step</code>. Here is an HTML page defining three steps:
</p>
<pre xml:space="preserve">
&lt;<b>section</b> data-bind="step: { 'id' : 'init', text : 'Initial Page'}" &gt;
&lt;<b>p</b>&gt;
Write your UI in portable HTML and display it in NetBeans
or on web! Read more at &lt;a href="http://wiki.netbeans.org/HtmlUIForTemplates"&gt;our wiki&lt;/a&gt;...
&lt;/<b>p</b>&gt;
&lt;/<b>section</b>&gt;
&lt;<b>section</b> data-bind="step: 'info'" &gt;
&lt;<b>p</b>&gt;
Use &lt;a href="http://knockoutjs.com"&gt;knockout.js&lt;/a&gt; bindings
to isolate your view model from the actual look of your HTML
page. Bind your view to model written in Java or JavaScript.
&lt;/<b>p</b>&gt;
&lt;<b>h3</b>&gt;Is everything OK?&lt;/<b>h3</b>&gt;
&lt;<b>input</b> type="checkbox" data-bind="checked: ok"/&gt;
&lt;<b>h3</b>&gt;How do you feel?&lt;/<b>h3</b>&gt;
&lt;<b>input</b> type='text' data-bind="textInput: msg"/&gt;
&lt;/<b>section</b>&gt;
&lt;<b>section</b> data-bind="step: { 'id' : 'summary' }" &gt;
&lt;<b>p</b>&gt;
You are feeling &lt;<b>span</b> data-bind="text: msg"&gt;&lt;/<b>span</b>&gt;!
Let's proceed to create a file which will express your
feeling by using &lt;<b>a</b> href="http://freemarker.org/"&gt;Freemarker&lt;/<b>a</b>&gt;
templating engine and values filled in this wizard.
&lt;/<b>p</b>&gt;
&lt;/<b>section</b>&gt;
</pre>
<p>
The Next/Finish buttons are controlled by the <code>errorCode</code> property.
If it is non-zero, there is an error and these buttons are disabled.
Also once can use that inside of the HTML page to display user related errors:
</p>
<pre xml:space="preserve">
&lt;<b>div</b> data-bind="visible: errorCode() == 1"&gt;
&lt;<b>span</b> style="color: red"&gt;Please check you are OK!&lt;/<b>span</b>&gt;
&lt;/<b>div</b>&gt;
&lt;<b>div</b> data-bind="visible: errorCode() == 2"&gt;
&lt;<b>span</b> style="color: red"&gt;Tell us how do you feel!&lt;/<b>span</b>&gt;
&lt;/<b>div</b>&gt;
</pre>
<p>
The L10N of the wizard is done on the level of HTML pages.
The whole page gets translated into different language with appropriate
suffix like <code>x_cs.html</code> and it is then
selected instead of the default one, when user runs in such locale.
</p>
<p>
When the wizard is successfully finished, all the values
specified in the model (except system ones like <code>current</code>,
<code>errorCode</code>, etc.) are transfered to the templating engine,
so they can influence the content of created files.
Here is a sample <code>x.fmt</code> content which reuses the <code>msg</code>
value provided by the wizard:
</p>
<pre xml:space="preserve">
Hi,
I am Freemarker.
I feel ${wizard.msg}.
</pre>
<p>
When such file is instantiated, the <code>${wizard.msg}</code> is
replaced by the actual value taken from the wizard.
</p>
<h4>Use HTML and Java</h4>
<a name="html-and-java" shape="rect"></a>
<p>
Some people would rather use Java instead of Java script while
getting the portability of the <em>HTML</em>. There is a simple
way to rewrite the <a href="#html-and-js" shape="rect">HTML and JavaScript sample</a>
to <b>Java</b>
(and possibly run it in a plugin-less browser via
<a href="http://bck2brwsr.apidesign.org" onclick="target='_blank'" shape="rect">bck2brwsr VM</a>). Keep the
same HTML, <a href="http://freemarker.org/" onclick="target='_blank'" shape="rect">Freemarker</a>, etc.
files - just instead of encoding the logic in JavaScript use Java:
</p>
<pre xml:space="preserve">
{@link net.java.html.json.Model @Model}(className = "JavaWizard", properties = {
{@link net.java.html.json.Property @Property}(name = "current", type = String.<b>class</b>),
{@link net.java.html.json.Property @Property}(name = "ok", type = <b>boolean</b>.<b>class</b>),
{@link net.java.html.json.Property @Property}(name = "msg", type = String.<b>class</b>)
})
<b>public class</b> JavaWizardCntrl {
{@link net.java.html.json.ComputedProperty @ComputedProperty} <b>static int</b> errorCode(
String current, boolean ok, String msg
) {
if ("Init".equals(current)) <b>return</b> 0;
if (!ok) <b>return</b> 1;
if (msg == null || msg.isEmpty()) <b>return</b> 2;
<b>return</b> 0;
}
{@code @TemplateRegistration}(
page = "x.html",
scriptEngine = "freemarker",
displayName = "HTML/Java Wizard",
folder = "Java",
content = "x.fmk"
)
<b>public static</b> JavaWizard javaWizardFactory() {
return new JavaWizard("Init", false, "");
}
}
</pre>
<p>
The return value of the annotated method is now an
<a href="http://bits.netbeans.org/html+java/" onclick="target='_blank'" shape="rect">HTML/Java</a>
model class which can naturally represent the essential
<a href="http://knockoutjs.com" onclick="target='_blank'" shape="rect">Knockout.js</a> objects
in Java.
</p>
<h4>Selecting target location with HTML UI</h4>
<a name="targetchooser" shape="rect"></a>
<p>
It is very common that the HTML file creation wizards (either
controled by <a href="#html-and-js" shape="rect">JavaScript</a> or by
<a href="#html-and-java" shape="rect">Java</a>) need to allow user to specify
target location of their file. To simplify such common task and
to ensure its UI is consistent with the rest of the environment,
one can just include following code snippet in the HTML file and
leave its actual rendering on the system:
</p>
<pre xml:space="preserve">
&lt;<b>section</b> data-bind="step: 'targetChooser'" &gt;
&lt;/<b>section</b>&gt;
</pre>
<p>
Such section will then be replaced by a panel which provides appropriate
UI for choosing target directory as well as name for the newly created
file.
</p>
<a name="javaTargetChooser" shape="rect"></a>
<p>
In case one prefers more Java-like chooser, it is possible to use
<code>'targetChooser:java'</code> as name of the step. Then all
Java source groups in target project will be listed and presented
in a typical Java package view selection mode. Once can use different
suffix than <code>java</code> to list other types of source groups.
This feature requires presence of <code>org.netbeans.modules.java.project.ui</code>
module, otherwise the target chooser falls back to classical one.
</p>
<h4>UI for Maven Archetypes</h4>
<a name="html-and-maven" shape="rect"></a>
<p>
There is a way to create a portable wizard (with logic either
in <a href="#html-and-js" shape="rect">JavaScript</a> or in
<a href="#html-and-java" shape="rect">Java</a>) to instantiate a <b>Maven</b>
archetype. This way one merges the <em>project templating</em>
functionality of <b>Maven</b> with flexible and tailored UI
provided by HTML and JS/Java.
</p>
<p>
The definition of the UI is the same as in
<a href="#html-and-js" shape="rect">previous</a>
<a href="#html-and-java" shape="rect">cases</a>, just as a <a href="#targetchooser" shape="rect">target chooser</a>
one can also use dedicated <b>Maven</b> one - just use
<code>'targetChooser:archetype'</code> to get a panel
with options to select directory, <code>archetypeId</code>,
<code>groupId</code> and <code>version</code> of the project to
create.
This feature requires presence of <code>org.netbeans.api.maven</code>
module, otherwise the target chooser falls back to classical one.
</p>
<p>
The archetype registration is then a classical one. Here is an
example of the UI being in <code>x.html</code> and the archetype
described in <code>x.archetype</code> one:
</p>
<pre xml:space="preserve">
{@code @TemplateRegistration}(
page = "x.html",
displayName = "HTML/Java Wizard",
folder = "Java",
content = "x.archetype"
)
<b>public static</b> MavenWizard mavenArchetype() {
<b>return new</b> MavenWizard(<em>/*...*/</em>);
}
</pre>
<p>
The <code>x.archetype</code> file describes the archetype to use
and has following properties-like syntax:
</p>
<pre xml:space="preserve">
archetypeGroupId=org.codehaus.mojo.archetypes
archetypeArtifactId=javafx
archetypeVersion=0.6
archetypeBuild=false # or true to build the project once created
archetypeOpen=src/main/java/.*/Main.java,src/main/resources/default.config # regexp to
# find files that should be opened once the project is created
</pre>
<p>
The values <code>archetypeArtifactId</code>,
<code>archetypeGroupId</code> and <code>archetypeVersion</code>
are by default taken from the archetype definition file, but the
wizard model can define these properties as well and in such case
they would take precedence. These values define what Maven
archetype will be used to initialized the project structure.
</p>
<p>
Any properties defined by the model (in the above example
the <code>MavenWizard</code>) are going to be passed into
<b>Maven</b> archetype execution and can thus influence the
the behavior of the archetype - this is the way to write an
HTML UI for <b>Maven</b> archetype.
</p>
<hr>
<h2>
<a name="usecase-Visual Library API">How to use </a><a href="overview-summary.html#def-api-Visual Library API">Visual Library API</a>?
</h2>
<description>
The Visual Library 2.0 is the next generation of the original Graph Library 1.0.
It is designed for a general visualization with a support for graph-oriented modeling.
Its focus is to become a part of the NetBeans platform and unify the visualization (UI and API) used in NetBeans-Platform-based applications.
See http://graph.netbeans.org/ web-site for details.
See documentation for complete set of use-cases and code-snippets.
</description>
<p></p>
<p>
See <a href="org-netbeans-api-visual/org/netbeans/api/visual/widget/doc-files/documentation.html" shape="rect">documentation</a> for complete set of use-cases.
</p>
<hr>
<h2>
<a name="usecase-Bootstrap">How to use </a><a href="overview-summary.html#def-api-Bootstrap">Bootstrap</a>?
</h2>
<description>
The NetBeans launcher starts the application. Different launchers are
provided for different supported platforms - Unix/Linux, Windows, and
others. There are also a handful of classes in the
org.netbeans and org.netbeans.core packages
which directly support early startup features, such as command-line
options.
</description>
<p></p>
<h4>Invalidating Caches</h4>
<a name="usecase-invalidate.cache" shape="rect"></a>
<p>
NetBeans Module system is optimized to eliminate useless I/O
operations on start (as a result the <a href="http://netbinox.apidesign.org" shape="rect">
embedded OSGi container</a> is fastest on the planet -- with respect to
application start up time). This is achieved by caching information
known to have been needed in previous starts and using it
rather than obtaining it again from the module JAR files.
</p>
<p>
There are various caches (like
<a href="org-netbeans-bootstrap/architecture-summary.html#java.io.File-all-layers.dat" shape="rect">all-layers.dat</a>,
<a href="org-netbeans-bootstrap/architecture-summary.html#java.io.File-all-manifests.dat" shape="rect">all-manifests.dat</a>,
<a href="org-netbeans-bootstrap/architecture-summary.html#java.io.File-all-resources.dat" shape="rect">all-resources.dat</a>,
<a href="./org-netbeans-core-netigso/architecture-summary.html#java.io.File-netigso-bundles" shape="rect">netigso-bundles</a>,
etc.
) provided by the module system or by other subsystems of the application.
Together, working in orchestration, they eliminate the need to
touch the disk (which is very slow operation especially during
<a href="http://wiki.apidesign.org/wiki/Startup#Morning_Launch" shape="rect">morning launch</a>).
Btw. there is a <a href="http://hg.netbeans.org/releases/file/cdbdc70050a8/core.startup/test/unit/src/org/netbeans/core/startup/layers/CachingPreventsFileTouchesTest.java" shape="rect">
test which verifies</a>
the caching system really works
-- it is recommended for each product built on top of NetBeans Platform
to copy and adjust it to verify the caches are really used.
</p>
<p>
Of course, the caches may get out of date, for example when an external
tool modifies the installation layout.
How can the system detect whether the caches are valid and
still be usable? The only way to verify the
caches are 100% correct is to regenerate them and compare whether the
cached bits are the same. However that would be terribly slow and defeat
the whole purpose of using caches.
</p>
<p>
As such we have the <a href="org-netbeans-bootstrap/architecture-summary.html#java.io.File-.lastModified" shape="rect">lastModified API</a>.
Every cluster (as enumerated by <a href="org-netbeans-bootstrap/architecture-summary.html#systemproperty-netbeans.dirs" shape="rect">netbeans.dirs</a>
and <a href="org-netbeans-bootstrap/architecture-summary.html#systemproperty-netbeans.home" shape="rect">netbeans.home</a> properties)
is supposed to contain such file. Whenever an external tool changes something
inside some cluster, it is supposed to touch the file and change its
timestamp. That will tell the system that caches are invalid
(as their timestamps will become older than newest <code>.lastModified</code> file).
</p>
<h4>Generating Shared Cache</h4>
<p>
The caches (as introduced in <a href="org-netbeans-bootstrap/architecture-summary.html#usecase-invalidate.cache" shape="rect">
invalidating caches</a> section) are optimized to reflect the state of
previous start. However that means, the very first start runs
without them. This may not be a problem (if the start follows
immediately after installation), however in <a href="http://wiki.apidesign.org/wiki/Startup#Multi_User_Initial_Launch" shape="rect">
multi user environment</a> (when the installation is done by administrator),
the first start may be slow.
</p>
<p>
To mitigate that the system offers support for <em>shared caches</em>.
As part of installation, one can also copy <a href="org-netbeans-bootstrap/architecture-summary.html#java.io.File-installation.cache" shape="rect">
certain cache files
</a> into the shared location. Those files will then be used
on a first start of the system (when the user directory is empty).
</p>
<p>
To generate the shared cache files start NetBeans with an empty,
temporary user directory and then copy the desired files into
first cluster directory:
</p>
<pre xml:space="preserve">
$ netbeans --userdir /tmp/nb -J-Dnetbeans.close=true -J-Dorg.netbeans.core.WindowSystem.show=false
$ cd /tmp/nb
$ zip -r $INSTALL/$first_netbeans_dirs_dir/var/cache/populate.zip var/cache/netigso
$ cp var/cache/* $INSTALL/$first_netbeans_dirs_dir/var/cache
$ rm -r /tmp/nb/
</pre>
<p>
The meaning of <code>populate.zip</code> and list of known cache
files is described <a href="org-netbeans-bootstrap/architecture-summary.html#java.io.File-installation.cache" shape="rect">here</a>.
Additional modules and subsystems may add new files however. The
ultimate knowledge is available only to those who understand overall
product installation structure.
</p>
<h4>Patch classes</h4>
<a name="usecase-patch" shape="rect"></a>
<p>
In case one wants to modify other classes before they get loaded into
the VM, one can register its own
<code>Agent-Class</code> and then be called whenever another
class is defined. The behavior matches as closely as possible the one
provided by <a href="http://download.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html" shape="rect">
JDK instrument package</a>. To patch bytecode of other classes
register your class in manifest and in its static <code>agentmain</code> method
add your own <a href="http://download.oracle.com/javase/8/docs/api/java/lang/instrument/ClassFileTransformer.html" shape="rect">ClassFileTransformer</a>
which will then be consulted whenever new classes are loaded.
</p>
<pre xml:space="preserve">
# following line should be in manifest of your module
Agent-Class: your.pkg.Transformer
// this should be your class
package your.pkg;
public class Transformer implements ClassFileTransformer {
public static void agentmain(String args, Instrumentation i) {
i.addTransformer(new Transformer());
}
public byte[] transform(
ClassLoader loader, String className, Class classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer
) {
// do your transformation
}
}
</pre>
<p>
The implementation tries to be as complient as possible with the
original JDK's specification, but
some differences are inevitable. For example the <code>classBeingRedefined</code>
parameter in the previous example is always <code>null</code>
as NetBeans runtime container does not
have access to the class instance that is being defined yet.
</p>
<h4>Module Fragments</h4>
<a name="usecase-modfrag" shape="rect"></a>
<p>
This is a specific case of <a href="#usecase-patch" shape="rect">Patch Classes</a> use-case.
To maintain binary compatibility when <b>removing</b> methods from API classes,
the "removed" implementation is actually moved to a special class, which becomes
a <i>superclass</i> of the original API class. Such special classes should be
separated into a 'compat' module, which is only loaded in presence of old clients.
</p>
<p>
The compat module should declare it is a fragment of the original API module in its
<code>MANIFEST.MF</code>
</p>
<pre xml:space="preserve">
OpenIDE-Module-Fragment-Host: orignal.module.codename
</pre>
<p>
which ensures contents of the compat module will be loaded using classloader
of the 'fragment host' module. The compat module will not get its own classloader.
The special class itself should be marked using <a href="./org-openide-modules/org/openide/modules/PatchFor.html" shape="rect">PatchFor</a> annotation,
which causes it will be patched as superclass and inserted into the inheritance
chain.
</p>
<hr>
<h2>
<a name="usecase-Core">How to use </a><a href="overview-summary.html#def-api-Core">Core</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
No special APIs exported beyond few friend contracts:
<ul>
<li>
<api category="friend" group="java" name="org.netbeans.core.modules.AutomaticDependencies" type="export" url="./org-openide-modules/org/openide/modules/doc-files/api.html#refactoring"></api>
</li>
<li>
<api category="friend" group="java" name="org.netbeans.core.WindowSystem" type="export"></api>
</li>
</ul>
<hr>
<h2>
<a name="usecase-Core - IDE">How to use </a><a href="overview-summary.html#def-api-Core - IDE">Core - IDE</a>?
</h2>
<description>
<b>core.ide</b>
</description>
<p></p>
<p>
<h4>Register Node in Services tab</h4>
Use <a href="org-netbeans-core-ide/org/netbeans/api/core/ide/ServicesTabNodeRegistration.html" shape="rect">
ServicesTabNodeRegistration</a> to register your nodes into <em>Services</em> in the IDE.
</p>
<hr>
<h2>
<a name="usecase-Multi-tabs">How to use </a><a href="overview-summary.html#def-api-Multi-tabs">Multi-tabs</a>?
</h2>
<description>
Allow easy customization of editor tabs.
</description>
<p></p>
<p>
<h4>Tab Decorator</h4>
<p>To customize the rendering of (some) editor tabs one needs subclass
<code>TabDecorator</code> class and register it in the global <code>Lookup</code>.</p>
<p>The example below shows a decorator that removes file extension
from Java source files to have shorter tabs to show more file names
without the need for scrolling.</p>
<pre xml:space="preserve">
ServiceProvider(service = TabDecorator.class, position = 1000)
public class MyTabDecorator extends TabDecorator {
public String getText( TabData tab ) {
String res = tab.getText();
if( null != res )
res = res.replace( ".java", "");
return res;
}
}
</pre>
<h4>Custom Tab Displayer</h4>
<p>If one needs a custom editor tab displayer for example to have special
tab layout or special layout of scrolling buttons etc it is necessary
to subclass <code>TabDisplayer</code> class and register an instance
of <code>TabDisplayerFactory</code> in the global <code>Lookup</code>.
</p>
<pre xml:space="preserve">
public class MyTabDisplayer extends TabDisplayer {
public MyTabDisplayer( TabDataModel model ) {
super( model );
}
ServiceProvider(service = TabDisplayerFactory.class)
public static class MyTabDisplayerFactory extends TabDisplayerFactory {
public TabDisplayer createTabDisplayer( TabDataModel tabModel, int orientation ) {
return new MyTabDisplayer( tabModel );
}
}
//implement all abstract methods here
}
</pre>
</p>
<hr>
<h2>
<a name="usecase-MultiView Windows">How to use </a><a href="overview-summary.html#def-api-MultiView Windows">MultiView Windows</a>?
</h2>
<description>
Multi views are general mechanism for displaying several perspectives, or views of data,
which will be used consistently across whole IDE window system. Using multi views
will enable modules to visually represent data document or object in unified manner
at one specific place in the system, yet still allowing for different perspectives
of data viewing.
</description>
<p></p>
There is an introduction to MultiView and its usage in its
<a href="org-netbeans-core-multiview/overview-summary.html" shape="rect">javadoc</a>. It covers the major part
of available usecases.
Here is just
a list of frequently asked or interesting questions slowly expanding as
people ask them:
<h3>MultiView faq:</h3>
<h4>How does serialization work?</h4>
<em><b>Q:</b>
How does serialization of multiviews work and what needs to be serializable?
</em>
<p>
First of all, you don't need to worry about serialization if all your <code>MultiViewDescription</code> instances
contained in the multiview state to be non serializable.
Meaning they all return <code>TopComponent.PERSISTENCE_NEVER</code> in <code>MultiViewDescription.getPersistenceType()</code>.
</p>
<p>
If at least one of the views requires serialization, you have no choice but to make all
<code>MultiViewDescription</code> implementors serializable.
You also can persist the MultiViewElement instances that the multiview contains. The algorithm here is a bit complicated for
performance reasons. Only those Elements are stored that were created during the session and which are Serializable.
So if the user never switches to the 4rd tab, and it's corresponding element and visual component never get created, then
it won't be stored. (We would have to create it just for the sake of persistance).
So if your visual component needs some inital context for creation, you should store it in the description instance, and if the visual component
wants to store it's state (location of cursor, selected field, something else that makes sense for the opened component) you should store it in the MultiViewElement.
So basically if you are always able create the Element from Description without any persisted data, you don't need to persist anything.
</p>
<p>
If you define your own <code>CloseOperationHandler</code> implementation for the multiview component, then you also ought to define it
Serializable. Otherwise it will be silently replaced by the default handler on restoration of the multiview component.
</p>
<h4>How to set the display name?</h4>
<em><b>Q:</b>
How do I set the display name for the multiview component?
</em>
<p>
Each <code>MultiViewDescription</code> defines display name and icon. While the icon
is meant for the whole document/view tab, the display name is just for the inner switching button.
So how does one set the name for the whole MultiView component? It can be done when creating the component.
</p>
<pre xml:space="preserve">
TopComponent mvtc = MultiViewFactory.createMultiView(myDescriptions);
mvtc.setDisplayName("My static mvtc displayName");
</pre>
<p>
Later in the lifecycle of the component, it can be also influenced from within the individual
multiview visual elements using the <code>MultiViewElementCallback.updateTitle()</code> method.
</p>
<hr>
<h2>
<a name="usecase-NetBeans OSGi Integration">How to use </a><a href="overview-summary.html#def-api-NetBeans OSGi Integration">NetBeans OSGi Integration</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
<h4>Share NetBeans Resource Cache</h4>The only supported usecase right now is to
allow any framework to obtain access to internal cache and load classes
from it. See <a href="org-netbeans-core-netigso/org/netbeans/core/netigso/spi/NetigsoArchive.html" shape="rect">NetigsoArchive</a>.
</p>
<hr>
<h2>
<a name="usecase-Core Network">How to use </a><a href="overview-summary.html#def-api-Core Network">Core Network</a>?
</h2>
<description>
The Core Network module provide ProxySelector as well as utilities related
to network connections.
</description>
<p></p>
<p>
<h4>Custom ProxySelector</h4>
You can provide your own ProxySelector instead of the one
provided by this module. You do this by registering your
own {@link java.net.ProxySelector}
in the Global Lookup. However, make sure you understand that
the instantiation of the ProxySelector (i.e. executing its constructor)
is part of the main startup path of a NetBeans application. For this
reason the constructor better be fast. Defer as much work as possible to
later.
<api category="standard" group="java" name="java.net.ProxySelector" type="import" url="http://download.oracle.com/javase/8/docs/api/java/net/ProxySelector.html"></api>
<h4>Custom PAC Evaluator</h4>
You can plug in your own PAC evaluator if you are unhappy with
the {@link org.netbeans.core.network.proxy.pac.impl.NbPacScriptEvaluator default one}
provided in this module. You do this by registering your
own {@link org.netbeans.core.network.proxy.pac.PacScriptEvaluatorFactory}
in the Global Lookup. This factory must then in turn return an
instance of your custom {@link org.netbeans.core.network.proxy.pac.PacScriptEvaluator}.
<api category="friend" group="java" name="org.netbeans.core.network.proxy.pac.PacScriptEvaluatorFactory" type="export" url="org-netbeans-core-network/org/netbeans/core/network/proxy/pac/PacScriptEvaluatorFactory.html"></api>
<api category="friend" group="java" name="org.netbeans.core.network.proxy.pac.PacScriptEvaluator" type="export" url="org-netbeans-core-network/org/netbeans/core/network/proxy/pac/PacScriptEvaluator.html"></api>
<h4>Customizing the default PAC Evaluator</h4>
Instead of replacing all of the {@link org.netbeans.core.network.proxy.pac.impl.NbPacScriptEvaluator default PAC evaluator}
you can replace only its implementation of the <i>PAC Helper Functions</i>.
However, you have to play by rules set by the {@link org.netbeans.core.network.proxy.pac.impl.NbPacScriptEvaluator default PacScriptEvaluator},
namely that all the Helper Functions are implemented in Java (as opposed to JavaScript).
Simply register your sub-class of {@link org.netbeans.core.network.proxy.pac.PacHelperMethods}
in the Global Lookup and your implementation will automatically be picked
up. When creating your own <code>PacHelperMethods</code> you may
take benefit from the PAC utility functions provided by {@link org.netbeans.core.network.proxy.pac.PacUtils}
and {@link org.netbeans.core.network.proxy.pac.datetime.PacUtilsDateTime},
as well as the more general ones provided by {@link org.netbeans.core.network.utils network utils package}.
<api category="friend" group="java" name="org.netbeans.core.network.proxy.pac.PacHelperMethods" type="export" url="org-netbeans-core-network/org/netbeans/core/network/proxy/pac/PacHelperMethods.html"></api>
<api category="friend" group="java" name="org.netbeans.core.network.utils.HostnameUtils" type="export" url="org-netbeans-core-network/org/netbeans/core/network/utils/HostnameUtils.html"></api>
<api category="friend" group="java" name="org.netbeans.core.network.utils.IpAddressUtils" type="export" url="org-netbeans-core-network/org/netbeans/core/network/utils/IpAddressUtils.html"></api>
<api category="friend" group="java" name="org.netbeans.core.network.utils.LocalAddressUtils" type="export" url="org-netbeans-core-network/org/netbeans/core/network/utils/LocalAddressUtils.html"></api>
<api category="friend" group="java" name="org.netbeans.core.network.utils.SimpleObjCache" type="export" url="org-netbeans-core-network/org/netbeans/core/network/utils/SimpleObjCache.html"></api>
<api category="friend" group="java" name="org.netbeans.core.network.proxy.pac.PacUtils" type="export" url="org-netbeans-core-network/org/netbeans/core/network/proxy/pac/PacUtils.html"></api>
<api category="friend" group="java" name="org.netbeans.core.network.proxy.pac.datetime.PacUtilsDateTime" type="export" url="org-netbeans-core-network/org/netbeans/core/network/proxy/pac/datetime/PacUtilsDateTime.html"></api>
</p>
<hr>
<h2>
<a name="usecase-Startup">How to use </a><a href="overview-summary.html#def-api-Startup">Startup</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-UI Handler Library">How to use </a><a href="overview-summary.html#def-api-UI Handler Library">UI Handler Library</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-Git Library API">How to use </a><a href="overview-summary.html#def-api-Git Library API">Git Library API</a>?
</h2>
<description>
The library provides a Java implementation of git client allowing you to work with and get information about Git repositories and run Git commands.
</description>
<p></p>
<h4>Get Git client</h4>
Before you can run preferred Git commands, you must get an instance of <a href="org-netbeans-libs-git/org/netbeans/libs/git/GitClient.html" shape="rect">GitClient</a> bound to a specific repository.<br>
Instances of <code>GitClient</code> are provided by <a href="org-netbeans-libs-git/org/netbeans/libs/git/GitRepository.html#createClient--" shape="rect">GitRepository</a>.
<code>GitRepository</code> represents a concrete local Git repository and is always bound to a specific folder.
<p></p>
The correct way to achieve this is to call <code><a href="org-netbeans-libs-git/org/netbeans/libs/git/GitRepository.html" shape="rect">GitRepository</a>.getInstance(repositoryRoot).createClient()</code>.
<h4>Run Git commands</h4>
To run a Git command simply call a method mapped to the command on an instance of GitClient.
<h4>Control Git command's workflow</h4>
You are able to control a Git command's work and listen for warning and error messages and informative messages indicating start and finish of the command via
<a href="org-netbeans-libs-git/org/netbeans/libs/git/progress/ProgressMonitor.html" shape="rect">ProgressMonitor</a>. Every method of <code>GitClient</code> mapped to a Git command accepts an instance of
<code>ProgressMonitor</code> as a parameter. Through an instance of this class you can cancel a command, an implementation of such a command periodically calls
<a href="org-netbeans-libs-git/org/netbeans/libs/git/progress/ProgressMonitor.html#isCanceled--" shape="rect">isCanceled</a> and interrupts its work if the method returns <code>true</code>.<br>
Its basic implementation at <a href="org-netbeans-libs-git/org/netbeans/libs/git/progress/ProgressMonitor.DefaultProgressMonitor.html" shape="rect">ProgressMonitor.DefaultProgressMonitor</a> supports canceling commands
while implementing other methods as no-op.
<h4>Recieve notifications</h4>
Some Git commands may take a noticeable amount of time to finish and waiting that long for the full result returned by the command may not be sufficient. Git API provides a way
to follow the process of building the result of such commands.<br>
Let's say you want to get all revisions from the Git history. The log command is expensive especially on large repositories and you do not want to wait for it to finish but want to
be notified when a single revision from the history is fetched and added to the result. This way you can <em>incrementally</em> present the result in the UI without the need for
waiting indefinitely for the command to finish.
<p>
Package <a href="org-netbeans-libs-git/org/netbeans/libs/git/progress/package-summary.html" shape="rect">org.netbeans.libs.git.progress</a> offers
a set of listeners extending the <a href="org-netbeans-libs-git/org/netbeans/libs/git/progress/NotificationListener.html" shape="rect">NotificationListener</a> interface which you can attach to an instance of
<code>GitClient</code> via <a href="org-netbeans-libs-git/org/netbeans/libs/git/GitClient.html#addNotificationListener-org.netbeans.libs.git.progress.NotificationListener-" shape="rect">addNotificationListener()</a>
and through which you can closely monitor building of the result.
</p>
<hr>
<h2>
<a name="usecase-Auto Update Services">How to use </a><a href="overview-summary.html#def-api-Auto Update Services">Auto Update Services</a>?
</h2>
<description>
<b>org.netbeans.api.autoupdate</b>
<b>org.netbeans.spi.autoupdate</b>
</description>
<p></p>
<p>
<h4>Browse all available units</h4>
Give overview of IDE installation to users, it involve overview of installed modules (grouped together as feature),
overview of available updates, overview of available new features.
The API can return list of <code>UpdateUnit</code> which describes all instances of unit, e.g. installation in IDE,
all its available updates, optionlly its backup instance.
<code>UpdateUnit</code> can represent either a feature (e.g. group
of modules), a single module or a localization.
<p></p>
<i>Proposed usage of API:</i> Call <code>List&lt;UpdateUnit&gt; UpdateManager.getDefault().getUpdateUnits()</code>
<!-- JST:UpdateManager cannot be singleton because it has mutable
state with apply method. Imho, there should be UpdateManager.create(...).
The arguments could handle various requirements, like
create(FEATURE_LEVEL) or create(DETAILED_LEVEL), etc.
-->
<h4>Browse all units by chosen style (e.g. modules, features, localization)</h4>
Sometimes there can be a need to get overview of units
by chosen style, e.g. feature, module or localization.
<p></p>
<i>Proposed usage of API:</i> Call <code>List&lt;UpdateUnit&gt; UpdateManager.getDefault().getUpdateUnits(UpdateStyle style)</code>
<h4>Browse installed modules</h4>
When an API client needs to get overview of installed modules.
<p></p>
<i>Proposed usage of API:</i> Call <code>List&lt;UpdateUnit&gt; UpdateManager.getDefault().getUpdateUnits(UpdateStyle style)</code>
and filter units which haven't been installed yet.
<!-- JST: The comment by Tonda was that this may be too slow.
This may turn true, then I suggest to have another argument
to the UpdateManager.create(...) method - "correctness":
- LOCAL - only return what is available locally
- PREFER_CACHES - if caches exists read from them, but
if not, go and connect to the websites
- EXACT - always try to get the most up-to-date info available,
e.g. do not use caches, connect to the web site
-->
<h4>Search for new functionality</h4>
Someone is searching for some functionality which can be
installed into IDE. It needs a set of available <code>UpdateUnit</code>s
which are applicable to active IDE. <code>UpdateManager</code> will
search all available <code>UpdateUnit</code> given attribute.
<a name="install-new-functionality" shape="rect"></a>
<h4>Install new functionality</h4>
An client needs to install new functionality into the IDE installation.
She knows what unit and what version wants to install.
Needs to identify if the functionality is ready to install,
resolve its dependencies, identify possible problems and locate
other unit what have to be installed together with asked functionality.
<p></p>
<i>Proposed usage of API:</i>
<ul>
<li>Client needs install NetBeans module in required minimal specification version.</li>
<li>Find corresnponing <code>UpdateUnit</code> by module's code name and finds <code>UpdateElement</code> what fits the required version.</li>
<li>So, the client now have <code>UpdateElement</code> which wants to install.</li>
<li>Take the <code>OperationContainer</code> for install, e.g. <code>OperationContainer.createForInstall</code>
</li>
<li>Adds the element into container <code>OperationContainer.add(UpdateElement)</code> and gets <code>OperationInfo</code> for that operation.</li>
<li>Identify other required elements: <code>OperationInfo.getRequiredElements()</code>
</li>
<li>Check if there is no broken dependencies: <code>OperationInfo.getBrokenDependency()</code> Note: if there are some broken dependencies then operation cannot continue.</li>
<li>If all okay, then install the unit: <code>OperationContainer.doOperation()</code>
</li>
</ul>
<h4>Update of installed unit</h4>
A client needs to update some unit of functionality which is
already installed. She knows what unit and what update element (by version) wants to install.
Needs to identify possible problems with update install, resolve its dependencies, identify possible problems and locate
other unit what have to be installed together with asked functionality.
<p></p>
<i>Proposed usage of API:</i> See above <a href="#install-new-functionality" shape="rect">Install new functionality</a>
<h4>Uninstall functionality</h4>
An client needs to uninstall some functionality from IDE installation. She knows what unit wants to uninstall.
Needs to identify if the functionality is ready to uninstall, resolve its dependencies, identify possible problems and locate
other unit what will be disabled together.
<p></p>
<i>Proposed usage of API:</i>
<ul>
<li>Client knows <code>UpdateElement</code> which wants to uninstall.</li>
<li>Take the <code>OperationContainer</code> for uninstall, e.g. <code>OperationContainer.createForUninstall</code>
</li>
<li>Adds the element into container <code>OperationContainer.add(UpdateElement)</code> and gets <code>OperationInfo</code> for that operation.</li>
<li>Identify other required elements: <code>OperationInfo.getRequiredElements()</code>
</li>
<li>If all okay, then uninstall the unit: <code>OperationContainer.doOperation()</code>
</li>
</ul>
<a name="disable-unit" shape="rect"></a>
<h4>Switch off functionality</h4>
An client needs to switch off (disable) some functionality in IDE installation. Needs to resolve its dependencies,
identify possible problems and locate other unit what will be disabled together.
<p></p>
<i>Proposed usage of API:</i>
<ul>
<li>Client knows <code>UpdateElement</code> which wants to uninstall.</li>
<li>Take the <code>OperationContainer</code> for disable, e.g. <code>OperationContainer.createForDisable</code>
</li>
<li>Adds the element into container <code>OperationContainer.add(UpdateElement)</code> and gets <code>OperationInfo</code> for that operation.</li>
<li>Identify other required elements: <code>OperationInfo.getRequiredElements()</code>
</li>
<li>If all okay, then disable the unit: <code>OperationContainer.doOperation()</code>
</li>
</ul>
<h4>Switch on functionality</h4>
Like <a href="#disable-unit" shape="rect">Switch off functionality</a> An client needs to switch on (enable) some functionality in IDE installation.
<h4>Rollback of previous update</h4>
Sometimes an client needs to rollback of installed update of unit to previous version.
Needs to resolve its dependencies, identify possible problems and locate
other unit what are affected by rollback.
<p></p>
<i>Proposed usage of API:</i> Like above <a href="#disable-unit" shape="rect">Switch off functionality</a>
<ul>
<li>Client knows <code>UpdateElement</code> which wants to uninstall.</li>
<li>Take the <code>OperationContainer</code> for enable, e.g. <code>OperationContainer.createForEnable</code>
</li>
<li>Adds the element into container <code>OperationContainer.add(UpdateElement)</code> and gets <code>OperationInfo</code> for that operation.</li>
<li>Identify other required elements: <code>OperationInfo.getRequiredElements()</code>
</li>
<li>If all okay, then enable the unit: <code>OperationContainer.doOperation()</code>
</li>
</ul>
<h4>Resolve problems what accrued while processing operation</h4>
<code>OperationContainer</code> and <code>OperationInfo</code> identifies some problems,
i.e. broken dependencies, needs to install more units, the operation causes disable some
other modules and so on. The client can use this information to consult these with end-user.
<h4>Make IDE up-to-date</h4>
Sometimes need to make whole IDE installation up-to-date. Find all available updates of installed units and install the latest available version.
It is covered by previous use-cases.
<h4>Get all subscriptions to Update Center</h4>
Show me all registered subscriptions to Update Center, e.g. get me list of <code>UpdateUnitProvider</code>.
<i>Proposed usage of API:</i> Call <code>UpdateUnitProviderFactory.getUpdateUnitProviders()</code>
<h4>Subscribe new Update Center</h4>
If there is a new Update Center which is not already subscribed into IDE user wants to subscribe new one Update
Center which will be connected from that time in periodically checks.
There should be a factory where subscribe new one Update Center, known types of Update Center have own factory method.
<i>Proposed usage of API:</i> Simply call <code>UpdateUnitProviderFactory.create()</code> which creates and registered
new one subscription in the system and will be used from that time in the future.
<h4>Customization of Update Center subscription</h4>
An user wants to enable or disable of Update Center subscription.
<i>Proposed usage of API:</i> Simply call <code>UpdateUnitProviderFactory.setEnable(UpdateUnitProvider, boolean)</code>.
<h4>Unsubscribe of some Update Center</h4>
Simple unsubscribe a chosen Update Center from the system. Need to know of chosen Update Provider Id.
This Update Center won't be checked anymore.
<i>Proposed usage of API:</i> Simply call <code>UpdateUnitProviderFactory.remove(Id)</code>.
<h4>Refresh content of subscribed Update Center</h4>
The content of Update Provider is cached and the system works across there caches. There is a cache per each
Update Center subscription. The caches are refreshed periodically by the system. But, sometime an user wants to
call refresh manually.
<i>Proposed usage of API:</i> Simply call <code>UpdateUnitProvider.refresh()</code>.
<h4>Specify the cluster where to install</h4>TBD
<h4>Get all installed files of given unit</h4>TBD
</p>
<hr>
<h2>
<a name="usecase-Auto Update UI">How to use </a><a href="overview-summary.html#def-api-Auto Update UI">Auto Update UI</a>?
</h2>
<description>
<b>AutoUpdateUI</b>
</description>
<p></p>
<h4>Download and Install</h4>
Primary purpose of the API is to share classical UI for downloading and
installing additional modules. Read about
<a href="org-netbeans-modules-autoupdate-ui/org/netbeans/modules/autoupdate/ui/api/PluginManager.html" shape="rect">PluginManager.openInstallWizard</a>.
<hr>
<h2>
<a name="usecase-Issue Tracking">How to use </a><a href="overview-summary.html#def-api-Issue Tracking">Issue Tracking</a>?
</h2>
<description>
The module allows to integrate Bugtracking systems into the IDE workflow.
</description>
<p></p>
<p>
The main Bugtracking SPI and API Use Cases are based on:<br>
- the <a href="http://xdesign-tools.cz.oracle.com/projects/netbeans/IssueTracking/" shape="rect">Bugtracking UI spec.</a>
<br>
- the <a href="http://wiki.netbeans.org/TaskManagementUseCases" shape="rect">Issue Management Use Cases</a>.
For additional information see also <a href="http://wiki.netbeans.org/TaskDashboardDesignSpec" shape="rect">Tasks Dashboard UI spec</a>
<br>
</p>
<h4>Registration and setup</h4>
The Bugtracking SPI provides a way to register bugtracking plugins and
to setup remote Repository configurations of one kind.
<h4>Accessing Issues</h4>
All registered plugins provide the capability to access Issues from a Repository via:<br>
- their ID<br>
- based on a simple text criteria<br>
- the capability to create, edit and execute more complex Queries
<h4>Issue management</h4>
For the needs of Issue Management all registered plugins provide:
- the capability to create and edit Issues<br>
- basic Issue information like id, summary, priority, scheduling ...
<h4>Automated Issue Operations</h4>
All registered plugins provide bugtracking functionality (if available)
to other IDE workflows via the Bugtracking API.
- e.g. attaching files, closing Issues, etc.
<p>
See also the more detailed <a href="http://wiki.netbeans.org/BugtrackingAPISPIUseCases" shape="rect">API/SPI requirements.</a>
</p>
<hr>
<h2>
<a name="usecase-Classfile Reader">How to use </a><a href="overview-summary.html#def-api-Classfile Reader">Classfile Reader</a>?
</h2>
<description>
The ClassFile API is designed as a fast, low memory-cost way to access classfile
information. It is useful for tools and modules that directly read classfiles,
such as the clazz and javacore modules.
</description>
<p></p>
<p>
The normal usecase is for a client wanting to inspect a classfile. A <code>ClassFile</code>
instance is created with either a <code>String</code> path, <code>File</code> or
<code>InputStream</code> instance. All attributes of the classfile are available as properties,
such as <code>getSourceFileName</code> or <code>getMethods</code>.
</p>
<hr>
<h2>
<a name="usecase-Static Analysis Core">How to use </a><a href="overview-summary.html#def-api-Static Analysis Core">Static Analysis Core</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-Database Explorer">How to use </a><a href="overview-summary.html#def-api-Database Explorer">Database Explorer</a>?
</h2>
<description>
This project provides access to objects defined in the Database Explorer.
Documentation is available in the Javadoc.
</description>
<p></p>
<h4>Registering JDBC ../db.drivers</h4>
<p>
An external module can register JDBC drivers. A typical example is a module
which provides integration with a database server. In this case the module
contains the JDBC driver for that database server and uses the Database
Explorer API to add it do the Database Explorer.
</p>
<p>
Another client of this API could be a module providing integration with a J2EE
application server. Sometimes a J2EE application server bundles a database server
for improving the out-of-the-box experience. When the server is registered
in the IDE the JDBC drivers for the bundled database server are added to the Database
Explorer.
</p>
<p>
The drivers are registered by making calls on
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/JDBCDriverManager.html" shape="rect">JDBCDriverManager</a> or
by registering an XML file which describes the driver in the module layer.
The XML file is described by the
<a href="http://www.netbeans.org/dtds/jdbc-driver-1_1.dtd" shape="rect">JDBC Driver DTD</a>.
An example of a registration file describing the JDBC driver for PostgreSQL follows:
</p>
<pre xml:space="preserve">
&lt;?xml version='1.0'?&gt;
&lt;!DOCTYPE driver PUBLIC '-//NetBeans//DTD JDBC Driver 1.0//EN' 'http://www.netbeans.org/dtds/jdbc-driver-1_0.dtd'&gt;
&lt;driver&gt;
&lt;name value='postgresql-7'/&gt;
&lt;display-name value='PostgreSQL (v7.0 and later)'/&gt;
&lt;class value='org.postgresql.Driver'/&gt;
&lt;urls&gt;
&lt;url value='file:/folder1/folder2/drivers/pg74.1jdbc3.jar'/&gt;
&lt;/urls&gt;
&lt;/driver&gt;
</pre>
<p>
This file should be registered in the <code>Databases/JDBCDrivers</code> folder of the module layer.
To addres a bundled JAR inside the IDE the nbinst protocol can be used in the URLs:
<code>nbinst:/modules/ext/bundled-driver.jar</code>.
</p>
<h4>Get the underlying JDBC Driver instance for a JDBCDriver</h4>
<p>
You can use the <a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/JDBCDriver.html#getDriver--" shape="rect">JDBCDriver.getDriver()</a>
method to obtain a reference to the underlying JDBC Driver instance. This is useful if you want to use the registered
drivers but create your own JDBC connections independent of the Database Explorer.
</p>
<h4>Retrieving the list of JDBC ../db.drivers</h4>
<p>
When creating a new connection the JDBC driver which it should use can be specified.
A list of all the registered JDBC drivers can be retrieved using
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/JDBCDriverManager.html#getDrivers--" shape="rect">JDBCDriverManager.getDrivers()</a>.
</p>
<h4>Registering database runtimes</h4>
<p>
An external module can register new database runtimes. A database runtime
is an abstraction of a database server instance
(usually bundled with the IDE, an integration module or with a J2EE server). It allows a database
server instance to be started and stopped when a connection to this
instance is made in the IDE. Database runtimes are represented by the
<a href="org-netbeans-modules-db/org/netbeans/spi/db/explorer/DatabaseRuntime.html" shape="rect">DatabaseRuntime</a>
SPI interface and are registered in the <code>Databases/Runtimes</code> of the module layer.
</p>
<h4>Creating database connections</h4>
<p>
A module can create new database connections (for example to a bundled database).
New connections can be added by calling
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/DatabaseConnection.html#create-org.netbeans.api.db.explorer.JDBCDriver-java.lang.String-java.lang.String-java.lang.String-java.lang.String-boolean-" shape="rect">DatabaseConnection.create()</a>
to create a new DatabaseConnection instance and then
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/ConnectionManager.html#addConnection-org.netbeans.api.db.explorer.DatabaseConnection-" shape="rect">ConnectionManager.addConnection()</a> to
add the connection to the Database Explorer.
</p>
<p>
New connections can also be added by registering them in the module layer.
The format of the registration file is described by the
<a href="http://www.netbeans.org/dtds/connection-1_0.dtd" shape="rect">Database Connection DTD</a>.
An example of a registration file describing a connection to a PostgreSQL database follows:
</p>
<pre xml:space="preserve">
&lt;?xml version='1.0'?&gt;
&lt;!DOCTYPE connection PUBLIC '-//NetBeans//DTD Database Connection 1.1//EN' 'http://www.netbeans.org/dtds/connection-1_1.dtd'&gt;
&lt;connection&gt;
&lt;driver-class value='org.postgresql.Driver'/&gt;
&lt;driver-name value='postgres-7'/&gt;
&lt;database-url value='jdbc:postgresql:test'/&gt;
&lt;schema value='public'/&gt;
&lt;user value='test'/&gt;
&lt;password value='cGFzc3dvcmQ='/&gt;
&lt;/connection&gt;
</pre>
<p>
This file should be registered in the <code>Databases/Connections</code> folder
of the module layer.
</p>
<p>
The password element is optional, but if it is included,
its value must be the Base64 encoding of the UTF-8 representation of the
password. Note that the UTF-8 representation of passwords composed entirely of
ASCII characters is the same as their ASCII representation, so for such
passwords all that needs to be done is to convert them to Base64.
</p>
<p>
Base64 encoding serves as a simple scrambling to prevent
accidental revelation of the password. It is not indended to offer any
real security. You can protect the password by assigning appropriate
file protections to the connection XML file.
</p>
<h4>Retrieving and displaying the list of database connections</h4>
<p>
Sometimes the list of connections needs to be displayed somewhere
else in the IDE than the Runtime tab. A typical example is the SQL Editor,
which allows the user to select the database connection which the SQL statement
will be executed against in a combo box in the editor toolbar.
The list of connections can be obtained by calling
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/ConnectionManager.html#getConnections--" shape="rect">ConnectionManager.getConnections()</a>,
which returns an array of
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/DatabaseConnection.html" shape="rect">DatabaseConnection</a>
instances.
</p>
<p>
The client usually needs to show the display name of the connection. The
display name can be retrieved using the
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/DatabaseConnection.html#getDisplayName--" shape="rect">DatabaseConnection.getDisplayName()</a>
method.
</p>
<h4>Retrieving the properties of database connections</h4>
<p>
Sometimes a client needs to retrieve the connection properties, such as the driver class.
An example could be a module for a J2EE server creating a connection pool. The properties can
be retrieved using the <code>getDriverClass()</code>, <code>getDatabaseURL()</code>,
<code>getSchema()</code>, <code>getUser()</code> and <code>getPassword()</code>
methods of the
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/DatabaseConnection.html" shape="rect">DatabaseConnection</a>
class.
</p>
<h4>Showing the New Database Connection dialog</h4>
<p>
Usually when displaying a list of connections (usually in a combo box),
the last item is "New Connection", which displays the standard New Database Connection
dialog of the Database Explorer. This can be achieved by calling one of the
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/ConnectionManager.html#showAddConnectionDialog-org.netbeans.api.db.explorer.JDBCDriver-" shape="rect">ConnectionManager.showAddConnectionDialog()</a> methods.
</p>
<h4>Remove a database connection</h4>
<p>
A user of this API may want to remove a connection from the list of connections
registered by the Database Explorer. This is done using
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/ConnectionManager.html#removeConnection-org.netbeans.api.db.explorer.DatabaseConnection-" shape="rect">ConnectionManager.removeConnection()</a>
</p>
<h4>Connecting to a database</h4>
<p>
A component which provides database functionality (such as the SQL Editor)
will need to connect to a database. This can be achieved using the
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/ConnectionManager.html#showConnectionDialog-org.netbeans.api.db.explorer.DatabaseConnection-" shape="rect">DatabaseConnection.showConnectionDialog()</a>
method and the <code>java.sql.Connection</code> instance can be retrieved using the
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/DatabaseConnection.html#getJDBCConnection--" shape="rect">getJDBCConnection()</a>
method.
</p>
<p>
If you want to connect to the database without showing a dialog or any kind of UI, you can use the
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/ConnectionManager.html#connect-org.netbeans.api.db.explorer.DatabaseConnection-" shape="rect">DatabaseConnection.connect()</a>
method.
</p>
<h4>Test a database connection for validity</h4>
<p>
You may want to test to make sure the underlying physical JDBC connection
obtained from a DatabaseConnection is either valid or null. This is done using the
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/DatabaseConnection.html#getJDBCConnection-boolean-" shape="rect">
DatabaseConnection.getJDBCConnection(boolean test)</a>
method, which validates the underlying connection before returning it. If the
connection is invalid, it marks the DatabaseConnection as disconnected and returns null.
</p>
<h4>Displaying the database connections in the UI</h4>
<p>
A component which provides database functionality (such as the SQL Editor
or a module providing support for data sources) will need to let the user
select the a database connection, usually through a combo box.
This can be achieved using the
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/support/DatabaseExplorerUIs.html#connect-javax.swing.JComboBox-org.netbeans.api.db.explorer.ConnectionManager-" shape="rect">DatabaseExplorerUIs.connect()</a>
method. The <code>JComboBox</code> passed to the method will be filled with the list of connections as returned by
<a href="org-netbeans-modules-db/org/netbeans/api/db/explorer/ConnectionManager.html#getConnections--" shape="rect">ConnectionManager.getConnections()</a>, followed by a separator
and a <em>New Database Connection</em> item which will display the dialog for adding a new database connection when selected.
</p>
<h4>Drag and drop support for database objects</h4>
<p>
A component might need to allow database tables from the Database Explorer to
be dragged to a visual editor. An API is provided in <code>DatabaseMetaDataTransfer</code>
containing <code>DataFlavor</code>s for database objects and nested classes
encapsulating those database objects during a drag and drop transfer.
</p>
<h4>Get support for working with SQL identifiers</h4>
<p>
A component might need support for working with SQL identifiers. In particular,
it's important to know when to quote a SQL identifier. The
<a href="org-netbeans-modules-db/org/netbeans/api/db/sql/support/SQLIdentifiers.Quoter.html" shape="rect">
SQLIdentifiers.Quoter</a> class is provided for this.
</p>
<hr>
<h2>
<a name="usecase-Diff">How to use </a><a href="overview-summary.html#def-api-Diff">Diff</a>?
</h2>
<description>
The diff module provides the ability to visualize differences between source files.
It also has a graphical conflicts resolver tool and built-in patch algorithm.
List of the main features:
Simple APIs, that provide access to registered diff and merge engines and visualizers.
Built in and external diff engines defined.
Graphical diff vizualizer and conflicts resolver.
Extensible with additional diff and merge engines and vizualizers.
Patch algorithm implemented for UNIX-style, unidiff and contextual diff formats.
</description>
<p></p>
<h4>Show a diff from action</h4>
<p>
From an action or wherever you like you can call this:
</p>
<pre xml:space="preserve">
public void diff(final StreamSource local, final StreamSource remote){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
<a href="org-netbeans-modules-diff/org/netbeans/api/diff/DiffView.html" shape="rect">DiffView</a> view = <a href="org-netbeans-modules-diff/org/netbeans/api/diff/Diff.html" shape="rect">Diff</a>.getDefault().createDiff(local, remote);
showDiff(view);
} catch (IOException ex) {
Logger.getLogger(ThisClass.class.getName()).throwing(ex);
}
}
});
}
public void showDiff(final <a href="org-netbeans-modules-diff/org/netbeans/api/diff/DiffView.html" shape="rect">DiffView</a> view){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//create our panel with our view
//right now I am just going to use the diff component
// instead of a panel
//create a topcomponent with our panel
DiffTopComponent tc = new DiffTopComponent(view);
tc.setName("MY_DIFF");
tc.setDisplayName("Some display name");
tc.open();
tc.requestActive();
}
});
}
</pre>
<h4>Embeded into TopComponent</h4>
<p>
Here is a top component to display it:
</p>
<pre xml:space="preserve">
public class DiffTopComponent extends <a href="./org-openide-windows/org/openide/windows/TopComponent.html" shape="rect">TopComponent</a> {
&nbsp; &nbsp; /** Creates a new instance of DiffTopComponent */
&nbsp; &nbsp; public DiffTopComponent(Component diffPanel) {
&nbsp; &nbsp; &nbsp; &nbsp; setLayout(new BorderLayout());
&nbsp; &nbsp; &nbsp; &nbsp; add(diffPanel, BorderLayout.CENTER);
getAccessibleContext().setAccessibleName(
NbBundle.getMessage(DiffTopComponent.class,
"ACSN_Diff_Top_Component")); // NOI18N
&nbsp; &nbsp; &nbsp; &nbsp;
getAccessibleContext().setAccessibleDescription(
NbBundle.getMessage(DiffTopComponent.class,
"ACSD_Diff_Top_Component")); // NOI18N
&nbsp; &nbsp; }
&nbsp; &nbsp;
&nbsp; &nbsp; public DiffTopComponent(DiffView view) {
&nbsp; &nbsp; &nbsp; &nbsp; this(view.getComponent());
&nbsp; &nbsp; }
&nbsp; &nbsp; public int getPersistenceType(){
&nbsp; &nbsp; &nbsp; &nbsp; return TopComponent.PERSISTENCE_NEVER;
&nbsp; &nbsp; }
&nbsp; &nbsp; protected String preferredID(){
&nbsp; &nbsp; &nbsp; &nbsp; return "DiffTopComponent"; &nbsp; &nbsp;//NOI18N
&nbsp; &nbsp; }
&nbsp; &nbsp; public HelpCtx getHelpCtx() {
&nbsp; &nbsp; &nbsp; &nbsp; return new HelpCtx(getClass());
&nbsp; &nbsp; }
}
</pre>
<hr>
<h2>
<a name="usecase-Editor Module">How to use </a><a href="overview-summary.html#def-api-Editor Module">Editor Module</a>?
</h2>
<description>
The editor module provides a full-featured source text editor
that is integrated with the Form Editor, Explorer, compiler, and debugger.
List of the main features:
Syntax highlighting of java, HTML, XML and other languages.
Code Completion enables to type a few characters
and then display a list of suggestions appropriate
in the given context that can be then used
to automatically complete the expression.
Word Matching enables enables to type the beginning characters
of a word used elsewhere in the code and then have the editor
generate the rest of the word.
Abbreviations allow to expand typed text from a few
predefined characters into a full word or phrase.
Goto Class enables to open a Java file in the Source Editor
by typing only the class name.
The IDE helps to identify the correct package name for the class.
The Fast Import feature enables to quickly add import statements
for Java classes in the source file.
Goto Declaration feature allows to quickly jump to a declaration
of a variable under the cursor.
Goto Source allows to open source file containing
definition of a type that the variable under the cursor is of.
Code folding allows to collapse sections of the code that are
unimportant to the user at the given time.
For example in java source the collapsable sections include
imports section, inner classes, methods and javadocs.
</description>
<p></p>
No answer
<hr>
<h2>
<a name="usecase-Editor Braces Matching">How to use </a><a href="overview-summary.html#def-api-Editor Braces Matching">Editor Braces Matching</a>?
</h2>
<description>
The Braces Matching SPI allows modules providing editor support for documents
to create their own BracesMatchers that are tailored for the type of documents they
support. The module itself provides an infrastructure for
highlighting matching areas identified by a matcher and navigating between them.
</description>
<p></p>
<p>
Although the SPI can generally by used for highlighting areas in a document
that have something in common, the usecases below are demonstrated on a simple
braces matching example. This example is used for its simplicity and clarity,
but it could be substituted by more complex examples.
</p>
<p>
The usecases listed here were heavily inspired by comments in issues
<a href="http://www.netbeans.org/issues/show_bug.cgi?id=95126" shape="rect">95126</a> and
<a href="http://www.netbeans.org/issues/show_bug.cgi?id=66037" shape="rect">66037</a>.
</p>
<h4>Usecase 1. - Highlighting results</h4>
<p>
Probably the main reason why this SPI exists is to allow Netbeans editor to
highlight matching braces in a document. The highlighting itself is done by the
infrastructure and is not of a concern for <code>BracesMatcher</code> implementors.
It should be possible to highlight independently
(ie. in a different color) both the original brace and the matching brace. It should also
be possible to highlight the original brace in a special color when its matching
brace can't be found. The colors obviously have to be customizable by users.
</p>
<h4>Usecase 2. - Navigating between results</h4>
<p>
If the original brace is detected and its matching brace is found Netbeans editor
needs to allow an easy navigation between those two positions (ie. jumping
from the original brace to the matching one and back).
</p>
<p>
In general if there is more than one matching area users should be allowed to cycle
through all of them. Since there is only one editor action (shortcut) for navigating
between matching areas the cycling is only done in one direction (backward). In
order for cycling to work properly the <code>BracesMatcher</code> implementation has to report
matching areas in a consistent way. That is the matching areas should always be
sorted by their position in a document, starting with the one at the lowest offset.
</p>
<h4>Usecase 3. - Different search scenarios</h4>
<p>
The users are likely to have different preferences for the way how braces matching
works therefore its behavior should be customizable. We have listed below several
possible scenarios that can be used simply by setting different values for the
search parameters described before. They all differ in the way how the original
area is detected.
</p>
<p>
The shortcuts for the parameters have the following meaning - <code>MBL</code>
... max backward lookahead, <code>MFL</code> ... max forward lookahead,
<code>SD</code> ... search direction, <code>CB</code> ... caret bias. The values
are <code>B</code> ... backward or backward preferred and
<code>F</code> ... forward or forward preferred. The question mark <code>?</code>
means that the value of this parameter has no effect for the search.
</p>
<ul style="list-style-type : upper-alpha">
<li>
<a name="search-scenario-A" shape="rect"><code>MBL = 0, MFL = 0, SD = ?, CB = F</code></a> : Check only the right hand side
character of the caret. This is the default for Netbeans overwrite mode (ie. the
block shaped caret).
</li>
<li>
<a name="search-scenario-B" shape="rect"><code>MBL = 1, MFL = 1, SD = ?, CB = B</code></a> : Check characters right next to
the caret on both its sides. This is the default for Netbeans normal mode (ie.
the I-beam shaped caret).
</li>
<li>
<code>MBL = 0, MFL = 256, SD = F, CB = B</code> : Check the character on the
left hand side of the caret, otherwise search forward. This is the default
for jVi insert mode.
</li>
<li>
<code>MBL = 0, MFL = 256, SD = F, CB = F</code> : Search forward from the caret.
This is the default for jVi command mode.
</li>
<li>
<code>MBL = 256, MFL = 256, SD = F, CB = B</code> : Check the left hand side
character, otherwise search forward first and then backward. Suitable for
I-beam carets that detect the original area anywhere on the line with the
caret giving preferrence to the area positioned forward from the caret. The
preferrence for the backward positioned area can simply be achieved by changing
the search direction (ie. <code>SD = B</code>).
</li>
<li>
<code>MBL = 256, MFL = 256, SD = F, CB = F</code> : The same as
option E, but for the block carets.
</li>
</ul>
<h4>Usecase 4. - Auto-switching the search scenario</h4>
<p>
The editor in Netbeans can operate in two modes - normal and overwrite. They both
use different shape of a caret and thus need a different caret bias. The braces
matching infrastructure should detect what mode the editor is in and change the
parameters used for searching for the original area accordingly. The caret bias
is the most important parameter, but other parameters may need to be changed too.
</p>
<p>
This feature should of course be only active for text components where the parameters
have not been overwritten by some other module.
</p>
<p>
By default the two search scenarios used for the normal and overwrite modes in
Netbeans editor are the <a href="#search-scenario-B" shape="rect">scenario B</a> for the normal
mode and <a href="#search-scenario-A" shape="rect">scenario A</a> for the overwrite mode. In
general scenarios from both editor modes should be customizable by users.
</p>
<hr>
<h2>
<a name="usecase-Editor Code Templates">How to use </a><a href="overview-summary.html#def-api-Editor Code Templates">Editor Code Templates</a>?
</h2>
<description>
Code Templates allow to paste various code snippets by using parametrized text.
The parameters of the same name will share the same default value and if that value
gets changed by user's typing the new value gets replicated into all the parameter's
occurrences.
Code Templates replace the original abbreviations functionality.
Code template's example
for (Iterator ${iterator} = ${collection instanceof="java.util.Collection"}.iterator(); ${iterator}.hasNext();) {
${cursor}${iterator}.next();"
}
Each parameter can have additional hints of what values
can be assigned to it.
The hint has a form
${param hint=value}
or just
${param hint}
which translates to
${param hint="true"}
If necessary the value of the hint can be enclosed
in quotes to allow to write whitespace or { or }
into the value. The quote can be written by using \".
Reserved parameter names
${cursor} defines position where the caret will be located
after the editing of the code template default values will finish.
Reserved hint names
${param editable=false} can be used to make the parameter to be skipped
from user's editing. This may be useful e.g. with using java-specific type
hint (described below).
Java:
${ind index} defines that the default value of the parameter
should be an unused variable in the given context named i.
If i is already used then j is attempted
or then k etc. until z.
Then i0, i1 etc. are attempted.
${param type="java.util.Collection"} defines
java type that the parameter must be instance of.
Besides class names there can be array e.g. String[]
or generics java.util.List&lt;String&gt;
${param array} defines parameter of array type (including
arrays of primitive data types).
${param type="java.util.Iterator"} defines
that the parameter has the given java type. The template processing infrastructure
will use short name Iterator and import java.util.Iterator.
</description>
<p></p>
<h4>Code Template Parameters</h4>
One of the main benefits of the code templates is their parametrization
which allows to substitute the default values for the parameters
before the final insertion and it also allows the user to modify
these default values explicitly after the code template gets inserted
into the document.
<br>
The parameters are marked in the code template's text by <code>${...}</code>.
<br>
Parameters of the same name benefit from automatic replication. Once the template
gets pasted into the document all the parameter's occurrences
get replaced by parameter's default value.
<br>
The first parameter's occurrence gets selected.
<br>
The user can now replace the default value. If the user does so the new value
gets replicated to all the other occurrences of this parameter automatically.
<h4>Mime-type specific operation</h4>
Each code template needs to find the default values for its parameters
before it gets inserted into the text.
<br>
Sometimes it's enough to just specify the default value in the template's text
but usually the default value gets determined from the context of insertion.
<br>
There is an intent to create a mime-type specific code template processor
that would be registered per mime-type. There could be even more than one
such processors processing the template in a specific order.
<h4>Parameter hints</h4>
Besides parameter's name the template processors may need additional
hints of how to find a default value for the parameter.
<br>
For example java code template's parameter may be an <code>index</code>
parameter which means that the infrastructure should fill in
a fresh index variable e.g. <code>i</code>.
<br>
Or the parameter can only be of a certain java type such
as in the case of iterating through a collection
the type must be subtype of <code>java.util.Collection</code>.
<br>
These requirements could be specified as additional hints
to the parameters e.g. <code>${i index}</code>
or <code>${c instanceof=java.util.Collection}</code>.
<br>
The hints allow string literals to support arbitrary
explicit default values specifications
e.g. <code>${x default="Hello world"}</code>.
<br>
The '{' and '}' have no special meaning inside the string literal.
<br>
The '"' char is allowed to be used by escaping
<code>${x default="\"quoted string\""}</code>.
<h4>Temporary Code Templates</h4>
The Code Completion functionality allows to build temporary
Code Templates functionality if it could build a temporary template
for completing of the method parameters. The parameters could
be completed one by one by tabbing and the Code Templates framework
would fill in proper default values just like it does for regular templates.
<pre xml:space="preserve">
JTextComponent pane = ...
String tempCodeTemplateText = ...
CodeTemplate ct = CodeTemplateManager.get(pane.getDocument()).createTemporary(tempCodeTemplateText);
ct.insert(pane);
</pre>
<h4>Insert Text Building and Updating</h4>
The parametrized text of the code template first gets parsed
and the parameters get their default values which by default are
the names of the parameters.
The code template processor are then called to update this default
value.
<br>
The new java infrastructure being developed would benefit
from the possibility to obtain the full string containing
the skeleton of the code template (without parameters)
with the present default values. It can take that string
and locally parse it to find out types of local variables
used in the particular template and fill in dependent
variable types.
<h4>Parameter Editability</h4>
Certain part of the code template may change text but it should
not be edited by the user. For example when iterating over collection
given as a parameter the collection may be generics-ed
by additional type. The iterator's variable type then also
needs to generics-ed with the same type.
<br>
The iterator's type parameter should not be editable because
this operation may be done automatically
by the java code template processor.
<br>
There should be a hint <code>editable</code> having
<code>true</code>/<code>false</code>.
<hr>
<h2>
<a name="usecase-Editor Code Completion">How to use </a><a href="overview-summary.html#def-api-Editor Code Completion">Editor Code Completion</a>?
</h2>
<description>
Code Completion provides users with a list of suggested completions for partially typed texts in the editor and various dialog input fields.
The Code Completion module was created to replace
the original legacy editor code completion which
lacked several key requirements:
Support for multiple independent code completion content providers.
Implied requirement for ordering and prioritization of the completion items.
Direct support for asynchronous completion result computation.
Missing separation to the API and SPI and implementation parts.
</description>
<p></p>
<h3>API</h3>
<h4>Show or hide completion window</h4>
<p>
The API is small and it only allows to explicitly show or hide the completion window.
<br>
It's being used by code templates that need to explicitly show the code completion
window when tabbing to a particular parameter.
<br>
There may be certain actions that want to ensure that the code completion is hidden
at the time when they are invoked. For example the actions pasting the content
of the completion item into the document.
</p>
<h3>SPI</h3>
<h4>Provide completion content by independent providers</h4>
<p>
Completion infrastructure needs to obtain the results that are then displayed
in the completion window.
<br>
There are three types of displayed results related to the current caret offset:
</p>
<ul>
<li>
Code completion items
</li>
<li>
Documentation (e.g. the javadoc documentation)
</li>
<li>
Tooltip (e.g. for method parameters)
</li>
</ul>
<p>
For the purpose of obtaining these completion results
<a href="org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionProvider.html" shape="rect">
CompletionProvider</a>
exists.
<br>
There may be an arbitrary number of independent completion providers for
a single completion popup window.
<br>
The completion providers are registered through the xml layer into
<i>Editors/&lt;mime-type&gt;/CompletionProviders</i>. Once the document
with the particular mime-type gets loaded the corresponding completion providers
will get instantiated and used.
</p>
<p>
Threading:
<br>
The code completion's infrastructure invokes the requests
for the completion results in the AWT thread.
<br>
Therefore all the methods of the completion providers are invoked
in AWT thread but they may reschedule their processing into other threads.
</p>
<h4>Provide completion results computed asynchronously</h4>
<p>
The completion provider creates a task that computes the resulting
data that will then be displayed by the code completion infrastructure.
<br>
The task creation and computation are called synchronously
from the AWT event dispatch thread.
<br>
However there can be potentially long-running tasks (e.g. working with MDR)
that are not desirable to be run in AWT thread.
<br>
Therefore the completion infrastructure provides a listener
to which the completion task notifies the results.
<br>
The support class
<a href="org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/support/AsyncCompletionTask.html" shape="rect">
AsyncCompletionTask</a> allows to post the task computation
into <code>RequestProcessor</code>.
</p>
<h4>Provide list of completion items fulfilling various requirements</h4>
<p>
The completion task computes a collection of completion items
which are then collected by the completion infrastructure and displayed.
<br>
<b>Displaying</b>. Each completion item must be able to display itself in a <code>JList</code>.
<br>
<b>Sorting</b>. The completion items may come from different completion providers
and they must be sorted before displaying. The sort order
should not only be alphabetical but it should also allow a prioritization
of the items according to their importance in the given context.
<br>
<b>Actions</b>. The interaction of the user with the completion item
is done by interacting with item's input map and action map.
<br>
<b>Documentation</b>. The item may want to display additional
detailed information in a documentation popup window.
</p>
<hr>
<h2>
<a name="usecase-Editor Error Stripe">How to use </a><a href="overview-summary.html#def-api-Editor Error Stripe">Editor Error Stripe</a>?
</h2>
<description>
The Error Stripe shows an overview of important information of an edited source code.
It shows this information for the whole source code (regardless of its size).
</description>
<p></p>
<h4>Augment Annotations to be shown in the Error Stripe</h4>
Use the <api category="stable" group="java" name="TextAPI" type="export" url="./org-openide-text/overview-summary.html">OpenIDE Text API</api>.
<h4>Provide Up-to-date Status for the Error Stripe</h4>
<p>A module in the IDE has information whether data shown in the Error Stripe
is up-to-date or not. The Error Stripe may change the appearance according to this knowledge.
</p>
<p>Implement the <a href="org-netbeans-modules-editor-errorstripe-api/org/netbeans/spi/editor/errorstripe/UpToDateStatusProvider.html" shape="rect">UpToDateStatusProvider</a>
that provides up-to-date status. Be sure that it fires PropertyChangeEvent when this status is changed.</p>
<p>Implement the <a href="org-netbeans-modules-editor-errorstripe-api/org/netbeans/spi/editor/errorstripe/UpToDateStatusProviderFactory.html" shape="rect">UpToDateStatusProviderFactory</a>
that creates an instance of your UpToDateStatusProvider for a given JTextComponent and install it as described
<a href="org-netbeans-modules-editor-errorstripe-api/org/netbeans/spi/editor/errorstripe/UpToDateStatusProviderFactory.html" shape="rect">here</a>.</p>
<!-- <usecase id="registration" name="MIME Type Based Registration">
<p>An UpToDateStatusMarkProvider may provide information that can be applied to any editor type, or it may
provide infromation that applies only to a very specific type of editor.
</p>
</usecase>-->
<hr>
<h2>
<a name="usecase-Editor Code Folding">How to use </a><a href="overview-summary.html#def-api-Editor Code Folding">Editor Code Folding</a>?
</h2>
<description>
The Code Folding is part of the editor module functionality and it's responsible for hiding of the portions
of the code that are less important for the user at the given time.
</description>
<p></p>
<h2>
API Use Cases
</h2>
<h3>
Exploring of the Folds
</h3>
<p>
The code folding structure (fold hierarchy) relates
to <code>javax.swing.JTextComponent</code> instance in one-to-one relationship.
<br>
To find the code folding hierarchy instance for the given non-null text component
the following code snippet can be used:
</p>
<pre xml:space="preserve">
JTextComponent editorComponent = ...
FoldHierarchy hierarchy = FoldHierarchy.get(editorComponent);
</pre>
<h3>
Explore the Folds Hierarchy
</h3>
<p>
The tree-based hierarchy has one non-removable and non-collapsable root fold
that covers the whole document. It can be obtained by
</p>
<pre xml:space="preserve">
FoldHierarchy foldHierarchy = ...
Fold rootFold = hierarchy.getRootFold();
</pre>
<p>
The children folds of the root fold (or children folds)
can be obtained by
</p>
<pre xml:space="preserve">
// the hierarchy must be locked prior exploration or manipulation
hierarchy.lock();
try {
Fold rootFold = ...
int foldCount = rootFold.getFoldCount();
for (int i = 0; i &lt; foldCount; i++) {
Fold childFold = rootFold.getFold(i);
}
} finally {
hierarchy.unlock();
}
</pre>
<p>
Index of the child in its parent can be found by
</p>
<pre xml:space="preserve">
hierarchy.lock();
try {
Fold rootFold = ...
int foldIndex = rootFold.getFoldIndex(childFold);
} finally {
hierarchy.unlock();
}
</pre>
<h3>
Collapse Nearest Fold
</h3>
<p>
In the given fold hierarchy find the nearest fold right at or after the given offset
and collapse it.
</p>
<pre xml:space="preserve">
hierarchy.lock();
try {
Fold fold = FoldUtilities.findNearestFold(hierarchy, offset);
hierarchy.collapse(fold);
} finally {
hierarchy.unlock();
}
</pre>
<h3>
Expand All Folds
</h3>
<p>
In the given fold hierarchy expand all folds that are currently collapsed.
</p>
<pre xml:space="preserve">
FoldUtilities.expand(hierarchy, null);
</pre>
<h3>
Collapse All Folds of Certain Type
</h3>
<p>
In the given fold hierarchy collapse all e.g. javadoc folds that are currently collapsed.
<br>
The example can be generalized to any fold type.
</p>
<pre xml:space="preserve">
FoldUtilities.collapse(hierarchy, JAVADOC_FOLD_TYPE);
</pre>
<h3>
Start Listening on Fold Hierarchy Changes
</h3>
<p>
In the given fold hierarchy start to listen on all changes
done in the hierarchy.
<br>
This is actually used e.g. in the Editor's View Hierarchy that needs
to refresh views based on the fold changes.
</p>
<pre xml:space="preserve">
hierarchy.addFoldHierarchyListener(new FoldHierarchyListener() {
public void foldHierarchyChanged(FoldHierarchyEvent evt) {
// Hierarchy does not need to be locked here
//
// evt.getAffectedStartOffset() and getAffectedEndOffset()
// give text area affected by the fold changes in the event
}
});
</pre>
<h3>
Inspect Collapsed Folds in Affected Area
</h3>
<p>
Listen on the hierarchy changes
and refresh the views in the text area affected by the fold change.
<br>
Inspect the collapsed folds in the affected area
because special views need to be created for the collapsed folds.
<br>
The actual code in the View Hierarchy is somewhat different
but the one given here is more descriptive.
</p>
<pre xml:space="preserve">
hierarchy.addFoldHierarchyListener(new FoldHierarchyListener() {
public void foldHierarchyChanged(FoldHierarchyEvent evt) {
for (Iterator collapsedFoldIterator
= FoldUtilities.collapsedFoldIterator(hierarchy,
evt.getAffectedStartOffset(),
evt.getAffectedEndOffset()
);
it.hasNext();
) {
Fold collapsedFold = (Fold)it.next();
// Create special view for the collapsedFold
}
}
});
</pre>
<h2>
SPI Use Cases
</h2>
<h3>
Create a New Fold Manager
</h3>
<p>
Manipulation of the folds is designed to be done by fold managers.
<br>
Those classes implement <code>FoldManager</code> interface in the SPI.
<br>
At initialization time they are given instance of <code>FoldOperation</code>
through which they can create, add or remove the fold instances.
</p>
<p>
To create and use a new <code>FoldManager</code> instance
it's necessary to
</p>
<ul>
<li> Define the class of the FoldManager.
<pre xml:space="preserve">
public class MyFoldManager implements FoldManager { // or extends AbstractFoldManager
...
}
</pre>
</li>
<li> Create FoldManagerFactory for the FoldManager.
<pre xml:space="preserve">
public class MyFoldManager ...
...
public static final class Factory implements FoldManagerFactory {
public FoldManager createFoldManager() {
return new MyFoldManager();
}
}
}
</pre>
</li>
<li> Register FoldManagerFactory into xml layer into the directory
"Editors/&lt;mime-type&gt;/FoldManager/"
</li>
<li> Enable Code Folding in editor's Settings initializer
(please see e.g. <code>NbJavaSettingsInitializer</code>)
<pre xml:space="preserve">
public class MySettingsInitializer ...
public void updateSettingsMap(Class kitClass, Map settingsMap) {
...
settingsMap.put(SettingsNames.CODE_FOLDING_ENABLE, Boolean.TRUE);
}
}
</pre>
</li>
</ul>
<h3>
Create a New Fold by Fold Manager
</h3>
<p>
Create a new fold and add it to the hierarchy. The operation
is performed by the fold manager either at initialization phase
(in the <code>initFolds()</code> which gets called automatically
by the infrastructure) or at any other time when the fold manager's
operation gets invoked (usually by a listener that the fold manager
attaches to be notified about changes that can cause the folds structure
to be changed - e.g. a parsing listener for java folds).
</p>
<p>
Operations that manipulate the hierarchy are done
in terms of a valid transaction over the fold hierarchy.
<br>
Transactions allow to fire the collected changes as a single
<code>FoldHierarchyEvent</code> at the time when they are committed.
</p>
<pre xml:space="preserve">
// In the FoldManager's context
FoldOperation operation = getOperation();
FoldHierarchyTransaction transaction = operation.openTransaction();
try {
Fold fold = operation.createFold(...);
operation.addFoldToHierarchy(fold, transaction);
} finally {
transaction.commit();
}
</pre>
<h3>
Remove Fold from Hierarchy by Fold Manager
</h3>
<p>
Remove the existing fold from the hierarchy
</p>
<pre xml:space="preserve">
// In the FoldManager's context
FoldOperation operation = getOperation();
FoldHierarchyTransaction transaction = operation.openTransaction();
try {
Fold fold = ...
operation.removeFoldFromHierarchy(fold, transaction);
} finally {
transaction.commit();
}
</pre>
<h3>Updating Fold hierarchy</h3>
In the preceding cases, maintaining Folds was the FoldManager's responsibility. The FoldManager typically
held a copy of the Folds added to the hierarchy, and during the refresh, it compared them to the new data
and decided what folds to remove.
For simple cases, which only create/remove folds based on text positions, part of the work can be offloaded to the
FoldOperation:
<pre xml:space="preserve">
// create new fold positional information for all folds.
Collection&lt;FoldInfo&gt; newInfos = ...;
// create FoldInfo for each of the fold
newInfos.add(
FoldInfo.range(start, end, type).
withTemplate(customTemplate).
withDescription(veryCustomDescription).
collapse(true)
);
// the hierarchy must be locked prior to update
doc.readLock();
hierarchy.lock();
try {
operation.update(newInfos, null, null);
} finally {
}
</pre>
The <code>update()</code> operation performs a diff, creates new folds, discards old ones, and updates the folds, which
prevailed.
<h3>Accessing folds</h3>
Instead of keeping a copy of created folds, the FoldManager may call <code>operation.foldIterator</code>. The iterator
will enumerate all folds, including (recursively) blocked ones.
<hr>
<h2>
<a name="usecase-Editor Guarded Sections">How to use </a><a href="overview-summary.html#def-api-Editor Guarded Sections">Editor Guarded Sections</a>?
</h2>
<description>
Guarded Sections protects user from modifying document content. The main goal is
to simplify work with such a content to module writers and preserve created
sections.
</description>
<p></p>
<p>
<h4>Add new section</h4>
In order to add a new section after the existing section, which seems to be most frequent, use:
<pre xml:space="preserve">
String sectionName = ...;
StyledDocument doc = ...;
GuardedSectionManager guards = GuardedSectionManager.getInstance(doc);
GuardedSection g = guards.findSimpleSection(sectionName);
guards.createSimpleSection("new_name", doc.createPosition(g.getEndPosition().getOffset() + 1));
</pre>
<h4>Delete existing section</h4>
<pre xml:space="preserve">
StyledDocument doc = ...;
GuardedSectionManager guards = GuardedSectionManager.getInstance(doc);
GuardedSection g = guards.findSimpleSection("sectionName");
g.deleteSection();
</pre>
<h4>Plug guarded sections stuff into the editor</h4>
In case you want your <code>CloneableEditorSupport</code> to provide
guarded sections you should implement the <code>GuardedEditorSupport</code>
interface.
<pre xml:space="preserve">
private final class MyGuardedEditor implements GuardedEditorSupport {
...
}
</pre>
Further implement reading and writing of existing sections.
<pre xml:space="preserve">
protected void loadFromStreamToKit(StyledDocument doc, InputStream stream, EditorKit kit) throws IOException, BadLocationException {
if (guardedEditor == null) {
guardedEditor = new MyGuardedEditor();
// remember the provider
String mimeType = ((CloneableEditorSupport.Env) this.env).getMimeType();
guardedProvider = GuardedSectionsFactory.find(mimeType).create(guardedEditor);
}
// load content to kit
if (guardedProvider != null) {
guardedEditor.setDocument(doc);
Charset cs = FileEncodingQuery.getEncoding(this.getDataObject().getPrimaryFile());
Reader reader = guardedProvider.createGuardedReader(stream, cs);
try {
kit.read(reader, doc, 0);
} finally {
reader.close();
}
} else {
kit.read(stream, doc, 0);
}
}
protected void saveFromKitToStream(StyledDocument doc, EditorKit kit, OutputStream stream) throws IOException, BadLocationException {
if (guardedProvider != null) {
Charset cs = FileEncodingQuery.getEncoding(this.getDataObject().getPrimaryFile());
Writer writer = guardedProvider.createGuardedWriter(stream, cs);
try {
kit.write(writer, doc, 0, doc.getLength());
} finally {
writer.close();
}
} else {
kit.write(stream, doc, 0, doc.getLength());
}
}
</pre>
Your module should also require a proper implementation. In case of java
content add to your module manifest file:
<pre xml:space="preserve">
OpenIDE-Module-Requires: org.netbeans.api.editor.guards.Java
</pre>
</p>
<hr>
<h2>
<a name="usecase-Editor Indentation">How to use </a><a href="overview-summary.html#def-api-Editor Indentation">Editor Indentation</a>?
</h2>
<description>
Editor indentation performs reindentation and code beautification of Swing document.
</description>
<p></p>
<h1>
API Usecases
</h1>
<h3>
Fix indentation of a single or multiple lines of a document.
</h3>
<p>
Altghough there are formatting actions already there may be clients
wishing to explicitly fix indentation of e.g. a newly inserted code into a Swing document.
</p>
<p>
The same code is used after inserting a newline into a document.
</p>
The
<a href="./org-netbeans-modules-editor-indent/org/netbeans/modules/editor/indent/api/Indent.html" shape="rect">Indent</a>
is an entry point for performing reindentation. The following code should be used by clients:
<pre xml:space="preserve">
Indent indent = Indent.get(doc);
indent.lock();
try {
doc.atomicLock();
try {
indent.reindent(startOffset, endOffset);
} finally {
doc.atomicUnlock();
}
} finally {
indent.unlock();
}
</pre>
<h3>
Code beautification of a selected area of a document.
</h3>
<p>
Code beautification should not only fix line indentation but it may also perform
extra changes to code according to formatting rules. For example add newlines
or additional whitespace or add/remove extra braces etc.
</p>
The
<a href="./org-netbeans-modules-editor-indent/org/netbeans/modules/editor/indent/api/Reformat.html" shape="rect">Reformat</a>
class should be used:
<pre xml:space="preserve">
Reformat reformat = Reformat.get(doc);
reformat.lock();
try {
doc.atomicLock();
try {
reformat.reformat(startOffset, endOffset);
} finally {
doc.atomicUnlock();
}
} finally {
reformat.unlock();
}
</pre>
<hr>
<h2>
<a name="usecase-Editor Library">How to use </a><a href="overview-summary.html#def-api-Editor Library">Editor Library</a>?
</h2>
<description>
The editor library module provides subset of editor functionality independent
on the NetBeans IDE (except few specific standalone classes).
List of the main features:
Syntax highlighting of java, HTML, XML and other languages.
Code Completion enables to type a few characters
and then display a list of suggestions appropriate
in the given context that can be then used
to automatically complete the expression.
Word Matching enables enables to type the beginning characters
of a word used elsewhere in the code and then have the editor
generate the rest of the word.
Abbreviations allow to expand typed text from a few
predefined characters into a full word or phrase.
Goto Class enables to open a Java file in the Source Editor
by typing only the class name.
The IDE helps to identify the correct package name for the class.
The Fast Import feature enables to quickly add import statements
for Java classes in the source file.
Goto Declaration feature allows to quickly jump to a declaration
of a variable under the cursor.
Goto Source allows to open source file containing
definition of a type that the variable under the cursor is of.
Code folding allows to collapse sections of the code that are
unimportant to the user at the given time.
For example in java source the collapsable sections include
imports section, inner classes, methods and javadocs.
</description>
<p></p>
No answer
<hr>
<h2>
<a name="usecase-Editor Library 2">How to use </a><a href="overview-summary.html#def-api-Editor Library 2">Editor Library 2</a>?
</h2>
<description>
The Editor Library 2 module is a set of official APIs and SPIs, designed to
replaces the original Editor Library with legacy APIs
that are not properly structured and do not conform to the rules
implied on the current NB APIs.
The APIs currently offered in Editor Library 2 module include:
<b>editor-code-generator</b>
<b>editor-highlighting</b>
<b>editor-typing-hooks</b>
<b>editor-caret</b>
</description>
<p></p>
At the moment the Editor Library 2 module contains distinct APIs/SPIs. They live
in their own package and the usecases can be found in the packages overview.
<ul>
<li>Code Generator SPI -
<a href="./org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/codegen/package-summary.html#usecases" shape="rect">org.netbeans.spi.editor.codegen</a>
</li>
<li>Highlighting SPI -
<a href="./org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/highlighting/package-summary.html#usecases" shape="rect">org.netbeans.spi.editor.highlighting</a>
</li>
<li>Typing Hooks SPI -
<a href="./org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/typinghooks/package-summary.html#usecases" shape="rect">org.netbeans.spi.editor.typinghooks</a>
</li>
<li>Caret API -
<a href="./org-netbeans-modules-editor-lib2/org/netbeans/api/editor/caret/package-summary.html#usecases" shape="rect">org.netbeans.api.editor.caret</a>
</li>
<li>Caret SPI -
<a href="./org-netbeans-modules-editor-lib2/org/netbeans/spi/editor/caret/package-summary.html#usecases" shape="rect">org.netbeans.spi.editor.caret</a>
</li>
</ul>
<hr>
<h2>
<a name="usecase-MIME Lookup API">How to use </a><a href="overview-summary.html#def-api-MIME Lookup API">MIME Lookup API</a>?
</h2>
<description>
Each editor provides an EditorKit which controls the policy of specific MIME content type.
The policy of content type should be easily registered and found via some lookup mechanism,
that will provide convenient way of using it either for kit provider or base
editor infrastructure. In addition to this, the policy can be inherited, (e.g. in case of embeded
kits like JSP) and the content types need to be merged in this case. MIME Lookup API should
provide all mentioned requierements via easy lookup query, so content type policy
user need not to solve this searching and merging on its own side.
</description>
<p></p>
<h4>Per mime-type operation</h4>
Operation of the editor module must be parametrized by the type of the file
being edited. In the past the operation was parametrized by the class
of the editor kit but that did not show up as being useful enough.
<br>
It is more practical to use a string-based parametrization concretely
the mime-type. Anyone can then easily register an additional functionality
for the editor because it's just enough to know the right mime-type and the type
of the functionality class to be implemented and the xml layer folder
where the class should be registered.
<h4>Provide list of instances as lookup result</h4>
On the modules' implementation side the registered functionality
must be retrieved somehow. It's necessary to instantiate the registered objects
and react to module enabling/disabling which can affect validity of the registered objects.
<br>
As the most convenient solution appears to use
<code>org.openide.util.Lookup</code> allowing to provide
the registered instances as a <code>Lookup.Result</code>
allowing to listen for changes (e.g. caused by the module enabling/disabling).
<br>
This resulted into creation of <code>class MimeLookup extends Lookup</code> containing
<code>static MimeLookup getMimeLookup(String mimeType)</code>.
<h4>Nested mime-types</h4>
On the lexical level the document can contain nested languages.
<br>
For example JSP document can contain pieces of java code which can further contain
javadoc comment tokens with nested javadoc language.
<br>
The nested languages should allow for special settings
such as fonts and colors of nested syntax coloring but even
things like actions that would be active in the nested document section.
<br>
This resulted into creation of
<code>static Lookup getLookup(MimePath mimePath)</code> method in <code>MimeLookup</code>.
<h4>Known clients summary</h4>
<b>Fold Manager Factories</b>
<br>
The editor/fold module expects to find the registered
fold manager factories (<code>org.netbeans.spi.editor.fold.FoldManagerFactory</code> classes).
<br>
<br>
<b>Completion Providers</b>
<br>
The editor/completion module expects to find the registered
completion providers (<code>org.netbeans.spi.editor.completion.CompletionProvider</code> classes).
<br>
<br>
<b>Editor Context Menu Actions</b>
<br>
The editor module expects to find the registered
popup menu actions (<code>javax.swing.Action</code> classes or names of actions
(i.e. value of Action.NAME attribute) present in editor kit e.g. "goto-source").
<br>
<br>
<b>Side Bars</b>
<br>
The editor/lib module expects to find factories for components to be placed on the
sides of the editor component (<code>org.netbeans.editor.SideBarFactory</code> classes).
<br>
<br>
<b>Hyperlink Providers</b>
<br>
The editor/lib module expects to find hyperlink providers that allow connecting
an open document with some other documents (<code>org.netbeans.lib.editor.hyperlink.spi.HyperlinkProvider</code> classes).
<br>
<br>
<b>Code Template Processors</b>
<br>
The editor/codetemplates module expects to find factories for code template processors
(<code>org.netbeans.lib.editor.codetemplates.spi.CodeTemplateProcessorFactory</code> classes).
<br>
<br>
<b>Hints Providers</b>
<br>
The editor/hints module expects to find editor hints providers
(<code>org.netbeans.modules.editor.hints.spi.HintsProvider</code> classes).
<br>
<br>
<br>
<b>
API Use Cases
</b>
<hr>
<h4>Find class instances for the given mime-type</h4>
An API method
<p></p>
<code>
MimeLookup lookup = MimeLookup.getMimeLookup("text/x-java");
</code>
<p></p>
can be used for getting the mime specific lookup. Having this we can lookup class
or template:
<p></p>
<code>
Object obj = lookup.lookup(LookedUpClass.class);
</code>
<p></p>
or
<p></p>
<code>
Lookup.Result result = lookup.lookup(new Lookup.Template(LookedUpClass.class));
</code>
<h4>Getting embeded mime-type specific Lookup</h4>
As an example a jsp scriptlet is used. Scriptlet in fact consists of parent "text/x-jsp" mime-type and
embeded "text/x-java" mime-type. To obtain a scriptlet lookup firstly we need to get a MimePath and then
get appropriate lookup:
<p></p>
<pre xml:space="preserve">
MimePath scriptletPath = MimePath.parse("text/x-jsp/text/x-java");
Lookup lookup = MimeLookup.getLookup(scriptletPath);
</pre>
<br>
<b>
SPI Use Cases
</b>
<hr>
<h4>Providing implemented MimeLookupInitializer</h4>
It is the general way of adding mime specific object into the <code>MimeLookup</code>. Implementation of <code>MimeLookupInitializer</code> should be created and
registered to default lookup via <code>META-INF/services</code> registration.
For details, please look at the simplified
<code>TestMimeLookupInitializer</code>
in <code>mimelookup/test/unit</code> or <code>LayerMimeLookupInitializer</code>.
<b> Usage of MimeLookupInitializer is deprecated, please use MimeDataProvider instead in similar way </b>
<hr>
<h2>
<a name="usecase-Editor Settings">How to use </a><a href="overview-summary.html#def-api-Editor Settings">Editor Settings</a>?
</h2>
<description>
The legacy settings system in the editor module is complicated, error prone
and hard to use. It'd been created spontaneously over the years to support
immediate needs at that time without paying enough attention to extensibility
and interoperability. Historically any module providing editor settings needed
to depend on the whole editor module.
The main purpose of this project is to define API for editor settings, that
is lightweight and easily extensible. The API relies on MimeLookup
to provide a way of registering and looking up settings.
The aim is NOT to provide an implementation of a storage for editor settings,
but to define an interface between this storage and clients
like &lt;mime-type&gt; editors, externaleditor, etc.
</description>
<p></p>
<h4>Accessing settings</h4>
<p>
All editor settings are mime type specific and therefore should be retrieved
using <code>MimeLookup</code>. The following example shows how to retrieve
the <code>FontColorSettings</code> for java files and how to get <code>AttributeSet</code>
with coloring attributes for a particular coloring (i.e. in this case the
colors used for highlighting selected text)
</p>
<pre xml:space="preserve">
MimePath mimePath = MimePath.parse("text/x-java");
FontColorSettings fcs = (FontColorSettings) MimeLookup.getLookup(mimePath).lookup(FontColorSettings.class);
AttributeSet coloring = fcs.getFontColors(FontColorNames.SELECTION_COLORING);
</pre>
<h4>Listening on changes</h4>
<p>
If clients need to react on changes in editor settings they can attach <code>LookupListener</code>
to the <code>LookupResult</code> they got for their particular settings class
from <code>MimeLookup</code>. The following example shows how to do it.
</p>
<pre xml:space="preserve">
MimePath mimePath = MimePath.parse("text/x-java");
Lookup lookup = MimeLookup.getLookup(mimePath);
LookupResult result = lookup.lookup(new Lookup.Template(FontColorSettings.class));
result.addLookupListener(new LookupListener() {
public void resultChanged(LookupEvent ev) {
//... the client's response to the settings change
}
});
</pre>
<p>
The <code>FontColorSettings</code> class implementor is responsible and will create
a new instance of <code>FontColorSettings</code> whenever some coloring will change.
This new instance will be placed in <code>MimeLookup</code> replacing the old one.
</p>
<hr>
<h2>
<a name="usecase-Editor Settings Storage">How to use </a><a href="overview-summary.html#def-api-Editor Settings Storage">Editor Settings Storage</a>?
</h2>
<description>
The module is an implementation of the
<b>org.netbeans.modules.editor.settings</b>
providing a settings storage on the default filesystem.
</description>
<p></p>
<h4>New Options Dialog</h4>
<p>
The friend API provided by this module is used only by the new options dialog. It
is not expected to have any other clients or users. The API gives the options
dialog a read/write access to the editor settings storage allowing it to implement
UI for maintaining the settings.
</p>
<h4>Defining a coloring</h4>
<p>
Various modules need to provide predefined font a colors for text tokens from
languages they support. An example of such a module is <code>java/editor</code>
which defines colorings for tokens in java files. Defining colorings is as simple
as writing an XML file with the appropriate information. The example below shows
how to do that.
</p>
<pre xml:space="preserve">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE fontscolors PUBLIC "-//NetBeans//DTD Editor Fonts and Colors settings 1.1//EN" "http://www.netbeans.org/dtds/EditorFontsColors-1_1.dtd"&gt;
&lt;fontscolors&gt;
&lt;fontcolor name="mylang-keyword" foreColor="0000CC" default="keyword"&gt;
&lt;font style="bold" /&gt;
&lt;/fontcolor&gt;
&lt;/fontscolors&gt;
</pre>
<p>
Please see the
<a href="http://www.netbeans.org/dtds/EditorFontsColors-1_1.dtd" shape="rect">http://www.netbeans.org/dtds/EditorFontsColors-1_1.dtd</a>
for more details.
</p>
<h4>Defining a key binding</h4>
<p>
As well as providing predefined colorings modules need to provide predefined
key bindings. This can be accomplished by writing another simple XML file.
</p>
<pre xml:space="preserve">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE bindings PUBLIC "-//NetBeans//DTD Editor KeyBindings settings 1.1//EN" "http://www.netbeans.org/dtds/EditorKeyBindings-1_1.dtd"&gt;
&lt;bindings&gt;
&lt;bind actionName="goto-source" key="O-O"/&gt;
&lt;/bindings&gt;
</pre>
<p>
Please see the
<a href="http://www.netbeans.org/dtds/EditorKeyBindings-1_1.dtd" shape="rect">http://www.netbeans.org/dtds/EditorKeyBindings-1_1.dtd</a>
for more details.
</p>
<hr>
<h2>
<a name="usecase-Editor Utilities">How to use </a><a href="overview-summary.html#def-api-Editor Utilities">Editor Utilities</a>?
</h2>
<description>
Editor Utilities module contains useful utility classes and methods used
by other editor related modules.
</description>
<p></p>
<h3>
GapList
</h3>
<p>
The GapList class is a <code>java.util.List</code> implementation
similar to <code>java.util.ArrayList</code> but containing a gap in its underlying
array. After a first modification at a particular index
the subsequent modifications around that index are cheap.
<br>
The class is suitable for storage of any elements related to editing
such as positions, elements, views etc.
</p>
<h3>
PriorityMutex
</h3>
<p>
The PriorityMutex is a simple mutex implementation
allowing to find out that a priority thread (by default Event Dispatch Thread)
is waiting to enter the mutex.
<br>
It's used e.g. in editor's view hierarchy or in editor fold hierarchy.
</p>
<h3>
GapBranchElement
</h3>
<p>
GapList-based element implementation suitable for line elements
and any other branch element types.
</p>
<hr>
<h2>
<a name="usecase-External Execution API">How to use </a><a href="overview-summary.html#def-api-External Execution API">External Execution API</a>?
</h2>
<description>
Provides common APIs to execute external process in the IDE to handle its
streams and present the output to the user. Input/line processing can be used
as separate part.
</description>
<p></p>
<h4>Execution of an external process</h4>
<p>
Client needs to execute an external process and handle process streams and
display the output in the output tab.
</p>
<p>
In order to achieve this client creates the
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/ExecutionDescriptor.html" shape="rect">ExecutionDescriptor</a>.
Via this object client configures all the UI behaviour of the subsequent
execution. As a next step client creates the
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/ExecutionService.html" shape="rect">ExecutionService</a>
itself and calls run to execute the job. Run can be called multiple times.
The output and input streams are presented in output tab. Additional
processing and printing conversion can be configured in descriptor through
interfaces described in following usecases.
</p>
<p>
The creation of the external process is supported by
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/ExternalProcessBuilder.html" shape="rect">ExternalProcessBuilder</a>
to make things easier.
</p>
<h4>Processing the input</h4>
<p>
<span style="text-decoration:line-through;">Client needs to process character
data coming from stream, file or other source.</span> This usecase should
be solved by External Execution Base API.
</p>
<p>
To abstract the source of the data client must implement
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/input/InputReader.html" shape="rect">InputReader</a>.
To abstract the data processing client must implement
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/input/InputProcessor.html" shape="rect">InputProcessor</a> or
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/input/LineProcessor.html" shape="rect">LineProcessor</a>.
For all three interfaces there are prepared common implementations (and bridge
from character based to line based processing) at these three factory classes:
</p>
<ul>
<li>
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/input/InputReaders.html" shape="rect">InputReaders</a>
</li>
<li>
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/input/InputProcessors.html" shape="rect">InputProcessors</a>
</li>
<li>
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/input/LineProcessors.html" shape="rect">LineProcessors</a>
</li>
</ul>
<p>
To configure additional functionality specific to <code>org.openide.windows.OutputWriter</code>
see the next usecase.
</p>
<p>
Once the data source and processing objects are prepared client creates
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/input/InputReaderTask.html" shape="rect">InputReaderTask</a>.
Factory methods of the <a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/input/InputReaderTask.html" shape="rect">InputReaderTask</a>
can create either common task exiting on interruption or cancellation
or draining task which is trying to drain out all available data before exiting.
</p>
<h4>Printing the input</h4>
<p>
Client intends to process input lines and print them to <code>org.openide.windows.OutputWriter</code>.
In addition printed lines should be transformed (converted) somehow
and enriched by line listeners.
</p>
<p>
The both default printing processors provide factory method accepting
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/print/LineConvertor.html" shape="rect">LineConvertor</a>.
Namely
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/print/InputProcessors.html#printing-org.openide.windows.OutputWriter-org.netbeans.api.extexecution.print.LineConvertor-boolean-" shape="rect">
InputProcessors.printing(org.openide.windows.OutputWriter out, LineConvertor convertor, boolean resetEnabled)</a>
and
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/print/LineProcessors.html#printing-org.openide.windows.OutputWriter-org.netbeans.api.extexecution.print.LineConvertor-boolean-" shape="rect">
LineProcessors.printing(org.openide.windows.OutputWriter out, LineConvertor convertor, boolean resetEnabled)</a>.
Convertor is then used to convert received lines to printed ones.
Common convertors (file, http) are provided in factory class
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/print/LineConvertors.html" shape="rect">LineConvertors</a>.
</p>
<h4>Custom process builder</h4>
<p>
<span style="text-decoration:line-through;">Third party wants to implement custom process builder to provide
additional functionality, such as remote execution.</span>
This usecase should be solved by External Execution Base API.
</p>
<p>
In order to do so it will implement
<a href="org-netbeans-modules-extexecution/org/netbeans/spi/extexecution/ProcessBuilderImplementation.html" shape="rect">
ProcessBuilderImplementation</a> and pass
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/ProcessBuilder.html" shape="rect">
ProcessBuilder</a> to its clients. The API instances are created with
help of
<a href="org-netbeans-modules-extexecution/org/netbeans/spi/extexecution/ProcessBuilderFactory.html" shape="rect">ProcessBuilderFactory</a>.
</p>
<h4>Destroying a process</h4>
<p>
<span style="text-decoration:line-through;">Client wants to destroy the process, trying to kill whole process tree.</span>
This usecase should be solved by External Execution Base API.
Method
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/ExternalProcessSupport.html#destroy-java.lang.Process-java.util.Map-" shape="rect">
ExternalProcessSupport.destroy(java.lang.Process process, Map&lt;String,String&gt; env)</a>
is designed for that. It will use a
<a href="org-netbeans-modules-extexecution/org/netbeans/spi/extexecution/destroy/ProcessDestroyPerformer.html" shape="rect">ProcessDestroyPerformer</a>
registered in default lookup to do so.
</p>
<h4>Extending startup environment</h4>
<p>
The third party plugin may want to be able provide additional arguments
for the process startup in a standardized way. In order to do so it will
register a implementation of
<a href="org-netbeans-modules-extexecution/org/netbeans/spi/extexecution/startup/StartupExtenderImplementation.html" shape="rect">StartupExtenderImplementation</a>
to the layer folder StartupExtender. The annotation
<a href="org-netbeans-modules-extexecution/org/netbeans/spi/extexecution/startup/StartupExtenderImplementation.Registration.html" shape="rect">StartupExtenderImplementation.Registration</a>
can be used for that.
</p>
<p>
The clients (for exmaple project or server) may query the extenders via the
API class
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/startup/StartupExtender.html" shape="rect">StartupExtender</a>
and use the additional arguments for the process.
</p>
<h4>Making certain open actions pluggable</h4>
<p>
Some default
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/print/LineConvertor.html" shape="rect">LineConvertor</a>s
returned by
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/print/LineConvertors.html" shape="rect">LineConvertor</a>
needs to open file or URL. A bit special case is also options dialog opening
required by
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/ExecutionService.html" shape="rect">ExecutionService</a>
to open options dialog specified by
<a href="org-netbeans-modules-extexecution/org/netbeans/api/extexecution/ExecutionDescriptor.html" shape="rect">ExecutionDescriptor</a>.
To cover this three usecases in a pluggable way while keeping dependencies
minimal there are three corresponding SPI classes one may implement.
So there is
<a href="org-netbeans-modules-extexecution/org/netbeans/spi/extexecution/open/FileOpenHandler.html" shape="rect">FileOpenHandler</a>
to handle file opening,
<a href="org-netbeans-modules-extexecution/org/netbeans/spi/extexecution/open/HttpOpenHandler.html" shape="rect">HttpOpenHandler</a>
to deal with HTTP URLs and
<a href="org-netbeans-modules-extexecution/org/netbeans/spi/extexecution/open/OptionOpenHandler.html" shape="rect">OptionOpenHandler</a>
to open proper options dialog.
</p>
<hr>
<h2>
<a name="usecase-Java EE Metadata">How to use </a><a href="overview-summary.html#def-api-Java EE Metadata">Java EE Metadata</a>?
</h2>
<description>
The project provides a generic framework for accessing Java EE metadata models.
</description>
<p></p>
<h4>Accessing metadata models</h4>
<p>
A module wishing to access Java EE metadata obtains a metadata model, which is encapsulated
by the <a href="org-netbeans-modules-j2ee-metadata/org/netbeans/modules/j2ee/metadata/model/api/MetadataModel.html" shape="rect">MetadataModel</a>
class. The client then implements a model action, represented by the
<a href="org-netbeans-modules-j2ee-metadata/org/netbeans/modules/j2ee/metadata/model/api/MetadataModelAction.html" shape="rect">MetadataModelAction</a> class,
and executes this action in the model context by calling the model's
<a href="org-netbeans-modules-j2ee-metadata/org/netbeans/modules/j2ee/metadata/model/api/MetadataModel.html#runReadAction-org.netbeans.modules.j2ee.metadata.model.api.MetadataModelAction-" shape="rect">runReadAction()</a>
method:
</p>
<pre xml:space="preserve">
MetadataModel&lt;SomeMetadata&gt; model = // ...
String result = model.runReadAction(new MetadataModelAction&lt;SomeMetadata, String&gt;() {
public String run(SomeMetadata metadata) {
// ... do something with metadata, e.g.
// compute a String value
return value;
}
}
</pre>
<p>
The way to obtain the model itself, as well as the kinds of metadata encapsulated by <code>MetadataModel</code> is
metadata and metadata provider-specific and is not addressed by this API.
</p>
<h4>Providing metadata models</h4>
<p>
A metadata provider first defines a root class describing the metadata, e.g., <code>SomeMetadata</code>. Then the provider
implements the <a href="org-netbeans-modules-j2ee-metadata/org/netbeans/modules/j2ee/metadata/model/spi/MetadataModelImplementation.html" shape="rect">MetadataModelImplementation</a> interface and
creates a <code>MetadataModel</code> using <a href="org-netbeans-modules-j2ee-metadata/org/netbeans/modules/j2ee/metadata/model/spi/MetadataModelFactory.html" shape="rect">MetadataModelFactory</a>.
Then the provider defines a way to return the model to its clients:
</p>
<pre xml:space="preserve">
private SomeMetadataModelImplementation modelImpl = new SomeMetadataModelImplementation();
private MetadataModel&lt;SomeMetadata&gt; model = MetadataModelFactory.createMetadataModel(modelImpl);
/**
* Call this to retrieve the model of some metadata.
*/
public MetadataModel&lt;SomeMetadata&gt; getSomeMetadataModel() {
return model;
}
// ...
private class SomeMetadataModelImplementation implements MetadataModelImplementation&lt;SomeMetadata&gt; {
// ...
}
</pre>
<h4>Providing multiple metadata models</h4>
<p>
A metadata provider might need to provide several kinds of metadata models at once. Furthermore, since there
can be many models available or for backward compatibility reasons it might be impractical to provide
a method for each of the models. In this case the provider may define a method like:
</p>
<pre xml:space="preserve">
public MetadataModel&lt;T&gt; getMetadataModel(Class&lt;T&gt; clazz) {
// ...
}
</pre>
<p>
The types of <code>Class</code> which may be passed to the method is a part of the contract between
the provider and its clients.
</p>
<hr>
<h2>
<a name="usecase-Java Hints Test API">How to use </a><a href="overview-summary.html#def-api-Java Hints Test API">Java Hints Test API</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-Java SE Projects">How to use </a><a href="overview-summary.html#def-api-Java SE Projects">Java SE Projects</a>?
</h2>
<description>
Provides a project type for plain Java projects. J2SE projects can be created
from scratch, or you can import existing Java source trees. Creates an Ant
script letting you build the project (and subprojects), run it, debug it, run
JUnit-format tests, and build Javadoc. GUI customizer permits easy
customization of the most commonly needed project parameters. Provides code
completion and other services for editing Java sources. Classpaths can include
other projects, raw JARs, or configured libraries. Specific J2SE platforms may
be configured.
</description>
<p></p>
<p>
Covered by UI specification and design document.
</p>
<hr>
<h2>
<a name="usecase-Java Platform">How to use </a><a href="overview-summary.html#def-api-Java Platform">Java Platform</a>?
</h2>
<description>
Many Java-based project types need to be able to configure the version and
location of Java to be used when building and running the project. This
API/SPI permits these platforms to be registered and queried, and any
customizations made in an appropriate GUI and persisted to disk.
</description>
<p></p>
<p>
The API can be used by any code wishing to know the list of installed
platforms and information about each one; typically this would be used by
project type providers to implement a customizer dialog. The SPI is intended
to be implemented by a few modules supply support for locating and
introspecting installed platforms, for example a JDK setup wizard.
</p>
<hr>
<h2>
<a name="usecase-Java Platform UI">How to use </a><a href="overview-summary.html#def-api-Java Platform UI">Java Platform UI</a>?
</h2>
<description>
Many Java-based project types need to be able to configure the version and
location of Java to be used when building and running the project. This
API/SPI permits these platforms to be registered and queried, and any
customizations made in an appropriate GUI and persisted to disk.
</description>
<p></p>
<p>
The API can be used by any code wishing to know the list of installed
platforms and information about each one; typically this would be used by
project type providers to implement a customizer dialog. The SPI is intended
to be implemented by a few modules supply support for locating and
introspecting installed platforms, for example a JDK setup wizard.
</p>
<hr>
<h2>
<a name="usecase-Java Project Support">How to use </a><a href="overview-summary.html#def-api-Java Project Support">Java Project Support</a>?
</h2>
<description>
Provides support infrastructure for projects working with the Java language.
</description>
<p></p>
<p>
Project type providers wishing to show Java packages in their logical views
can use this SPI. Templates which are Java-centric can use it. Projects which
wish to implement queries from the Java Support APIs can place implementations
in their lookup and these will be delegated to automatically.
</p>
<hr>
<h2>
<a name="usecase-Java Project Support UI">How to use </a><a href="overview-summary.html#def-api-Java Project Support UI">Java Project Support UI</a>?
</h2>
<description>
Provides support infrastructure for projects working with the Java language.
</description>
<p></p>
<p>
Project type providers wishing to show Java packages in their logical views
can use this SPI. Templates which are Java-centric can use it. Projects which
wish to implement queries from the Java Support APIs can place implementations
in their lookup and these will be delegated to automatically.
</p>
<hr>
<h2>
<a name="usecase-Java Source">How to use </a><a href="overview-summary.html#def-api-Java Source">Java Source</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-Java Source Base">How to use </a><a href="overview-summary.html#def-api-Java Source Base">Java Source Base</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-Java Source UI">How to use </a><a href="overview-summary.html#def-api-Java Source UI">Java Source UI</a>?
</h2>
<description>
<b>java.sourceui</b>
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-JUnit Tests">How to use </a><a href="overview-summary.html#def-api-JUnit Tests">JUnit Tests</a>?
</h2>
<description>
The module makes creating, running and navigation between tests easier.
(Actual test running is typically performed directly by a
project type provider using Ant.)
</description>
<p></p>
<p>
The SPI allows to plug a project-type-specific implementation of JUnit
support into NetBeans. The current NetBeans implementation only supports
JUnit on J2SE project types. The SPI describes services provided by the
custom JUnit support plugin.
</p>
<p>
The functionality to be plugged in comprises:
</p>
<ul>
<li>generation of test skeletons</li>
<li>navigation between source classes and corresponding test
classes</li>
</ul>
<p>
For navigation, the plugin defines mapping between source classes and
the corresponding test classes (both directions). Thus it provides
an additional information to the information provides by
<code>UnitTestForSourceQuery</code>
</p>
<p>
For generation of test skeletons, the plugin actually defines the whole
test skeleton generator - it generates one or more test files for
a given source file.
</p>
<hr>
<h2>
<a name="usecase-Keyring API">How to use </a><a href="overview-summary.html#def-api-Keyring API">Keyring API</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-Lexer">How to use </a><a href="overview-summary.html#def-api-Lexer">Lexer</a>?
</h2>
<description>
Lexer module provides token lists for various
text inputs. Token lists can either be flat or they can form
tree token hierarchies if any language embedding is present.
Tokens
</description>
<p></p>
<!-- API Usecases - API Usecases - API Usecases - API Usecases - API Usecases -->
<h1>
API Usecases
</h1>
<h3>
Obtaining of token hierarchy for various inputs.
</h3>
The
<a href="./org-netbeans-modules-lexer/org/netbeans/api/lexer/TokenHierarchy.html" shape="rect">TokenHierarchy</a>
is an entry point into Lexer API
and it represents the given input in terms of tokens.
<pre xml:space="preserve">
String text = "public void m() { }";
TokenHierarchy hi = TokenHierarchy.create(text, JavaLanguage.description());
</pre>
<br>
Token hierarchy for swing documents must be operated under read/write document's lock.
<pre xml:space="preserve">
document.readLock();
try {
TokenHierarchy hi = TokenHierarchy.get(document);
... // explore tokens etc.
} finally {
document.readUnlock();
}
</pre>
<h3>
Obtaining and iterating token sequence over particular swing document from the given offset.
</h3>
The tokens cover the whole document and it's possible to iterate either forward or backward.
<br>
Each token can contain language embedding that can also be explored by the token sequence.
The language embedding covers the whole text of the token (there can be few characters
skipped at the begining an end of the branch token).
<pre xml:space="preserve">
document.readLock();
try {
TokenHierarchy hi = TokenHierarchy.get(document);
TokenSequence ts = hi.tokenSequence();
// If necessary move ts to the requested offset
ts.move(offset);
while (ts.moveNext()) {
Token t = ts.token();
if (t.id() == ...) { ... }
if (TokenUtilities.equals(t.text(), "mytext")) { ... }
if (ts.offset() == ...) { ... }
// Possibly retrieve embedded token sequence
TokenSequence embedded = ts.embedded();
if (embedded != null) { // Token has a valid language embedding
...
}
}
} finally {
document.readUnlock();
}
</pre>
<br>
Typical clients:
<ul>
<li>Editor's painting code doing syntax coloring
<code>org.netbeans.modules.lexer.editorbridge.LexerLayer</code> in <i>lexer/editorbridge</i> module.
</li>
<li>Brace matching code searching for matching brace in forward/backward direction.</li>
<li>Code completion's quick check whether caret is located inside comment token.</li>
<li>Parser constructing a parse tree iterating through the tokens in forward direction.</li>
</ul>
<h3>
Using language path of the token sequence
</h3>
For the given token sequence the client may check whether it's a top level
token sequence in the token hierarchy or whether it's embedded at which level
it's embedded and what are the parent languages.
<br>
Each token can contain language embedding that can also be explored by the token sequence.
The language embedding covers the whole text of the token (there can be few characters
skipped at the begining an end of the branch token).
<pre xml:space="preserve">
TokenSequence ts = ...
LanguagePath lp = ts.languagePath();
if (lp.size() &gt; 1) { ... } // This is embedded token sequence
if (lp.topLanguage() == JavaLanguage.description()) { ... } // top-level language of the token hierarchy
String mimePath = lp.mimePath();
Object setting-value = some-settings.getSetting(mimePath, setting-name);
</pre>
<h3>
Extra information about the input
</h3>
The
<a href="./org-netbeans-modules-lexer/org/netbeans/api/lexer/InputAttributes.html" shape="rect">InputAttributes</a>
class may carry extra information about the text input on which the token hierarchy
is being created. For example there can be information about the version of the language
that the input represents and the lexer may be written to recognize multiple versions
of the language. It should suffice to do the versioning through a simple integer:
<pre xml:space="preserve">
public class MyLexer implements Lexer&lt;MyTokenId&gt; {
private final int version;
...
public MyLexer(LexerInput input, TokenFactory&lt;MyTokenId&gt; tokenFactory, Object state,
LanguagePath languagePath, InputAttributes inputAttributes) {
...
Integer ver = (inputAttributes != null)
? (Integer)inputAttributes.getValue(languagePath, "version")
: null;
this.version = (ver != null) ? ver.intValue() : 1; // Use version 1 if not specified explicitly
}
public Token&lt;MyTokenId&gt; nextToken() {
...
if (recognized-assert-keyword) {
return (version &gt;= 4) { // "assert" recognized as keyword since version 4
? keyword(MyTokenId.ASSERT)
: identifier();
}
...
}
...
}
</pre>
The client will then use the following code:
<pre xml:space="preserve">
InputAttributes attrs = new InputAttributes();
// The "true" means global value i.e. for any occurrence of the MyLanguage including embeddings
attrs.setValue(MyLanguage.description(), "version", Integer.valueOf(3), true);
TokenHierarchy hi = TokenHierarchy.create(text, false, SimpleLanguage.description(), null, attrs);
...
</pre>
<h3>
Filtering out unnecessary tokens
</h3>
Filtering is only possible for immutable inputs (e.g. String or Reader).
<pre xml:space="preserve">
Set&lt;MyTokenId&gt; skipIds = EnumSet.of(MyTokenId.COMMENT, MyTokenId.WHITESPACE);
TokenHierarchy tokenHierarchy = TokenHierarchy.create(inputText, false,
MyLanguage.description(), skipIds, null);
...
</pre>
<br>
Typical clients:
<ul>
<li>Parser constructing a parse tree. It is not interested
in the comment and whitespace tokens so these tokens do not need
to be constructed at all.
</li>
</ul>
<!-- SPI Usecases - SPI Usecases - SPI Usecases - SPI Usecases - SPI Usecases -->
<h1>
SPI Usecases
</h1>
<h3>
Providing language description and lexer.
</h3>
Token ids should be defined as enums. For example
<code>org.netbeans.lib.lexer.test.simple.SimpleTokenId</code> can be copied
or the following example from
<code>org.netbeans.modules.lexer.editorbridge.calc.lang.CalcTokenId</code>.
<br>
The static <code>language()</code> method returns the language describing the token ids.
<pre xml:space="preserve">
public enum CalcTokenId implements TokenId {
WHITESPACE(null, "whitespace"),
SL_COMMENT(null, "comment"),
ML_COMMENT(null, "comment"),
E("e", "keyword"),
PI("pi", "keyword"),
IDENTIFIER(null, null),
INT_LITERAL(null, "number"),
FLOAT_LITERAL(null, "number"),
PLUS("+", "operator"),
MINUS("-", "operator"),
STAR("*", "operator"),
SLASH("/", "operator"),
LPAREN("(", "separator"),
RPAREN(")", "separator"),
ERROR(null, "error"),
ML_COMMENT_INCOMPLETE(null, "comment");
private final String fixedText;
private final String primaryCategory;
private CalcTokenId(String fixedText, String primaryCategory) {
this.fixedText = fixedText;
this.primaryCategory = primaryCategory;
}
public String fixedText() {
return fixedText;
}
public String primaryCategory() {
return primaryCategory;
}
private static final Language&lt;CalcTokenId&gt; language = new LanguageHierarchy&lt;CalcTokenId&gt;() {
<code>@Override</code>
protected Collection&lt;CalcTokenId&gt; createTokenIds() {
return EnumSet.allOf(CalcTokenId.class);
}
<code>@Override</code>
protected Map&lt;String,Collection&lt;CalcTokenId&gt;&gt; createTokenCategories() {
Map&lt;String,Collection&lt;CalcTokenId&gt;&gt; cats = new HashMap&lt;String,Collection&lt;CalcTokenId&gt;&gt;();
// Incomplete literals
cats.put("incomplete", EnumSet.of(CalcTokenId.ML_COMMENT_INCOMPLETE));
// Additional literals being a lexical error
cats.put("error", EnumSet.of(CalcTokenId.ML_COMMENT_INCOMPLETE));
return cats;
}
<code>@Override</code>
protected Lexer&lt;CalcTokenId&gt; createLexer(LexerRestartInfo&lt;CalcTokenId&gt; info) {
return new CalcLexer(info);
}
<code>@Override</code>
protected String mimeType() {
return "text/x-calc";
}
}.language();
public static final Language&lt;CalcTokenId&gt; language() {
return language;
}
}
</pre>
Note that it is not needed to publish the underlying <code>LanguageHierarchy</code> extension.
<br>
Lexer example:
<pre xml:space="preserve">
public final class CalcLexer implements Lexer&lt;CalcTokenId&gt; {
private static final int EOF = LexerInput.EOF;
private static final Map&lt;String,CalcTokenId&gt; keywords = new HashMap&lt;String,CalcTokenId&gt;();
static {
keywords.put(CalcTokenId.E.fixedText(), CalcTokenId.E);
keywords.put(CalcTokenId.PI.fixedText(), CalcTokenId.PI);
}
private LexerInput input;
private TokenFactory&lt;CalcTokenId&gt; tokenFactory;
CalcLexer(LexerRestartInfo&lt;CalcTokenId&gt; info) {
this.input = info.input();
this.tokenFactory = info.tokenFactory();
assert (info.state() == null); // passed argument always null
}
public Token&lt;CalcTokenId&gt; nextToken() {
while (true) {
int ch = input.read();
switch (ch) {
case '+':
return token(CalcTokenId.PLUS);
case '-':
return token(CalcTokenId.MINUS);
case '*':
return token(CalcTokenId.STAR);
case '/':
switch (input.read()) {
case '/': // in single-line comment
while (true)
switch (input.read()) {
case '\r': input.consumeNewline();
case '\n':
case EOF:
return token(CalcTokenId.SL_COMMENT);
}
case '*': // in multi-line comment
while (true) {
ch = input.read();
while (ch == '*') {
ch = input.read();
if (ch == '/')
return token(CalcTokenId.ML_COMMENT);
else if (ch == EOF)
return token(CalcTokenId.ML_COMMENT_INCOMPLETE);
}
if (ch == EOF)
return token(CalcTokenId.ML_COMMENT_INCOMPLETE);
}
}
input.backup(1);
return token(CalcTokenId.SLASH);
case '(':
return token(CalcTokenId.LPAREN);
case ')':
return token(CalcTokenId.RPAREN);
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '.':
return finishIntOrFloatLiteral(ch);
case EOF:
return null;
default:
if (Character.isWhitespace((char)ch)) {
ch = input.read();
while (ch != EOF &amp;&amp; Character.isWhitespace((char)ch)) {
ch = input.read();
}
input.backup(1);
return token(CalcTokenId.WHITESPACE);
}
if (Character.isLetter((char)ch)) { // identifier or keyword
while (true) {
if (ch == EOF || !Character.isLetter((char)ch)) {
input.backup(1); // backup the extra char (or EOF)
// Check for keywords
CalcTokenId id = keywords.get(input.readText());
if (id == null) {
id = CalcTokenId.IDENTIFIER;
}
return token(id);
}
ch = input.read(); // read next char
}
}
return token(CalcTokenId.ERROR);
}
}
}
public Object state() {
return null;
}
private Token&lt;CalcTokenId&gt; finishIntOrFloatLiteral(int ch) {
boolean floatLiteral = false;
boolean inExponent = false;
while (true) {
switch (ch) {
case '.':
if (floatLiteral) {
return token(CalcTokenId.FLOAT_LITERAL);
} else {
floatLiteral = true;
}
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
break;
case 'e': case 'E': // exponent part
if (inExponent) {
return token(CalcTokenId.FLOAT_LITERAL);
} else {
floatLiteral = true;
inExponent = true;
}
break;
default:
input.backup(1);
return token(floatLiteral ? CalcTokenId.FLOAT_LITERAL
: CalcTokenId.INT_LITERAL);
}
ch = input.read();
}
}
private Token&lt;CalcTokenId&gt; token(CalcTokenId id) {
return (id.fixedText() != null)
? tokenFactory.getFlyweightToken(id, id.fixedText())
: tokenFactory.createToken(id);
}
}
</pre>
<p>
The classes containing token ids and the language description should be
part of an API. The lexer should only be part of the implementation.
</p>
<h3>
Providing language embedding.
</h3>
The embedding may be provided statically
in the <code>LanguageHierarchy.embedding()</code>
see e.g. <code>org.netbeans.lib.lexer.test.simple.SimpleLanguage</code>.
<p>
Or it may be provided dynamically through the xml layer
by using a file in "Editors/language-mime-type/languagesEmbeddingMap" folder
named by the token-id's name containing target mime-type and initial and ending skip lengths:
</p>
<pre xml:space="preserve">
&lt;folder name="Editors"&gt;
&lt;folder name="text"&gt;
&lt;folder name="x-outer-language"&gt;
&lt;folder name="languagesEmbeddingMap"&gt;
&lt;file name="WORD"&gt;&lt;![CDATA[text/x-inner-language,1,2]]&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;/folder&gt;
</pre>
<hr>
<h2>
<a name="usecase-Master Filesystem">How to use </a><a href="overview-summary.html#def-api-Master Filesystem">Master Filesystem</a>?
</h2>
<description>
MasterFileSystems is just implementation of FileSystem provided in standalone
module including implementation of URLMapper that resolves file protocol and
is responsible for conversion from URL into FileObject and vice versa.
Implementation just delegates to the other FileSystem implementations
(LocalFileSystem, VCSFileSystem, ...) and playes the role of arbiter that controls
instantiation and life cycle of provided FileObjects.
<b>MasterFileSystemAPI</b>
</description>
<p></p>
MasterFileSystem is just implementation of FileSystem. There are no special use
cases. FileObjects erlier returned from <code>URLMapper</code> or
<code>FileUtil.fromFile</code> provided by <code>LocalFileSystem</code> or
<code>CvsFileSystem</code> will be now provided by <code>MasterFileSystem</code>.
There will be guaranteed that there won't be more instances of FileObject
addressing one <code>java.ioFile</code>.
<hr>
<h2>
<a name="usecase-NB JUnit">How to use </a><a href="overview-summary.html#def-api-NB JUnit">NB JUnit</a>?
</h2>
<description>
Module contains NetBeans extension to JUnit.
</description>
<p></p>
<p>
Tests typically extends NbTestCase.
</p>
<hr>
<h2>
<a name="usecase-Options Dialog and SPI">How to use </a><a href="overview-summary.html#def-api-Options Dialog and SPI">Options Dialog and SPI</a>?
</h2>
<description>
This module contains implementation of Options Panel and simple SPI.
</description>
<p></p>
<h4>Register top level Options Panel</h4>
<p>Client can install new panel to Options Dialog - see JavaDoc for OptionsCategory class.</p>
<h4>Register panel to Advanced Options Panel</h4>
<p>Client can install new panel to Advanced Options Panel - see JavaDoc for AdvancedOption class.</p>
<hr>
<h2>
<a name="usecase-Parsing API">How to use </a><a href="overview-summary.html#def-api-Parsing API">Parsing API</a>?
</h2>
<description>
See Parsing API homepage for project requirements, motivation.
</description>
<p></p>
<ol>
<li>Parsing API Client can always ask for parser result.
This direct call has top level priority (stops all other requests).
Its designed to support direct user to IDE interaction
(like request for code completion) that have to be as
fast as possible. Such type of task is called UserTask.
This approach is used not only for parsing of file currently
edited in Editor, but it supports Refactoring too.</li>
<li>Parsing API Implementation listens on various changes in IDE
(typing in the current document, cursor movements, switching
of editor tabs, changes of classpath). These changes affects parse
tree of the current document, and various visualisation features
based on parser results (text coloring, hints, error stripe).
Parsing API Client can register some tasks that should run when
such change is done (Task). Implemementation of Parsing API than
calls all such registerred tasks. These calls has lower priority than
UserTasks, and they should not block user interaction with IDE
(typing in editor).</li>
<li>Parsing API defines how to recognize embedded languages. It should
be possible to create snapshot of some file, call some recognizers that
finds blocks of embedded languages and run different parsers for embedded blocks.
It should be able to use the same parser for top level language and any
embedded block of code written in the same language. Embedding recognizer
can add some virtual code (code that does not exists in top level source)
to the embedded block. There should be some support for translation
of offsets between top level source and virtual source generated
for embedded piece of code.</li>
</ol>
<hr>
<h2>
<a name="usecase-Parsing API Indexing">How to use </a><a href="overview-summary.html#def-api-Parsing API Indexing">Parsing API Indexing</a>?
</h2>
<description>
See Parsing API homepage for project requirements, motivation.
</description>
<p></p>
<ol>
<li>
Indexing API client may request that some or all indexes should be
rebuilt for a certain or all project source roots, or certain files. The indexing
infrastructure eventually rebuilds the indexes. The API client may
choose to wait for the indexing to complete.
</li>
<li>
Module implementor may plug into the indexing system by declaring a
CustomIndexer, BinaryIndexer, or EmbeddingIndexer. The implementation
is called at appropriate time to generate or refresh index information
for portion of project sources.
</li>
</ol>
<hr>
<h2>
<a name="usecase-Print">How to use </a><a href="overview-summary.html#def-api-Print">Print</a>?
</h2>
<description>
Provides print functionality in NetBeans.
</description>
<p></p>
<p>The typical client of Print module can be any tool to print custom data.</p>
<p>The simple way to enable printing for a custom data is:</p>
<p>If the data is a Swing component which extends <code>javax.swing.JComponent</code>
and shown in a <code>org.openide.windows.TopComponent</code>, the key "print.printable"
(PrintManager.PRINT_PRINTABLE) with value <code>"Boolean.TRUE"</code>
in the component must be set as a client property. See example:</p>
<pre xml:space="preserve">
public class MyComponent extends javax.swing.JComponent {
public MyComponent() {
...
putClientProperty("print.printable", Boolean.TRUE); // NOI18N
}
...
}</pre>
<hr>
<h2>
<a name="usecase-Ant-Based Project Support">How to use </a><a href="overview-summary.html#def-api-Ant-Based Project Support">Ant-Based Project Support</a>?
</h2>
<description>
Provides the basic infrastructure by which Ant-based projects can be created,
read and write configuration parameters and properties from/to disk, satisfy
common queries and interfaces, etc. See Javadoc and build system design
document.
</description>
<p></p>
<p>
Mostly an SPI for use by project type providers to create the project type.
Also includes a small API/SPI for other projects to find what Ant build steps
are necessary to create a certain build product, for use in inter-project
dependencies.
</p>
<b>Ant project support faq:</b>
<h4>How to use support for storing project properties?</h4>
<em><b>Q:</b>
I'm creating a customizer (properties dialog) for my project type. I wan't to use the support
for simple data types. What do I need to do?</em>
<p>
You basicaly need to do two things. First create the representation of the project properties which
can be used in the GUI. Second at some time convert the objects back to the ANT properties form and
store them into the project.
</p>
<ul>
<li>
<b>Creating the object representation.</b>
<ol>
<li>Create new instance of StoreGroup for each group of properties you want to store later
e.g. project and prvate. Sometimes it might be useful to create temporary source group
which will only be used for creating the models without being used for storing. E.g.
for properties which need special handling.</li>
<li>Call the factory methods e.g. createBooleanButtonModel, createStringDocument, etc. which
will create the swing models for you.</li>
<li>Use the models in your Swing controls by calling setModel() or setDocument()</li>
</ol>
</li>
<li>
<b>Storing the models back to the proprties of project.</b>
<ol>
<li>Get the EditableProperties you want to store the model in e.g. private or project
properties</li>
<li>Call the store method on given SourceGroup with the EditableProperties as parameter</li>
<li>Manually store models which need some special handling.</li>
</ol>
</li>
</ul>
<hr>
<h2>
<a name="usecase-Ant-Based Project Support UI">How to use </a><a href="overview-summary.html#def-api-Ant-Based Project Support UI">Ant-Based Project Support UI</a>?
</h2>
<description>
Provides the basic infrastructure by which Ant-based projects can be created,
read and write configuration parameters and properties from/to disk, satisfy
common queries and interfaces, etc. See Javadoc and build system design
document.
</description>
<p></p>
<p>
Mostly an SPI for use by project type providers to create the project type.
Also includes a small API/SPI for other projects to find what Ant build steps
are necessary to create a certain build product, for use in inter-project
dependencies.
</p>
<b>Ant project support faq:</b>
<h4>How to use support for storing project properties?</h4>
<em><b>Q:</b>
I'm creating a customizer (properties dialog) for my project type. I wan't to use the support
for simple data types. What do I need to do?</em>
<p>
You basicaly need to do two things. First create the representation of the project properties which
can be used in the GUI. Second at some time convert the objects back to the ANT properties form and
store them into the project.
</p>
<ul>
<li>
<b>Creating the object representation.</b>
<ol>
<li>Create new instance of StoreGroup for each group of properties you want to store later
e.g. project and prvate. Sometimes it might be useful to create temporary source group
which will only be used for creating the models without being used for storing. E.g.
for properties which need special handling.</li>
<li>Call the factory methods e.g. createBooleanButtonModel, createStringDocument, etc. which
will create the swing models for you.</li>
<li>Use the models in your Swing controls by calling setModel() or setDocument()</li>
</ol>
</li>
<li>
<b>Storing the models back to the proprties of project.</b>
<ol>
<li>Get the EditableProperties you want to store the model in e.g. private or project
properties</li>
<li>Call the store method on given SourceGroup with the EditableProperties as parameter</li>
<li>Manually store models which need some special handling.</li>
</ol>
</li>
</ul>
<hr>
<h2>
<a name="usecase-External Libraries">How to use </a><a href="overview-summary.html#def-api-External Libraries">External Libraries</a>?
</h2>
<description>
Permits libraries to be defined, customized, and stored by the user for
reuse in multiple projects. For example, a Java JAR library has a classpath
(usually one JAR), and an optional source path and Javadoc path that may be
used for development-time features.
</description>
<p></p>
<p>
Different technology support modules will supply definitions of different
kinds of libraries, e.g. Java JARs, that may be reused in user projects.
Modules may register library predefinitions to wrap libraries they bundle.
Project type providers can refer to available libraries in customizer dialogs.
</p>
<hr>
<h2>
<a name="usecase-External Libraries UI">How to use </a><a href="overview-summary.html#def-api-External Libraries UI">External Libraries UI</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-Project API">How to use </a><a href="overview-summary.html#def-api-Project API">Project API</a>?
</h2>
<description>
Provides a generic infrastructure for modelling projects.
Documentation available in the Javadoc. The build system design overview
describes the basic purpose of modelling projects.
</description>
<p></p>
<p>
The SPI should be used by modules defining particular project types, e.g. the
J2SE project type. The API is to be used primarily by GUI infrastructure and
some queries, though other module code may on occasion need to refer to the
API.
</p>
<hr>
<h2>
<a name="usecase-Project UI">How to use </a><a href="overview-summary.html#def-api-Project UI">Project UI</a>?
</h2>
<description>
General user interface implementation for the project system. UI
Specification
</description>
<p></p>
<p>
Needed for working with projects in the IDE.
</p>
<api category="friend" group="java" name="RecentProjects" type="export" url="http://www.netbeans.org/issues/show_bug.cgi?id=57073">
<p>
API can be used to get list of information about recently opened projects
in IDE. API provides project display name, icon and URL of project folder
location. Listeners can be registered to learn about change of the list.
</p>
</api>
<hr>
<h2>
<a name="usecase-Project UI API">How to use </a><a href="overview-summary.html#def-api-Project UI API">Project UI API</a>?
</h2>
<description>
The module supplies the APIs for the basic, generic UI infrastructure for
projects: list of opened projects, main project, basic project-sensitive
actions, template wizards, etc.
</description>
<p></p>
<p>
The main use case is for project type providers to supply logical views and
customizers for the project. Also for template providers to create
project-aware file templates. Can also get a list of open projects, create
different kinds of project-related actions, and select projects on disk.
</p>
<hr>
<h2>
<a name="usecase-Base Project UI API ">How to use </a><a href="overview-summary.html#def-api-Base Project UI API ">Base Project UI API </a>?
</h2>
<description>
The module supplies the APIs for the basic, generic UI infrastructure for
projects: list of opened projects, main project, basic project-sensitive
actions, template wizards, etc.
</description>
<p></p>
<p>
The main use case is for project type providers to supply logical views and
customizers for the project. Also for template providers to create
project-aware file templates. Can also get a list of open projects, create
different kinds of project-related actions, and select projects on disk.
</p>
<hr>
<h2>
<a name="usecase-General Queries API">How to use </a><a href="overview-summary.html#def-api-General Queries API">General Queries API</a>?
</h2>
<description>
General kinds of queries between modules.
Queries are one way of solving the
intermodule communication problem when it is necessary for some modules to
obtain basic information about the system (e.g. whether a particular file is
intended for version control) without needing direct dependencies on the
module providing the answer (e.g. the project type which controls the file).
Details are covered in the Javadoc.
</description>
<p></p>
<p>
Particular use cases are enumerated in the Javadoc for each query API. Usage
consists of simple static method calls. Potentially a wide variety of modules
could use these queries; implementations are typically registered by project
type providers, though also by Java library and platform implementations.
</p>
<hr>
<h2>
<a name="usecase-Refactoring API">How to use </a><a href="overview-summary.html#def-api-Refactoring API">Refactoring API</a>?
</h2>
<description>
Refactoring module allows developer to do high level code transformations aka refactorings.
</description>
<p></p>
Refactoring module provides API for refactorings. The idea is that at least the most elementary set of refactorings should be
available via an API, so that the refactorings could be invoked programmatically. This is particulary useful when creating more
complex refactorings. These can then be composed from the primitive refactorings accessible via an API using delegation. As an example we can use
a simple rename refactoring. When renaming a class in a J2SE environment, simple rename refactoring (which renames all occurrences of
the class) is sufficient. However in a J2EE environment, renaming a class may require renaming of other classes to preserve the functionality
of the application (e.g. synchrinized renaming a home and remote interface for an EJB). This could be achieved by creating a more complex rename
refactoring composed of two simple rename refactorings (one for each class to be renamed).
<p></p>
When analyzing flow of various refactorings, we have found out that the steps in the flow are very common for all
refactorings. The flow is as follows:
<ul>
<li>User selects an object (or set of objects) and chooses to invoke a particular refactoring on it.</li>
<li>Refactoring pre-conditions are checked - whether a given refactoring can be invoked on a given object (or set of objects) or not. User needs to be
presented with errors (if any). The errors can be fatal or non-fatal. If an error is fatal, it means the refactoring cannot be performed, if it is not
fatal, user should be notified of the problem but still be able to proceed with the refactoring.</li>
<li>User sets parameters of the refactoring - each refactoring has some input parameters (e.g. new name for an element in case of Rename refactoring).
These parameters need to be set by the client.</li>
<li>Entered values of refactoring parameters are checked - errors (if any) are presented to the user.</li>
<li>Refactoring collects all changes that need to be performed and presents them to the user.</li>
<li>User can choose to not perform a particular set of proposed changes.</li>
<li>Refactoring is performed - all the changes confirmed by user are made to the source code.</li>
</ul>
To make the implementation of various refactorings consistent, the refactoring module provides an API and UI framework that allows these refactorings to be plugged in. This
framework enforces the above flow. Using this framework (set of SPI and API) the refactoring implementor can focus purely on the things specific to that particular refactoring
(specific pre-conditions checks, parameters checks, implementation of changes, etc.) and leave the
functionality that is common for all refactorings (implementation of the flow) up to the framework.
<p></p>
It is quite common that some modules need to be able to affect the behavior of a refactoring. There are 4 typical use-cases when this is desirable:
<ol>
<li>A module wants to implement refactoring features for their own elements. For instance Java Refactoring module wants to implement Refactoring for Java elements.</li>
<li>A module wants to participate in existing refactoring. E.g. refactoring of java files requires refactoring of non-java files in J2EE area. When a code is refactored, these non-java files need to be refactored too.
We can mention JSP files or deployment descriptors as an example.</li>
<li>A module introduces some hidden relationships between several elements. E.g. a single logical EJB consists of several physical classes. When one of these classes are refactored,
the other classes need to be refactored as well.</li>
<li>A module generates some derived code into the guarded blocks. In such case it is desirable that the provider of the guarded block refactors the guarded code, since
the refactoring module itself has no knowledge of where the guarded code comes from.</li>
</ol>
The refactoring module provides hooks for other modules - an SPI that allows other modules to participate in refactorings. The modules can participate on all refactoring
phases from "preCheck" (checking preconditions), through "checkParameters" (checking validity of refactoring parameters) to "prepare" (collecting changes).
Use-cases number 1), 2) and 3) are covered by the same SPI (interfaces RefactoringPluginFactory and RefactoringPlugin). The forth use-case (guarded blocks) are covered by
a separate set of interfaces, since for this use-case the module does not need to participate in all refactoring phases. The refactoring framework itself automatically detects
that a given change points to a code in guarded blocks and requests all registered guarded block providers to handle that situation.
<p></p>
The rest of this section provides simple orientational examples of API/SPI usage.
<p></p>
<b>Refactoring API</b> can be used for programmatical invocation of refactorings and for pluging ui for these refactorings in.
<p>
<i><b>Refactoring API Example:</b></i>
</p>
<i>Intention:</i> Programatically rename java file<code>com/company/Test.java</code> to <code>com/company/RenamedTest.java</code> and update references.
<pre xml:space="preserve">
FileObject fo = ...com/company/Test.java...
RefactoringSession renameSession = RefactoringSession.create("Rename Class");
refactoring = new RenameRefactoring(fo);
Problem pre = refactoring.preCheck();
if (pre!=null &amp;&amp; pre.isFatal()) {
//fatal problem in precheck
return;
}
refactoring.setNewName("RenamedTest");
Problem p = refactoring.prepare(renameSession);
if (p!=null &amp;&amp; p.isFatal()) {
//fatal problem in precheck
return;
}
renameSession.doRefactoring(true /* saveAll */);
</pre>
<p>
<b>Refactoring SPI</b> permit other modules to plug into existing refactorings and allow them to participate.
Client of SPI must implement factory class <code>RefactoringPluginFactory</code> and register this class into Lookup.
</p>
<i><b>Refactoring SPI Example 1:</b></i>
<p>
<i>Intention:</i> Create a plugin for RenameRefactoring, which will participate in existing refactoring (let say in java refactoring)
and renames references in XML files.
</p>
<pre xml:space="preserve">
//implementation of factory class
public class J2EERefactoringFactory implements RefactoringPluginFactory {
public RefactoringPlugin createInstance(AbstractRefactoring refactoring) {
if (refactoring instanceof RenameRefactoring) {
//return our custom instance for RenameRefactoring
if (wantToParticipate(refactoring.getRefactoredObject())
return new J2EERenameRefactoringPlugin((RenameRefactoring) refactoring);
}
if (refactoring instanceof ... {
...
}
return null;
}
}
</pre>
It is necessary to register <code>J2EERefactoringFactory</code> in the lookup:
<pre xml:space="preserve">
META-INF/services/org.netbeans.modules.refactoring.spi.RefactoringPluginFactory
</pre>
<p>
and implement RefactoringPlugin interface:
</p>
<pre xml:space="preserve">
//implementation of RefactoringPlugin
public class J2EERenameRefactoringPlugin implements RefactoringPlugin {
private RenameRefactoring refactoring;
public J2EERenameRefactoringPlugin(RenameRefactoring refactoring) {
this.refactoring = refactoring;
}
public Problem preCheck() {
...
}
public Problem checkParameters() {
...
}
public Problem fastCheckParameters() {
...
}
public void cancelRequest() {
...
}
public Problem prepare(RefactoringElementsBag refactoringElements) {
RenameRefactoring renameRefactor = ((RenameRefactoring)refactoring);
Object element = renameRefactor.getRefactoredObject();
if (...) {
...
//lets add our RefactoringElements for usages found in XML files
refactoringElements.add(refactoring, new XMLRenameRefactoringElement());
}
return null;
}
public class XMLRenameRefactoringElement implements RefactoringElementImplementation {
public void performChange() {
//do change
}
}
</pre>
<i><b>Refactoring SPI Example 2:</b></i>
<i>Intention:</i> Create a module, which will add Rename... to html files
First you must create your ActionsImplementationProvider:
<pre xml:space="preserve">
public class MyProvider extends ActionsImplementationProvider {
public boolean canRename(Lookup lookup) {
Node[] nodes = lookup.lookupAll(Node.class);
if (..one node selected and the node belongs to html...)
return true;
else
return fals;
}
public void doRename(Lookup selectedNodes) {
Node[] nodes = lookup.lookupAll(Node.class);
final FileObject fo = getFileFromNode(nodes[0]);
return new Runnable() {
public void run() {
UI.openRefactoringUI(new RenameRefactoringUI(fo);
}
}
}
}
</pre>
And of course your own RefactoringPlugin and RefactoringPluginFactory see
<i><b>Refactoring SPI Example 1</b></i> and
<i><b>Refactoring SPI Example 2</b></i>
<br>
<i><b>Refactoring SPI Example 3</b></i>
Module wants to implement it's own refactoring preview tree:
Register your own TreeElementFactoryImplementation into META-INF/services
if you want to build your own RefactoringPreview tree.
For instance Java Refactoring understand Java - specific objects e.g.
Projects, Groups, Methods etc.
<pre xml:space="preserve">
public TreeElement getTreeElement(Object o) {
.
.
if (o instanceof SourceGroup) {
return new SourceGroupTreeElement((SourceGroup)o);
} else if (o instanceof SomethingFromJava) {
return new SomethingFromJavaTreeElement((SomethingFromJava) o);
}
</pre>
TreeElement is then displayed in refactoring preview panel.
<br>
<br>
<br>Other usecases are docummented in javadoc.
<ul>
<li>Module wants to add common Refactoring Action into popup. <br>
See <a href="org-netbeans-modules-refactoring-api/org/netbeans/modules/refactoring/api/ui/RefactoringActionsFactory.html" shape="rect">RefactoringActionsFactory</a>
</li>
<li>
http://wiki.netbeans.org/wiki/view/RefactoringFAQ
</li>
</ul>
<hr>
<h2>
<a name="usecase-Java Refactoring">How to use </a><a href="overview-summary.html#def-api-Java Refactoring">Java Refactoring</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-Sampler API">How to use </a><a href="overview-summary.html#def-api-Sampler API">Sampler API</a>?
</h2>
<description>
It allows NetBeans Platform developer to self-sample their application,
which should provide them with a valuable information about CPU
performance problems.
</description>
<p></p>
<p>
<h4>User controlled sampling</h4>
There needs to be a simple API for someone who wants to create simple user
action which starts and stops self-sampling and presents user with sampled
results.
<p></p>
The correct way to achieve this is to call
<code><a href="org-netbeans-modules-sampler/org/netbeans/modules/sampler/Sampler.html" shape="rect">Sampler</a>.createManualSampler</code>,
followed by
<code><a href="org-netbeans-modules-sampler/org/netbeans/modules/sampler/Sampler.html" shape="rect">Sampler</a>.start()</code> and
<code><a href="org-netbeans-modules-sampler/org/netbeans/modules/sampler/Sampler.html" shape="rect">Sampler</a>.stop()</code>.
<h4>Sampling of the slow operation</h4>
Second major use-case of the Sampling API is sampling of the slow operation.
<p></p>
The correct way to achieve this is to call
<code><a href="org-netbeans-modules-sampler/org/netbeans/modules/sampler/Sampler.html" shape="rect">Sampler</a>.createSampler()</code>,
followed by
<code><a href="org-netbeans-modules-sampler/org/netbeans/modules/sampler/Sampler.html" shape="rect">Sampler</a>.start()</code> and
<code><a href="org-netbeans-modules-sampler/org/netbeans/modules/sampler/Sampler.html" shape="rect">Sampler</a>.stopAndWriteTo(DataOutputStream dos)</code>.
</p>
<hr>
<h2>
<a name="usecase-Command Line Parsing API">How to use </a><a href="overview-summary.html#def-api-Command Line Parsing API">Command Line Parsing API</a>?
</h2>
<description>
GetOpts like infrastructure to parse command line arguments with the cooperative
participation of various modules.
</description>
<p></p>
<p>
<h4>Just Parse the Command Line</h4>
There needs to be a simple API for someone who has an array of strings
and wants to parse them. One does not need to search for providers,
just ask the infrastructure to do the parse and get the result.
<p></p>
The correct way to achieve this is to call
<code><a href="org-netbeans-modules-sendopts/org/netbeans/api/sendopts/CommandLine.html" shape="rect">CommandLine</a>.getDefault().process(args)</code>.
<h4>Parse the Command Line with Own Options</h4>
Since version 2.20 one can define own classes with fields and annotate
them with <a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Arg.html" shape="rect">@Arg</a>
annotation. Those classes can then be passed into a
<a href="org-netbeans-modules-sendopts/org/netbeans/api/sendopts/CommandLine.html#create-java.lang.Class...-" shape="rect">
factory method
</a>
that creates new <a href="org-netbeans-modules-sendopts/org/netbeans/api/sendopts/CommandLine.html#create-java.lang.Class...-" shape="rect">command line</a>.
One can then process the arguments as many times as needed via the
<a href="org-netbeans-modules-sendopts/org/netbeans/api/sendopts/CommandLine.html#process-java.lang.String...-" shape="rect">process</a>
method. Example:
<pre xml:space="preserve">
public final class MyOption implements <a href="http://download.oracle.com/javase/8/docs/api/java/lang/Runnable.html" shape="rect">Runnable</a> {
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Arg.html" shape="rect">@Arg</a>(longName="hello")
public String name;
public void run() {
System.out.println("Hello " + name + "!");
}
public static void main(String... args) {
<a href="org-netbeans-modules-sendopts/org/netbeans/api/sendopts/CommandLine.html" shape="rect">CommandLine</a> line = <a href="org-netbeans-modules-sendopts/org/netbeans/api/sendopts/CommandLine.html#create-java.lang.Class...-" shape="rect">CommandLine.create</a>(MyOption.class);
line.<a href="org-netbeans-modules-sendopts/org/netbeans/api/sendopts/CommandLine.html#process-java.lang.String...-" shape="rect">process</a>(args);
}
}
</pre>
<p>
If the above main class is called with parameters <code>--hello World</code> it
will print out <code>Hello World!</code>.
</p>
<h4>Short and Long options with or without an argument</h4>
The standard <code>getopts</code> supports short form of options - e.g. a dash
followed with one letter - or long form using two dashes followed with a word.
Moreover the long form is optimized for abbrevations. If there are no
conflicts between multiple options, then one can only use double dash followed
with a prefix of a long option.
<p></p>
When using the <a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Arg.html" shape="rect">declarative annotation style</a>
one can always specify
<code><a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Arg.html" shape="rect">@Arg</a>(longName="text", shortName='t')</code>.
The <code>longName</code> attribute is required, but if there is supposed to be
no long version of the argument, it can be set to empty string.
<p></p>
One can create an <a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Option.html" shape="rect">Option</a>
by calling any of its factory methods
(like
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Option.html#withoutArgument-char-java.lang.String-" shape="rect">withoutArgument</a>)
and provider <code>char</code> for the one letter option and/or string for
the long getopts option.
<h4>Options with or without an argument</h4>
There are three types of options. Those without an argument, those with
a required one and those with optional one. Each one can be created
by appropriate factory method in the
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Option.html" shape="rect">Option</a> class.
<p></p>
When using the <a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Arg.html" shape="rect">declarative annotation style</a>
one needs to annotate a field of type <code>boolean</code> to create
an option without an argument.
<h4>Support for --</h4>
The getopts compliant command line parsers support <q>--</q>. If
these characters do appear on the command line, the rest of it is
treated as extra arguments and not processed. The sendopts infrastructure
supports this as well.
<h4>Multiple Independent CLI Handlers</h4>
The handlers for the options need not know about each other and still
have to be able to process the command line successfully. Any module
which wishes to provide its own options can register its
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/OptionProcessor.html" shape="rect">OptionProcessor</a>
with <a href="./org-openide-util-lookup/org/openide/util/lookup/ServiceProvider.html" shape="rect">@ServiceProvider</a>
annotation. Alternatively the module can use the
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Arg.html" shape="rect">@Arg</a> annotation
of its fields and it will be registered as well.
<h4>Extensible Options Set</h4>
<p>
<b>Q:</b> How shall one write an
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/OptionProcessor.html" shape="rect">OptionProcessor</a>
that recognizes set of basic options, however contains one open <q>slot</q>?
The processor wants other modules to provide recognizers for that slot
and wants to communicate with them. For example, by default the processor
recognizes option <code>--channel &lt;name_of_the_channel&gt;</code>
which describes a source of data, and stores such data into a <q>sink</q>.
There can be multiple sinks - discard the output, save it to file, show
it on stdout, stream it to network. The processor itself can handle the
copying of data, but does not itself know all the possible <q>sink</q>
types.
</p>
<p>
To implement
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/OptionProcessor.html" shape="rect">OptionProcessor</a>
like this one shall define an additional interface to communicate with
the <q>sink</q> providers:
</p>
<pre xml:space="preserve">
package my.module;
public interface SinkProvider {
/** gets the option (even composite) that this sink needs on command line */
public Option getOption();
/** processes the options and creates a "sink" */
public OutputStream createSink(Env env, Map&lt;Option,String[]&gt; values) throws CommandException;
}
</pre>
<p>
Other modules would then registered implementations of this
interface in the
<code>META-INF/services/my.module.SinkProvider</code> files.
The
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/OptionProcessor.html" shape="rect">OptionProcessor</a>
itself would just look all the implementations up, queried for
the <q>sinks</q>, and then did the copying:
</p>
<pre xml:space="preserve">
class CopyingProvider extends OptionProvider {
public Option getOption() {
List&lt;Option&gt; l = ...;
for (SinkProvider sp : Lookup.getDefault().lookupAll(SinkProvider.class)) {
l.add(sp.getOption());
}
// we need only one provider to be present
Option oneOfSinks = OptionGroups.oneOf(l.toArray(new Option[0]));
// our channel option
Option channel = ...;
// the channel option needs to be present as well as a sink
return OptionGroups.allOf(channel, oneOfSinks);
}
public void process(Env env, Map&lt;Option,String[]&gt; values) throws CommandException {
OutputStream os = null;
for (SinkProvider sp : Lookup.getDefault().lookupAll(SinkProvider.class)) {
if (values.containsKey(sp.getOption())) {
os = sp.createSink(env, values);
break;
}
}
if (os == null) {
throw CommandException.exitCode(2);
}
// process the channel option and
// handle the copying to the sink <code>os</code>
}
}
</pre>
<p>
Another possible approach how to allow sharing of one option between
multiple modules is to expose the option definition and its handling
code as an interface to other modules, and then let the modules
to write their own
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/OptionProcessor.html" shape="rect">OptionProcessor</a>s.
Necessary condition is that each of the processor is uniquely
identified by some additional option, so when the shared option appears
the infrastructure knows which processor to delegate to.
This is demonstrated in the
<a href="http://www.netbeans.org/source/browse/contrib/sendopts/test/unit/src/org/netbeans/api/sendopts/Attic/SharedOptionTest.java?rev=1.1.2" shape="rect">
SharedOptionTest</a> which
basically does the following:
</p>
<pre xml:space="preserve">
/** the shared option, part of an interface of some module */
public static final Option SHARED = ...;
/** finds value(s) associated with the SHARED option and
* creates a JPanel based on them */
public static JPanel getSharedPanel(Map&lt;Option,String[]&gt; args) { ... }
</pre>
<p>
Then each module who wishes to reuse the SHARED option and the
factory method that knows how to process their values for their
own processing can just:
</p>
<pre xml:space="preserve">
public static final class ShowDialog extends OptionProcessor {
private static final Option DIALOG = Option.withoutArgument('d', "dialog");
protected Set&lt;Option&gt; getOptions() {
// the following says that this processor should be invoked
// everytime --dialog appears on command line, if the SHARED
// option is there, then this processor wants to consume it
// as well...
return Collections.singleton(Option.allOf(DIALOG, Option.anyOf(SHARED)));
}
protected void process(Env env, Map&lt;Option, String[]&gt; optionValues) throws CommandException {
JPanel p = getSharedPanel(optionvalues);
if (p == null) {
// show empty dialog
} else {
// show some dialog containing the panel p
}
}
}
</pre>
<p>
The other modules are then free to write other processors refering to
<code>SHARED</code>, for example one can write <code>ShowFrame</code>
that does the same, just shows the panel in a frame, etc. The infrastructure
guarantees that the exactly one provider which matches the command
line options is called.
</p>
<h4>Printing Full Help Text</h4>
Althrough the handlers are provided by independent parties, it must be possible
to generate resonable and consistent help description from all of them,
so for the end user it appears as well formated and easily understandable.
That is why
every option can be associated with a short description providing info
about what it is useful for using
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Option.html#shortDescription-org.netbeans.spi.sendopts.Option-java.lang.String-java.lang.String-" shape="rect">
Option.shortDescription
</a> method. When using the
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Arg.html" shape="rect">@Arg</a> style, there
is an additional <a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Description.html" shape="rect">@Description</a>
annotation which can be used to declaratively associate a localized display name
and short description with the option.
To get such descriptions for all available options one
can use
<a href="org-netbeans-modules-sendopts/org/netbeans/api/sendopts/CommandLine.html#usage-java.io.PrintWriter-" shape="rect">
CommandLine.getDefault().usage(java.io.PrintWriter)</a>.
<h4>Finding and Reporting when Options Are Not Correct</h4>
In case the command line cannot be processed a clean error for programmatic
consumation and also one that can be shown to the end user of the command
line must be given. This is handled by throwing
<a href="org-netbeans-modules-sendopts/org/netbeans/api/sendopts/CommandException.html" shape="rect">CommandException</a>
with appropriate message description and exit code.
<h4>Processing Extra Command Line Arguments</h4>
There can be non-option arguments in the command line and they can freely
mix with the option ones. For example the getopts would treat the following
command line arguments as the same:<pre xml:space="preserve">
--open X.java Y.java Z.txt
X.java Y.java --open Z.txt
</pre> if the option <q>open</q> handles <q>extra arguments</q>.
The sendopts infrastructure must distinquish between them
and pass the non-option ones to the only one handler (active because it
processed an option) that knowns how to
parse them. It is an error if more than one or no handler expresses
an interest in extra arguments and those are given. One can register
such option by using the <code>
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Option.html#additionalArguments-char-java.lang.String-" shape="rect">
Option.additionalArgument
</a>
</code> factory method.
<p></p>
When using the
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Arg.html" shape="rect">declarative annotation style</a>
one may annotate a field of type <code>String[]</code> which then means
this field should be filled with all additional arguments.
<h4>Handling Input and Output</h4>
Handler's shall not use the input and output streams directly for their execution, they should
rely on the framework provided ones. This allows NetBeans based application to
transfer the I/O from second started instance to the master one which
is already running. From the client side there is the
<code><a href="org-netbeans-modules-sendopts/org/netbeans/api/sendopts/CommandLine.html" shape="rect">CommandLine</a>.getDefault().parse</code>
methods taking additional arguments like input and output streams.
This gets transfered to providers as an
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Env.html" shape="rect">Env</a>
argument of their methods.
<h4>Returning Exit Code</h4>
When Handler's get execute (in the order defined by the order of options
on the command line), each of them can either execute successfully, or
fail. If a handler succeeds, next one is executed, if it fails, the
execution is terminated and its return code is returned to the caller.
The error can be notified by creating and throwing
<a href="org-netbeans-modules-sendopts/org/netbeans/api/sendopts/CommandException.html" shape="rect">CommandException.exitCode(int errorCode)</a>.
<h4>Processing Only Extra Command Line Arguments</h4>
Sometimes it is desirable to process non-option arguments like file names
without providing any option. Handlers can declare interest in such arguments.
It is an error if such non-options are provided and no or more than one
handler is around to handle them. One can create such option by
using <code>
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Option.html#defaultArguments--" shape="rect">Option.defaultArguments</a>
</code> factory method. With the
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Arg.html" shape="rect">declarative annotation style</a>
one can annotate a field of type <code>String[]</code> and specify that
it is supposed to be <a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Arg.html#implicit--" shape="rect">implicit</a>.
<h4>Only those processor need to process the options are created</h4>
For purposes of usage in NetBeans, it is needed to not-initialize those
handlers that are not really needed to process certain command line.
The infrastructure decides which of them are going to be needed and
instantiates only those. This is supported only when using the
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Arg.html" shape="rect">declarative annotation style</a> -
information about these options is recorded in declarative way and the
system can decide without loading the provider classes whether they are
present on the command line or not.
<h4>Complex Option Relations</h4>
Certain CLI processors may need more than one option before they
can process the input. For example it is necesary to tune the radio
and then also tell what to do with the output. It is unconvenient
to process that as one option with argument(s), that is why one can
use the
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/OptionGroups.html#allOf-org.netbeans.spi.sendopts.Option...-" shape="rect">
OptionGroups.allOf</a>,
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/OptionGroups.html#someOf-org.netbeans.spi.sendopts.Option...-" shape="rect">
OptionGroups.someOf</a>, for example like: <pre xml:space="preserve">
class PP extends OptionProcessor {
private static Option tune = Option.requiredArgument(Option.NO_SHORT_NAME, "tune");
private static Option stream = Option.requiredArgument(Option.NO_SHORT_NAME, "stream");
public Set&lt;Option&gt; getOptions() {
return Collections.singleton(
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/OptionGroups.html#allOf-org.netbeans.spi.sendopts.Option...-" shape="rect">OptionGroups.allOf</a>(tune, stream)
);
}
public void process(Env env, Map&gt;Option,String[]&gt; values) throws CommandException {
String freq = values.get(tune)[0];
String output = values.get(stream)[0];
// XXX handle what is needed here
}
}
</pre>
When the two options are registered and command line like
<q>--tune 91.9 --stream radio1.mp3</q> is being processed, the
<code>PP</code>'s <code>process</code> method is going to get
called with values <q>91.9</q> and <q>radio1.mp3</q>.
<p></p>
This kind of grouping is not currently supported with the
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/Arg.html" shape="rect">declarative annotation style</a>
registration.
<h4>Alternative Options</h4>
Sometimes there may different ways to specify the same option and
just one of them or none of them can be provided at given time.
For example is there is a way to tune the radio with direct frequency
or with name of the station. Just one can be provided and one is needed.
This can be specified by using
<a href="org-netbeans-modules-sendopts/org/netbeans/spi/sendopts/OptionGroups.html#oneOf-org.netbeans.spi.sendopts.Option...-" shape="rect">
OptionGroups.oneOf</a> factory methods:
<pre xml:space="preserve">
Option freq = Option.requiredArgument(Option.NO_SHORT_NAME, "tune");
Option station = Option.requiredArgument(Option.NO_SHORT_NAME, "station");
Option tune = OptionGroups.oneOf(freq, station);
</pre>
The option <code>tune</code> then signals that just one of the station or
freq options can appear and that they both are replaceable.
</p>
<hr>
<h2>
<a name="usecase-Common Server">How to use </a><a href="overview-summary.html#def-api-Common Server">Common Server</a>?
</h2>
<description>
Allows UI presentation of server instance without dependency on a server
specific API (like j2eeserver).
</description>
<p></p>
<h4>Registering the server/cloud instance provider</h4>
<p>
An external module can register itself as the server instance provider.
In order to do that it must register the implementation of
<a href="org-netbeans-modules-server/org/netbeans/spi/server/ServerInstanceProvider.html" shape="rect">ServerInstanceProvider</a>
in <code>Servers</code> or <code>Cloud</code> folder in the layer.xml.
</p>
<p>
When this is done the module will handle displaying of instances at appropriate
IDE dialogs and views. Note that more specific SPIs can still be required
for the technology specific dialogs and actions. This module covers the areas
where the "common server" term makes sence.
</p>
<p>
Every
<a href="org-netbeans-modules-server/org/netbeans/spi/server/ServerInstanceImplementation.html" shape="rect">ServerInstance</a>
returned by the provider is handled by this module. Some features of the
<a href="org-netbeans-modules-server/org/netbeans/spi/server/ServerInstanceImplementation.html" shape="rect">ServerInstance</a>
are not mandatory (as described in javadoc). If new instances can be added
or removed during the lifecycle of external module it has to notify all
listeners of the
<a href="org-netbeans-modules-server/org/netbeans/spi/server/ServerInstanceProvider.html" shape="rect">ServerInstanceProvider</a>.
</p>
<h4>Registering the server/cloud wizard</h4>
<p>
An external module can register the wizard(s) in order to allow the user
to add new instances. In order to do that it must register the implementation of
<a href="org-netbeans-modules-server/org/netbeans/spi/server/ServerWizardProvider.html" shape="rect">ServerWizardProvider</a>
in <code>Servers</code> or <code>Cloud</code> folder in the layer.xml.
</p>
<p>
When this is done the module will offer this wizard in UI (at contexts where
it makes sense).
</p>
<h4>Persisting instance properties</h4>
<p>
The Commons Server SPI implemetor has to usually implement persistence
of its instances somehow. There are many ways how this can be done.
To make it easier
<a href="org-netbeans-modules-server/org/netbeans/api/server/properties/InstancePropertiesManager.html" shape="rect">InstancePropertiesManager</a>
can be used. It provides a way how to store and retrieve properties of
the server instance.
</p>
<hr>
<h2>
<a name="usecase-UI Gestures Collector Infrastructure">How to use </a><a href="overview-summary.html#def-api-UI Gestures Collector Infrastructure">UI Gestures Collector Infrastructure</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<h4>Gather information about UI gestures</h4>
<p>
Primary purpose of this module is collect information about
the user actions that take place in the running NetBeans based
application.
</p>
<p>
<api category="devel" group="logger" name="UI_LOGGER_NAME" type="export">
The info about various UI events in the system is collected thru
listening on
<a href="http://download.oracle.com/javase/8/docs/api/java/util/logging/LogRecord.html" shape="rect">log records</a> send to
<a href="http://download.oracle.com/javase/8/docs/api/java/util/logging/Logger.html" shape="rect">
Logger.getLogger(UI_LOGGER_NAME_VALUE)
</a>, where UI_LOGGER_NAME_VALUE is a value of UI_LOGGER_NAME
resource bundle key, defining the name of the UI usage logger.
Any code in the system can get instance of this logger
or any child logger and send useful informations to it.
At the end of the session the last few hundereds events
is taken and displayed to the user for further processing.
</api>
<api category="devel" group="logger" name="METRICS_LOGGER_NAME" type="export">
The info about various UI events in the system is collected thru
listening on
<a href="http://download.oracle.com/javase/8/docs/api/java/util/logging/LogRecord.html" shape="rect">log records</a> send to
<a href="http://download.oracle.com/javase/8/docs/api/java/util/logging/Logger.html" shape="rect">
Logger.getLogger(METRICS_LOGGER_NAME_VALUE)
</a>, where METRICS_LOGGER_NAME_VALUE is a value of
METRICS_LOGGER_NAME resource bundle key, defining the name
of the metrics logger.
Any code in the system can get instance of this logger
or any child logger and send useful informations to it.
At the end of the session the last few hundereds events
is taken and displayed to the user for further processing.
</api>
</p>
<h4>Presenting usage statistics</h4>
<p>
Important part of the behaviour of this module is the ability
to cooperate with information analyzing tools and present their
results. This is done thru special HTTP contracts, where the
module reads and understands various server responses and is
able to open browser after submitting data to analysis.
</p>
<p>
<api category="private" group="property" name="WELCOME_URL" type="export">
There is a key in the <code>org.netbeans.modules.uihandler.Bundle</code>
that specifies the location of the page on a server one shall
query and display to the user when the module is about the
submit usage data for analysis.
</api>
<api category="private" group="property" name="METRICS_URL" type="export">
There is a key in the <code>org.netbeans.modules.uihandler.Bundle</code>
that specifies the location of the page on a server one shall
query and display to the user when the module is about the
submit metrics data for analysis.
</api>
<api category="private" group="property" name="ERROR_URL" type="export">
There is a key in the <code>org.netbeans.modules.uihandler.Bundle</code>
that specifies the location of the page on a server one shall
query and display to the user when the module is about the
submit an error report.
</api>
<api category="friend" group="java.io.File" name="WelcomePageContent" type="export">
The page pointed by <code>WELCOME_URL</code> can contain
any XHTML text, but it also should contain a &lt;form/&gt; tag
that defines &lt;input type="hidden" name="submit" value="localizedName"/&gt;.
The <code>localizedName</code> is then going to be used for a button
for the dialog displaying the summary. When this button is invoked,
the "action" URL is then feed with data from the UI logs.
The server is then supposed to process the data, create
some analytics pages and return them back to the client.
If the returned page contains tag like
&lt;meta http-equiv='Refresh' content='3; URL=somepage'&gt;
an (external) browser is opened with the specified URL and
the user can then interact directly with the server, thru
pages it serves.
</api>
<api category="private" group="systemproperty" name="org.netbeans.modules.uihandler.Submit" type="export">
For testing purposes one can
specify different URL for upload of files, by setting
<code>org.netbeans.modules.uihandler.Submit</code>
property when invoking NetBeans.
</api>
</p>
<h4>Adding own UI gestures</h4>
<p>
The base module is in fact just an infrastructure which collects
data about UI gestures, but the actual gestures need to be delivered
to it somehow. Here is the description of the ways how one can
extend own modules to cooperate with this UI gestures infrastructure.
</p>
<p>
To feed own data about special UI gestures one can just create own
<a href="http://download.oracle.com/javase/8/docs/api/java/util/logging/Logger.html" shape="rect">
Logger.getLogger(UI_LOGGER_NAME_VALUE+".ownname")
</a> and send own log records to it.
UI_LOGGER_NAME_VALUE is a value of UI_LOGGER_NAME
resource bundle key, defining the name of the logger.
The format of the log messages shall follow the one described by the
<a href="./org-openide-util/org/openide/util/doc-files/logging.html" shape="rect">
structured logging
</a> document, e.g. the
<a href="http://download.oracle.com/javase/8/docs/api/java/util/logging/LogRecord.html" shape="rect">LogRecord</a>
shall have associated
<a href="http://download.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html" shape="rect">ResourceBundle</a>
and the record's <code>getMessage</code> shall point to a key
in that bundle.
<api category="devel" group="property" name="ICON_BASE" type="export">
there is an extension to the regular formatting done by
the <a href="http://download.oracle.com/javase/8/docs/api/java/util/logging/Formatter.html" shape="rect">logging
formatter</a> that, in order to achieve nicer appearance to
the user, allows each record to be associated with an icon.
Just define <code>MSG_KEY_ICON_BASE</code> in the bundle associated
with the
<a href="http://download.oracle.com/javase/8/docs/api/java/util/logging/LogRecord.html" shape="rect">LogRecord</a>
(where the MSG_KEY is the string returned by <code>record.getMessage()</code>)
and the value is then going to be used for the
<a href="./org-openide-nodes/org/openide/nodes/AbstractNode.html#setIconBaseWithExtension-java.lang.String-" shape="rect">
Node
</a> representing the UI gesture.
</api>
</p>
<p>
Sometimes direct logging may not be possible. For example for
performance data it might be meaningful to collect the information
over a longer time period and only at the end output some statistics.
This is supported as well. Just implement and register one
of the
<api category="devel" group="java" name="CallbackInterfaces" type="export" url="org-netbeans-modules-uihandler/org/netbeans/modules/uihandler/api/Activated.html">interfaces from the API of this module</api>
and properly register
them and the implementation will be called when the logger module
is activated or when the user finishes the work with the application.
In order to keep dependencies clean, it is strongly adviced
to make modules that implement this API
eager,
so they get enabled as soon as the UI logger module is enabled.
</p>
<p>
These usecases are realized as described in
<a href="org-netbeans-modules-uihandler/org/netbeans/modules/uihandler/api/doc-files/ui.html" shape="rect">
here in provided UI specification</a>.
</p>
<hr>
<h2>
<a name="usecase-Versioning">How to use </a><a href="overview-summary.html#def-api-Versioning">Versioning</a>?
</h2>
<description>
The module allows SCM systems to fully integrate into the IDE workflow.
</description>
<p></p>
<p>
Main and Popup Menu usecases come from the UI spec available here:
<a href="http://ui.netbeans.org/docs/ui/VersioningSpecification/" shape="rect">Versioning UI spec</a>
<h4>Main Menu Itegration</h4>
All installed SCM systems must cooperate while constructing popup and main menus, see UI spec.
<h4>Popup Menu Itegration</h4>
All installed SCM systems must cooperate while constructing popup and main menus, see UI spec.
<h4>Coloring and Badging (annotations)</h4>
An SCM system needs a way to annotate labels and icons in the IDE.
<h4>Automated Versioning</h4>
To enable automated versioning (adds, removes, moves, delets), a SCM system needs to integrate at the lowest level
into the IDE's filesystem layer. Refactoring is the most critical filesystem client here.
</p>
<hr>
<h2>
<a name="usecase-Versioning Core">How to use </a><a href="overview-summary.html#def-api-Versioning Core">Versioning Core</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
Main and Popup Menu usecases come from the UI spec available here:
<a href="http://ui.netbeans.org/docs/ui/VersioningSpecification/" shape="rect">Versioning UI spec</a>
<h4>Main Menu Itegration</h4>
All installed SCM systems must cooperate while constructing popup and main menus, see UI spec.
<h4>Popup Menu Itegration</h4>
All installed SCM systems must cooperate while constructing popup and main menus, see UI spec.
<h4>Coloring and Badging (annotations)</h4>
An SCM system needs a way to annotate labels and icons in the IDE.
<h4>Automated Versioning</h4>
To enable automated versioning (adds, removes, moves, delets), a SCM system needs to integrate at the lowest level
into the IDE's filesystem layer. Refactoring is the most critical filesystem client here.
</p>
<hr>
<h2>
<a name="usecase-Extensible Abstract Model (XAM)">How to use </a><a href="overview-summary.html#def-api-Extensible Abstract Model (XAM)">Extensible Abstract Model (XAM)</a>?
</h2>
<description>
The xam module (XAM Module) provides a framework for domain model developers
to use when creating new models. This framework was started to encapsulate
common practices used when creating XML based models for XML schema and WSDL.
List of the main features:
Definition and partial implementation of both a generic and XML
specific model. The model supports eventing, Undo/Redo, sync, and
simple transactions. XML based models extend generic models and add support
for resolution.
</description>
<p></p>
<p>
<h4>domain model developer</h4>
A domain model developer would determine the appropriate extension
package. A model outside of XML would extend org.netbeans.modules.xml.xam.AbstractModel,
and have the components in the domain extend org.netbeans.modules.xml.xam.AbstractComponent.
The org.netbeans.modules.xml.xam.AbstractFactory can also be used for creation
of models. The factory provides the creational, the model provides the entry point
into the domain model as well as a concrete reference point to register for
events. The component serves as the root of the domain level objects. This
provides some consistency across models as the original intention was to be
able to provide a unified model across different XML vocabularies.
An XML model developer would likely want to start using the XDM model
which provides the full fidelty XML document model. This is in the xml/xdm
module (described seperately). The XML module developer would also incorporate
the facilities for reading and writing to a catalog. This is incorporated
into methods available to subclasses in the xam.dom and xdm.xam models. The
project based catalog facility provides the ability to support versioned
catalog files which allow local access but URL based location attributes.
</p>
<hr>
<h2>
<a name="usecase-XML Document Model (XDM)">How to use </a><a href="overview-summary.html#def-api-XML Document Model (XDM)">XML Document Model (XDM)</a>?
</h2>
<description>
The XDM module provides a basis for tool ready XML language models that require full
document fidelity, undo/redo, and the ability to sync with the underlying source.
List of the main features:
Support for full document fidelity. The users text including spacing and
comments are preserved.
Undo / Redo is supported using the concept of an immutable tree. XDM nodes
do not have parent pointers (only a pointer to the model). Thus a node can
be in multiple trees, where each tree is a version. When a mutation to the tree
occurs a clone is made of each node in the parent path from the root to the mutated
node. All unchanged nodes are simply referenced and thus will live in multiple
trees. Thus an undo / redo is simply a reference change. The cost of storing
multiple tree is minimized as only the diffs are stored in each version of the
tree.
The visitor pattern is used in addition to the DOM interfaces which allows
easier tree walking
An XML diff visitor supports XML difference. Element identity can be
supplied by the client.
</description>
<p></p>
<p>
The typical client of XDM would be a tool author supporting an XML language
who wants to provide a custom client API. A concrete example of this is the XML
Schema model. The XML Schema model starts by subclassing AbstractXDMModel and
providing the component updater, which is called in conjunction with sync
to mutate the model according to changes in the underlying source.
<h4>WSDL model</h4>
The WSDL model is based on the XDM model and relies on the XDM capabilities
to provide the infrastructure necessary for providing a XAM based model.
<h4>Schema model</h4>
The Schema model is based on the XDM model and relies on the XDM capabilities
to provide the infrastructure necessary for providing a XAM based model.
<h4>BPEL model</h4>
The BPEL model is based on the XDM model and relies on the XDM capabilities
to provide the infrastructure necessary for providing a XAM based model.
The XDM model can be used in standalone mode.
<code>
<br>
<br>
BaseDocument sd = ...;
<br>
Lookup lookup = Lookups.singleton(sd);
<br>
// create an editable ModelSource with base document
<br>
// in the lookup (this is required)
<br>
ModelSource ms = new ModelSource(lookup, true);
<br>
// create an XDMModel
<br>
XDMModel model = new XDMModel(ms);
<br>
// sync the XDM model with the underlying source
<br>
model.sync();
<br>
// create customer element, same as dom
<br>
Element customer = model.getDocument().createElement("customer");
<br>
// add to the model as 0th child of employee element, not shown
<br>
model.add(employee,customer,0);
<br>
</code>
</p>
<hr>
<h2>
<a name="usecase-Debugger Core - UI">How to use </a><a href="overview-summary.html#def-api-Debugger Core - UI">Debugger Core - UI</a>?
</h2>
<description>
The debuggercore module (Debugger Core UI) contains shared UI components for all debugger implementations, and defines some SPI
for sharing of them.
</description>
<p></p>
<h2>UseCase I. - Install
and use CPP debugger plug-in to NetBeans + Java Debugger.</h2>
<span style="font-style: italic;">CPP debugger plug-in installs support
for debugging of some new language to the NetBeans IDE, and some new
debugging engine. This implementation of debugger should share UI
components (actions, Debugger Views, ...) with default NB Java
Debugger. It should share basic debugger model too - notion of current
context, current session, thread, call stack line, ...</span>
<br>
<br>
CPP debugger plug-in installs:<br>
<ul>
<li>New set of breakpoint types - CPPLineBreakpointType,
CPPMethodBreakpointType...
<ul>
<li>This set of breakpoint types will have special cathegory in Add
Breakpoint Dialog called "CPP". Each breakpoint type will install a new
JPanel to Add Breakpoint Dialog.</li>
<li>ToggleBreakpointAction on CPP files will create / remove a
instance of CPPLineBreakpointType.</li>
</ul>
</li>
<li>Install some watches evaluator for CPP language.</li>
<li>Some new View to Debugger Window</li>
<li>Use Termilnal Emulator in Output Window as command line interface
to CPP debugger plug-in.</li>
<li>Install / uninstall a columns to / from standard Debugger Window
Views.</li>
<li>Redefine Nodes used for representation of CPP threads, watches,
variables, callstacks, sessions and breakpoints
<ul>
<li>Add / remove some properties<br>
</li>
<li>Add / remove some actions</li>
<li>change icons</li>
<li>change display names</li>
</ul>
</li>
<li>Register CPP Actions for:
<ul>
<li>Step Into, Over, Out, Continue, Pause, Start, Kill, Restart,
Finish</li>
</ul>
</li>
<li>Some new CPP specific actions.</li>
</ul>
<br>
<h2>UseCase II. -
Install and use JSP debugger plug-in to NetBeans + Java Debugger.</h2>
<span style="font-style: italic;">JSP debugger plug-in installs support
for debugging of some new language to the NetBeans Java Debugger. It
does not contain a new debugger engine, but it delegates to standard NB
Java debugger. So it does not depends on Debugger Core API only, but it
depends on JavaDebugger API too.<br>
<br>
JSP debugger plug-in installs:<br>
</span>
<ul>
<li>New set of breakpoint types - JSPLineBreakpointType, ...
<ul>
<li>This set of breakpoint types will have special cathegory in Add
Breakpoint Dialog called "JSP". Each breakpoint type will install a new
JPanel to Add Breakpoint Dialog.</li>
<li>ToggleBreakpointAction on JSP files will create / remove a
instance of JSPLineBreakpointType.</li>
<li>JSPLineBreakpointType delegates all functionality to
JPDAClassBreakpoint and JPDALineBreakpoint<br>
</li>
</ul>
</li>
<li>Some watches evaluator for JSP language expression. This
evaluator delegates evaluation of Java expressions to standard
JavaExpressionEvaluator.<br>
</li>
<li>Redefine Nodes used for representation of JSP callstacks and
breakpoints
<ul>
<li>Add / remove some properties<br>
</li>
<li>Add / remove some actions</li>
<li>change icons</li>
<li>change display names</li>
</ul>
</li>
<li>Register JSP Actions for:
<ul>
<li>Step Into, Over, Out</li>
<li>Implementation of this actions delegates to standard Java Step
actions - it redefines Java stepping functionality.</li>
</ul>
</li>
<li>JSP debugger plug in adds support for new programming language
(JSP) to already running Java Session.<br>
</li>
</ul>
<br>
<h2>UseCase III. -
Install and use J2EE debugger plug-in to NetBeans + Java Debugger.</h2>
<span style="font-style: italic;">J2EE debugger plug-in installs some
enhancements to the standard Java Debugger. It
does not contain a new debugger engine or language support. So it does
not depends on Debugger Core API only, but it
depends on JavaDebugger API too.<br>
<br>
J2EE debugger plug-in installs:<br>
</span>
<ul>
<li>New set of breakpoint types</li>
<li>Filter for Threads and Callstack Views. This filter should allow
to:<br>
<ul>
<li>Add / remove / modify nodes in this views.</li>
</ul>
</li>
<li>Redefine Stepping (Smart Stepping) behaviour of default Java
Debugger.</li>
<li>Some new View to Debugger Window</li>
</ul>
<br>
<h2>UseCase IV. -
Install and use DBX debugger plug-in to NetBeans.</h2>
<span style="font-style: italic;">DBX debugger plug-in installs support
for debugging of some new language (CPP) to the NetBeans IDE, and some
new
debugging engine. But it contains debugger engine for Java debugging
too. DBX debugger engine has its own session management (or will have
in the next versions). One debugger engine can manage more than one
sessions. One engine supports debugging in more than one language.<br>
<br>
</span>
<h2>UseCase V. -
Implement Debugger Core UI module on top of Debugger Core API / SPI.</h2>
<span style="font-style: italic;">Debugger Core UI needs:<br>
</span>
<ul>
<li>List all breakpoint types and all breakpoint cathegories.</li>
<li>Visually customize all breakpoints - some panel.</li>
<li>Add / remove breakpoints.</li>
<li>Add / remove watches.<br>
</li>
<li>Represent breakpoints, threads, thread groups, watches, sessions,
call stack frames, locales, and fields as Nodes in NB Explorer View.</li>
<li>List all threads, thread groups, locales, watches, breakpoints,
callstack frames, and fields.</li>
<li>Listen on changes of hierarchy of threads, thread groups,
locales, watches, breakpoints, callstack frames, and fields.</li>
<li>Some current context definition. Current contet should define
current session, language, thread, and call stack line.</li>
</ul>
<br>
<hr>
<h2>
<a name="usecase-Editor Hints">How to use </a><a href="overview-summary.html#def-api-Editor Hints">Editor Hints</a>?
</h2>
<description>
XXX no answer.
</description>
<p></p>
<p>
<h4>redunderline</h4>
Assume that you have a module using e.g. Parsing API to parse the source
files and wants to mark the errors in the editor to be shown as red
underlined in the editor. Here is the pseudo code that achieves this:
<pre xml:space="preserve">
Document doc = ...;
ArrayList&lt;ErrorDescription&gt; errors = new ArrayList&lt;ErrorDescription&gt;();
for (&lt;all errors from the parser that have parsed the doc&gt;) {
errors.add(
<b>ErrorDescriptionFactory.createErrorDescription</b>(
Severity.ERROR,
d.getMessage(Locale.getDefault()),
doc,
doc.createPosition(start),
doc.createPosition(end)
)
);
}
<b>HintsController.setErrors</b>(doc, "myerrors", errors);
</pre>
<h4>warningwithfix</h4>
Adding a warning with fixes:
<pre xml:space="preserve">
static final class FixImpl implements Fix {
...
}
...
Document doc = ...;
List&lt;Fix&gt; <b>fixes</b> = Arrays.&lt;Fix&gt;asList(new FixImpl(...));
ArrayList&lt;ErrorDescription&gt; warnings = new ArrayList&lt;ErrorDescription&gt;();
for (&lt;all places where the warning should be displayed&gt;) {
warnings.add(
ErrorDescriptionFactory.createErrorDescription(
Severity.WARNING,
displayName,
<b>fixes</b>,
doc,
doc.createPosition(start),
doc.createPosition(end)
)
);
}
HintsController.setErrors(doc, "mywarnings", warnings);
</pre>
</p>
<hr>
<h2>
<a name="usecase-Java Hints SPI">How to use </a><a href="overview-summary.html#def-api-Java Hints SPI">Java Hints SPI</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
<h4>Creating a new Java Hint</h4>
Simple way to create a new Java hint is as follows:
<ul>
<li>Create a new class, annotate it with the <a href="org-netbeans-spi-java-hints/org/netbeans/spi/java/hints/Hint.html" shape="rect">@Hint</a>
annotation to it.</li>
<li>Create a <code>public static ErrorDescription hint(HintContext ctx) {}</code> method in the
class. Annotate the method either with the <a href="org-netbeans-spi-java-hints/org/netbeans/spi/java/hints/TriggerPattern.html" shape="rect">@TriggerPattern</a>
annotation (strongly recommended), or with the <a href="org-netbeans-spi-java-hints/org/netbeans/spi/java/hints/TriggerTreeKind.html" shape="rect">@TriggerTreeKind</a>.
This method will be called when for parts of the code that match the given pattern, of for trees of the specified kinds.</li>
<li>Perform whatever checks necessary to find out whether a warning should be produced at the given place, and produce the ErrorDescription if needed.</li>
</ul>
<br>
Tips:
<ul>
<li>Always use the java.hints' <a href="org-netbeans-spi-java-hints/org/netbeans/spi/java/hints/ErrorDescriptionFactory.html" shape="rect">ErrorDescriptionFactory</a> to produce the resulting ErrorDescription.</li>
<li>Never try to produce a custom suppress warnings "fix". Specify suppress warnings keys in the @Hint annotation.</li>
<li>If an automated transformation is to be prodived from your hint, subclass <a href="org-netbeans-spi-java-hints/org/netbeans/spi/java/hints/JavaFix.html" shape="rect">JavaFix</a> and
use its <code>toEditorFix()</code> method to get the <code>Fix</code>, if the transformation is going to be used inside Inspect&amp;Transform.
</li>
<li>The name of the method is arbitrary, one hint can consist of more that one "triggered" method.</li>
</ul>
<h4>Creating a new Java Hint Without a Class</h4>
For simple hints, it is possible to annotate the hint method with the <a href="org-netbeans-spi-java-hints/org/netbeans/spi/java/hints/Hint.html" shape="rect">@Hint</a> annotation.
The hint then consists of this sole method. Any number of such hints may be created in a single class.
<h4>Creating a Tests for the Newly Created Java Hint</h4>
Creating automated tests for the hints is simple: create a test class, and use
<a href="org-netbeans-spi-java-hints/../org-netbeans-modules-java-hints-test/org/netbeans/modules/java/hints/test/api/HintTest.html" shape="rect">HintTest</a>
to setup the test, run the hint and verify that its outcomes are correct.
The tests automatically run with <code>test</code> branding, so create <code>Bundle_test.properties</code>, and add
bundle keys into it for ErrorDescription and Fix display names, to isolate the test from changes in the production
<code>Bundle.properties</code>.
<h4>Adding options to a Java Hint</h4>
To add a simple boolean option to your hint, use <a href="org-netbeans-spi-java-hints/org/netbeans/spi/java/hints/BooleanOption.html" shape="rect">@BooleanOption</a>.
</p>
<hr>
<h2>
<a name="usecase-Navigator API">How to use </a><a href="overview-summary.html#def-api-Navigator API">Navigator API</a>?
</h2>
<description>
Navigator module is a base API module which provides:
A place for modules to show structure/outline of their documents
Ability for modules to show their view only when special document(node)
is active in the system
UI for switching between multiple views available for currently active document(node)
Coalescing of fast coming selected node changes to show content for
</description>
<p></p>
<h4>Basic Usage Steps</h4>
In order to plug in a view into Navigator UI for certain document (data) type,
module writers need to write a <a href="org-netbeans-spi-navigator/org/netbeans/spi/navigator/NavigatorPanel.html" shape="rect">NavigatorPanel</a>
implementation marked with <code>@Registration</code>.
<h4>Writing NavigatorPanel implementation</h4>
<p>Implementing <a href="org-netbeans-spi-navigator/org/netbeans/spi/navigator/NavigatorPanel.html" shape="rect">NavigatorPanel</a>
interface is easy, you can copy from template basic implementation
<a href="org-netbeans-spi-navigator/org/netbeans/spi/navigator/doc-files/BasicNavPanelImpl_java" shape="rect">BasicNavPanelImpl.java</a>.</p>
Advices on important part of panel implementation:
<ul>
<li>
<b>Instantiation:</b> Your implementation of NavigatorPanel
is instantied automatically by the system if you register it using <code>@Registration</code>.</li>
<li>
<b>getComponent</b> method: Simply create and return your UI
representation of your data in Swing's JComponent envelope. Just be sure
that you don't create new JComponent subclass per every call, as
performance will suffer then.<p></p>
</li>
<li>
<b>panelActivated and panelDeactivated</b> methods wraps an
'active' life of your panel implementation. In panelActivated, grab
your data from given <a href="./org-openide-util-lookup/org/openide/util/Lookup.html" shape="rect">Lookup</a>,
usually by looking up its asociated
<a href="./org-openide-loaders/org/openide/loaders/DataObject.html" shape="rect">DataObject</a>
or
<a href="./org-openide-filesystems/org/openide/filesystems/FileObject.html" shape="rect">FileObject</a>
to take data from. Also remember to attach listeners to lookup result,
perhaps also to data itself and trigger UI update with new data.
Code will typically look like this:<br>
<pre xml:space="preserve">
/** JavaDataObject used as example, replace with your own data source */
private static final Lookup.Template MY_DATA = new Lookup.Template(JavaDataObject.class);
public void panelActivated (Lookup context) {
// lookup context and listen to result to get notified about context changes
curResult = context.lookup(MY_DATA);
curResult.addLookupListener(/** your LookupListener impl here*/);
Collection data = curResult.allInstances();
// ... compute view from data and trigger repaint
}
</pre>
Do *not* perform any long computation in panelActivated directly, see below.<br>
In panelDeactivated, be sure to remove all listeners to context given
to you in panelActivated.<p></p>
</li>
<li>
<b>Long computation of content:</b> What if rendering your
Navigator view takes long time, more than several milliseconds?
Right approach is to create and run new task using
<a href="./org-openide-util/org/openide/util/RequestProcessor.html" shape="rect">RequestProcessor techniques</a>,
each time when panelActivated call arrived or your listeners on
data context got called.<br>
While computing, UI of Navigator view
should show some please wait message.<p></p>
</li>
</ul>
<h4>Registering NavigatorPanel impl</h4>
<p>Declarative registration of your NavigatorPanel impl connects this
implementation with specific content type, which is type of
the document, expressed in mime-type syntax, for example 'text/x-java'
for java sources. Infrastructure will automatically load and show
your NavigatorPanel impl in UI, when <b>currently activated Node
is backed by primary FileObject whose
<a href="./org-openide-filesystems/org/openide/filesystems/FileObject.html#getMIMEType--" shape="rect">FileObject.getMimeType()</a>
equals to content type specified in your registering annotation</b> (see more options below).</p>
<h4>Advanced Content Registration - Linking to Node's Lookup</h4>
<p>There may be situations where linking between your Navigator view and
activated Node's primary FileObject is not enough or not possible at all.
This simply happens when the data you want to represent in Navigator are
not accessible through primary FileObject or DataObject. Usual example is
Multiview environment, where more views of one document exists.</p>
<p>The solution is to bind content of your Navigator view directly to your
TopComponent. Then, whenever your TopComponent gets activated in the system, Navigator UI
will show th content you connected to it.</p>
<b>Steps to do:</b>
<ul>
<li>Choose your content type, could be either well known or arbitrary,
say <b>'text/my-amazing-type'</b> and
do all basic steps described in above use case.<p></p>
</li>
<li>Implement <a href="org-netbeans-spi-navigator/org/netbeans/spi/navigator/NavigatorLookupHint.html" shape="rect">NavigatorLookupHint</a>
interface like this:
<pre xml:space="preserve">
class AmazingTypeLookupHint implements NavigatorLookupHint {
public String getContentType () {
return "text/my-amazing-type";
}
}
</pre>
<p></p>
</li>
<li>Alter your <a href="./org-openide-windows/org/openide/windows/TopComponent.html" shape="rect">TopComponent</a>
to contain your NavigatorLookupHint implementation (AmazingTypeLookupHint in this case)
in its lookup, returned from
<a href="./org-openide-windows/org/openide/windows/TopComponent.html#getLookup--" shape="rect">TopComponent.getLookup()</a>
method.<p></p>
</li>
<li>
Another option you have is to alter lookup of your <code>Node</code> subclass
instead of directly altering lookup of your <code>TopComponent</code>.
See <a href="./org-openide-nodes/org/openide/nodes/Node.html#getLookup--" shape="rect">Node.getLookup()</a> method.
Then Navigator will show your desired content whenever your <code>Node</code>
subclass will be active in the system.<br>
However, keep in mind that this option is less preferred, because it
only uses implementation detail knowledge that default implementation
of <code>TopComponent.getLookup()</code> includes also results from
lookup of asociated <code>Node</code>. So this approach will stop
working if you change default behaviour of <code>TopComponent.getLookup()</code> method.
<p></p>
</li>
</ul>
<h4>Programmatic activation of NavigatorPanel</h4>
<p>Programmatic activation of specific navigator panel activates and shows
navigator panel in navigation area, as if user had selected the panel
manually. API clients are expected to use programmatic activation to
activate/select preferred panel from a set of available panels.</p>
<b>Example:</b>
Several <code>TopComponents</code> in multiview arrangement,
<code>TopComponentA</code> and <code>TopComponentB</code>.
Both components provide the same
<code>NavigatorLookupHint</code> impl, which is recognized by two
providers <code>NavigatorPanelA</code> and <code>NavigatorPanelB</code>.
Now when <code>TopComponentA</code> becomes activated (has a focus),
it's desirable to select/show <code>NavigatorPanelA</code> from
navigator panels. On the other side, when <code>TopComponentB</code>
is activated, <code>NavigatorPanelB</code> should be activated automatically.
<p></p>
<b>Steps to do to activate panel programmatically:</b>
<ul>
<li>Get the instance of <code>NavigatorPanel</code> implementation that
you want to activate/show in navigator area.<br>
See <a href="./org-openide-util/org/openide/util/doc-files/api.html#instances" shape="rect">Instantiation rules</a>.<p></p>
</li>
<li>Call <a href="org-netbeans-spi-navigator/org/netbeans/spi/navigator/NavigatorHandler.html#activatePanel-org.netbeans.spi.navigator.NavigatorPanel-" shape="rect">
NavigatorHandler.activatePanel(NavigatorPanel panel)</a>
<p></p>.
</li>
</ul>
<h4>Setting activated node of Navigator window</h4>
<p>Sometimes clients need to alter activated Nodes of Navigator window,
to better represent Navigator area content within the whole application.
See <a href="./org-openide-windows/org/openide/windows/TopComponent.html#getActivatedNodes--" shape="rect">TopComponent.getActivatedNodes()</a>
and <a href="./org-openide-windows/org/openide/windows/TopComponent.Registry.html#getActivatedNodes--" shape="rect">TopComponent.Registry.html#getActivatedNodes()</a>
to find out what activated nodes of TopComponent and whole system mean.
</p>
<b>Use Case Example:</b>
NavigatorPanel implementation shows list or tree of some <code>Node</code>s
in Navigator area. When user selects a Node in the list or tree,
it is desirable to show selected Node's properties in Properties
window and enable proper actions in main menu. Exactly this can be done
by presenting Node selected in the list/tree as activated Node of
Navigator window.
<p></p>
<b>Steps to specify activated Nodes of Navigator window:</b>
<ul>
<li>In your implementation of <code>NavigatorPanel</code>, implement
method <code>getLookup()</code> to return Lookup instance filled
with Node(s) that you want to set as activated Nodes of Navigator window.
<p></p>
</li>
<li>Be sure to update Lookup content properly, for example using
<a href="./org-openide-util-lookup/org/openide/util/lookup/InstanceContent.html" shape="rect">InstanceContent</a> as follows:
<pre xml:space="preserve">
class MyNavigatorPanel implements NavigatorPanel {
/** Dynamic Lookup content */
private final InstanceContent ic;
/** Lookup instance */
private final Lookup lookup;
public MyNavigatorPanel () {
this.ic = new InstanceContent();
this.lookup = new AbstractLookup(ic);
}
public Lookup getLookup () {
return lookup;
}
/** Call this method when activated Nodes change is needed,
* for example when selection changes in your NavigatorPanel's Component
*/
private void selectionChanged (Node oldSel, Node newSel) {
ic.remove(oldSel);
ic.add(newSel);
}
... impl of rest of your NavigatorPanel
}
</pre>
</li>
</ul>
<h4>Adding UndoRedo support to the navigation view</h4>
<p>Some complex navigation views need support for undoing and redoing
edit changes done either directly in the view or in document which
the view is representing.
</p>
<b>Steps to support undo and redo in navigation view:</b>
<ul>
<li>Implement your navigation view as <a href="org-netbeans-spi-navigator/org/netbeans/spi/navigator/NavigatorPanelWithUndo.html" shape="rect">NavigatorPanelWithUndo</a>,
which is <code>NavigatorPanel</code> interface with extra method
<a href="org-netbeans-spi-navigator/org/netbeans/spi/navigator/NavigatorPanelWithUndo.html#getUndoRedo--" shape="rect">getUndoRedo()</a>.
<p></p>
</li>
<li>All other things remain the same as with basic <code>NavigatorPanel</code> usage.
<code>UndoRedo</code> support returned from <code>NavigatorPanelWithUndo.getUndoRedo()</code>
is propagated to the Navigator TopComponent and returned as its
<code>UndoRedo</code> support. For details see
<a href="./org-openide-windows/org/openide/windows/TopComponent.html#getUndoRedo--" shape="rect">TopComponent.getUndoRedo()</a>
and <a href="./org-openide-awt/org/openide/awt/UndoRedo.html" shape="rect">UndoRedo interface</a>.
<p></p>
</li>
<li>Example of <code>NavigatorPanelWithUndo</code> implementation:
<pre xml:space="preserve">
class MyNavigatorPanelWithUndo implements NavigatorPanelWithUndo {
/** UndoRedo support, substitute with your impl */
private final UndoRedo undo = new UndoRedo.Manager();
public UndoRedo getUndoRedo () {
return undo;
}
... rest of the NavigatorPanelWithUndo impl ...
}
</pre>
</li>
</ul>
<h4>Removing active Node/DataObject related NavigatorPanels from Navigator window</h4>
<p>In certain situations it's not desired to show NavigatorPanel implementations
related to DataObject of active Node in Navigator window. Typically
you need to have active Node of some type, so that actions in the system
works properly. But you don't want to show NavigatorPanels that "come"
with such active Node.
</p>
<b>Steps to remove such NavigatorPanels:</b>
<ul>
<li>Implement interface <a href="org-netbeans-spi-navigator/org/netbeans/spi/navigator/NavigatorLookupPanelsPolicy.html" shape="rect">NavigatorLookupPanelsPolicy</a>,
return kind of policy that suits you from <code>getPanelsPolicy()</code> method.
<p></p>
</li>
<li>Put implementation instance into your TopComponent's subclass lookup,
see <a href="./org-openide-windows/org/openide/windows/TopComponent.html#getLookup--" shape="rect">TopComponent.getLookup()</a>
for details.
<p></p>
</li>
<li>Now when your TopComponent becomes active in the system, found
panels policy is used to limit/affect set of available
<a href="org-netbeans-spi-navigator/org/netbeans/spi/navigator/NavigatorPanel.html" shape="rect">NavigatorPanel</a>
implementations.
<p></p>
</li>
</ul>
<h4>Integration of Explorer view into Navigator</h4>
<p>Explorer views comes handy when showing Nodes in varienty of situations
and it is just natural to be able to integrate them into Navigator window.
Working with explorer views is described at
<a href="./org-openide-explorer/org/openide/explorer/ExplorerUtils.html" shape="rect">ExplorerUtils javadoc</a>.
Integration with Navigator is easy and there are only subtle differencies
from integration into TopComponent.
</p>
<b>Steps to integrate some kind of Explorer View into Navigator:</b>
<ul>
<li>Implement <code>NavigatorPanel</code> interface and return created explorer
view from <code>getComponent()</code> method. Creating explorer view
is described in <a href="./org-openide-explorer/org/openide/explorer/ExplorerUtils.html" shape="rect">ExplorerUtils</a>.
<p></p>
</li>
<li>Return lookup created using
<a href="./org-openide-explorer/org/openide/explorer/ExplorerUtils.html#createLookup-org.openide.explorer.ExplorerManager-javax.swing.ActionMap-" shape="rect">
ExplorerUtils.createLookup(ExplorerManager, ActionMap)</a>
from <code>getLookup()</code> method of <code>NavigatorPanel</code>.
<p></p>
</li>
<li>Use <a href="./org-openide-explorer/org/openide/explorer/ExplorerUtils.html#activateActions-org.openide.explorer.ExplorerManager-boolean-" shape="rect">
ExplorerUtils.activateActions(ExplorerManager, boolean)</a> for actions activation and
deactivation in <code>panelActivated</code> and <code>panelDeactivated</code>.
<p></p>
</li>
<li>Take inspiration from following example code which integrates
ListView with Navigator:
<pre xml:space="preserve">
public class ListViewNavigatorPanel extends JPanel implements NavigatorPanel, ExplorerManager.Provider {
private ExplorerManager manager;
private ListView listView;
private Lookup lookup;
private Action copyAction;
public ListViewNavigatorPanel () {
manager = new ExplorerManager();
ActionMap map = getActionMap();
copyAction = ExplorerUtils.actionCopy(manager);
map.put(DefaultEditorKit.copyAction, copyAction);
map.put(DefaultEditorKit.cutAction, ExplorerUtils.actionCut(manager));
map.put(DefaultEditorKit.pasteAction, ExplorerUtils.actionPaste(manager));
map.put("delete", ExplorerUtils.actionDelete(manager, true)); // or false
lookup = ExplorerUtils.createLookup(manager, map);
listView = new ListView();
fillListView(listView);
add(listView);
}
public String getDisplayName() {
return "List view panel";
}
public String getDisplayHint() {
return "List view based navigator panel";
}
public JComponent getComponent() {
return this;
}
public void panelActivated(Lookup context) {
ExplorerUtils.activateActions(manager, true);
}
public void panelDeactivated() {
ExplorerUtils.activateActions(manager, false);
}
public Lookup getLookup() {
return lookup;
}
public ExplorerManager getExplorerManager() {
return manager;
}
private void fillListView(ListView listView) {
try {
Node testNode = new AbstractNode(Children.LEAF);
manager.setRootContext(testNode);
manager.setSelectedNodes(new Node[]{testNode});
} catch (PropertyVetoException ex) {
Exceptions.printStackTrace(ex);
}
}
}
</pre>
</li>
</ul>
<hr>
<h2>
<a name="usecase-Common Palette">How to use </a><a href="overview-summary.html#def-api-Common Palette">Common Palette</a>?
</h2>
<description>
The project implements a new component palette that will be reused by other
projects. The new palette should provide a common look and feel for Form editor,
Mobility, J2EE and possible other modules as well.
UI draft specification is available at http://ui.netbeans.org/docs/ui/palette/index.html
</description>
<p></p>
<p>
<h4>Palette Content</h4>
<p>The Common Palette content is a two-level hierarchy. The top-most level
are <b>Categories</b>, the Category children are <b>Items</b>. It's
possible to select (highlight) items in the palette panel using a mouse
or keyboard and then inserted/dropped into an editor that supports the palette.</p>
<p>The palette content can come from two different sources:</p>
<ul>
<li>
<b>Folders and files hierarchy defined in XML layer:</b> folders under
palette's root folder represent categories, files in category folders are palette
item. This way of creating of palette content is more convenient for module
developers as very little extra coding is required to setup a palette.</li>
<li>
<b>An arbitraty hierarchy of generic Nodes:</b> the children of palette's
root Node are categories and the children of a category Node are palette items.
This approach is more flexible when the palette content must change dynamically
(e.g. according to cursor position in editor window) however more coding
may be needed to setup the Node hierarchy. Please see Nodes API for more
details on Node management.</li>
</ul>
<h4>Basic usage</h4>
<p>The following steps must be taken if a module wants to define its own palette
content as a hierarchy of folders and files in its XML layer:</p>
<ul>
<li>Define palette's root folder in module's layer and also define subfolders for
categories and file objects for palette items.<br>Example:<br>
<pre xml:space="preserve">
&lt;filesystem&gt;
&lt;folder name="MyModulePalette"&gt;
&lt;folder name="Category1"&gt;
&lt;file name="PaletteItem_1.myitem" url="palette/PaletteItem_1.xml" /&gt;
&lt;file name="PaletteItem_2.myitem" url="palette/PaletteItem_2.xml" /&gt;
&lt;file name="PaletteItem_3.myitem" url="palette/PaletteItem_3.xml" /&gt;
&lt;/folder&gt;
&lt;folder name="Category2"&gt;
&lt;file name="PaletteItem_4.myitem" url="palette/PaletteItem_4.xml" /&gt;
&lt;file name="PaletteItem_5.myitem" url="palette/PaletteItem_5.xml" /&gt;
&lt;file name="PaletteItem_6.myitem" url="palette/PaletteItem_6.xml" /&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;/filesystem&gt;
</pre>
<br>Note: it's necessary to define some way of loading of the palette item
from e.g. XML files. There are several possible ways to achieve that,
please refer to DataLoaders API for more details.
</li>
<li>Extend <a href="org-netbeans-spi-palette/org/netbeans/spi/palette/PaletteActions.html" shape="rect">PaletteActions</a>
class that provides custom Actions for palette's popup menus.
<br>Example:<br>
<pre xml:space="preserve">
class MyPaletteActions extends PaletteActions {
public Action getPreferredAction(Lookup lookup) {
Node itemNode = (Node)lookup.lookup( Node.class );
if( null != itemNode ) {
return new InsertItemAtDefaultLocationAction( itemNode );
}
return null;
}
public Action[] getCustomItemActions(Lookup lookup) {
Node itemNode = (Node)lookup.lookup( Node.class );
if( null != itemNode ) {
return new Action[] { new CustomizeItemAction( itemNode ) };
}
return null;
}
public Action[] getCustomCategoryActions(Lookup lookup) {
Node categoryNode = (Node)lookup.lookup( Node.class );
if( null != categoryNode ) {
return new Action[] { new CustomizeCategoryAction( categoryNode ) };
}
return null;
}
public Action[] getImportActions() {
return new Action[] { new ImportItemsFromWebAction() };
}
public Action[] getCustomPaletteActions() {
return null; //no custom actions for palette's root
}
}
</pre>
</li>
<li>Use <a href="org-netbeans-spi-palette/org/netbeans/spi/palette/PaletteFactory.html" shape="rect">PaletteFactory</a>
to create an instance of PaletteController. The editor module keeps
a reference to this object and registers a PropertyChangeListner to it to be notified
of palette's selection changes.<br>Example:<br>
<pre xml:space="preserve">
class MyClass {
PaletteController controller;
PaletteController initializePalette() {
try {
controller = PaletteFactory.createPalette( "MyPalette", new MyPaletteActions() );
} catch (IOException ex) {
ex.printStackTrace();
return;
}
controller.addPropertyChangeListener( new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if( PaletteController.PROP_SELECTED_ITEM.equals( evt.getPropertyName() ) ) {
Lookup selItem = controller.getSelectedItem();
if( null == selItem ) {
//nothing is selected in palette
} else {
Node selNode = (Node)selItem.lookup( Node.class );
if( null != selNode ) {
//change mouse cursor for editor window to indicate
//the type of palette item that can be dropped
changeCursorInEditorWindow( selNode );
}
}
}
}
});
return controller;
}
}
</pre>
</li>
<li>Add the instance of
<a href="org-netbeans-spi-palette/org/netbeans/spi/palette/PaletteController.html" shape="rect">PaletteController</a>
to the lookup of editor's TopComponent.<br>
<pre xml:space="preserve">
class MyEditorTopComponent extends TopComponent {
private MyEditorTopComponent() {
this( new InstanceContent() );
}
private MyEditorTopComponent( InstanceContent content ) {
super( new AbstractLookup( content ) );
content.add( initializePalette() );
initEditorComponents();
}
PaletteController controller;
private PaletteController initializePalette() {
if( null == controller ) {
controller = PaletteFactory.createPalette( "MyPalette", new MyPaletteActions() );
}
return controller;
}
}
</pre>
</li>
</ul>
<p>
When an item is selected in the palette and user clicks into the editor window
then the module can ask for selected item by calling
<a href="org-netbeans-spi-palette/org/netbeans/spi/palette/PaletteController.html#getSelectedItem--" shape="rect">PaletteController.getSelectedItem()</a>.
This method returns a Lookup that holds object(s) representing the selected item.
After the item is inserted into the editor window the module may clear palette's selection
(<a href="org-netbeans-spi-palette/org/netbeans/spi/palette/PaletteController.html#clearSelection--" shape="rect">PaletteController.clearSelection()</a>)
or leave the item selected to implement 'multi drop' insertion scenario.
</p>
</p>
<p>
<h4>Filtering</h4>
<p>It is possible to filter palette content and hide some categories and/or
items from the user by extending <a href="org-netbeans-spi-palette/org/netbeans/spi/palette/PaletteFilter.html" shape="rect">PaletteFilter</a> class.
</p>
<pre xml:space="preserve">
class MyPaletteFilter extends PaletteFilter {
public boolean isValidItem(Lookup lookup) {
Node itemNode = (Node)lookup.lookup( Node.class );
return isItemVisibleInCurrentEditorContext( itemNode );
}
public boolean isValidCategory(Lookup lookup) {
Node categoryNode = (Node)lookup.lookup( Node.class );
return isCategoryVisibleInCurrentEditorContext( categoryNode );
}
private boolean isItemVisibleInCurrentEditorContext( Node item ) {
boolean res = true;
//check current cursor positions and/or item type and decide whether
//the item is valid, i.e. can be selected and dropped into editor
return res;
}
private boolean isCategoryVisibleInCurrentEditorContext( Node item ) {
boolean res = true;
//check current cursor positions and/or category type and decide whether
//the category is valid, i.e. its items can be selected and dropped into editor
return res;
}
</pre>
<p>Then initialize the palette using the following method:</p>
<pre xml:space="preserve">
MyPaletteFilter filter = new MyPaletteFilter();
PaletteController controller = PaletteFactory.createPalette( "MyPalette", new MyPaletteActions(), filter, null );
</pre>
<p>It is necessary to call
<a href="org-netbeans-spi-palette/org/netbeans/spi/palette/PaletteController.html#refresh--" shape="rect">PaletteController.refresh()</a>
to refresh and repaint the palette window whenever the filtering condition has changed:</p>
<pre xml:space="preserve">
myPaletteFilter.setShowSomeSpecialCategories( false );
paletteController.refresh();
</pre>
</p>
<p>
<h4>Default Settings</h4>
<p>The initial state of the palette can be overridden by setting appropriate
attributes to palette model. The list of supported attributes is defined
in PaletteController class. If the palette model is create from Nodes then
the attributes are extracted by calling Node.getValue() method on the root
Node and category and item nodes. If the palette model is defined as folders
and files in the layer then the attributes are extracted by calling
FileObject.getAttribute().</p>
<p>In the example below the palette will not show item names initially
(only icons are visible), the user can change this in palette's context menu.
Category1 is read-only therefore the user cannot remove it.
Category2 is not initially visible, the user can change this in
palette's customizer.
<br>
</p>
<pre xml:space="preserve">
&lt;filesystem&gt;
&lt;folder name="MyModulePalette"&gt;
&lt;attr name="showItemNames" stringvalue="false"/&gt;
&lt;folder name="Category1"&gt;
&lt;attr name="isReadonly" stringvalue="true"/&gt;
&lt;file name="PaletteItem_1.myitem" url="palette/PaletteItem_1.myitem" /&gt;
&lt;file name="PaletteItem_2.myitem" url="palette/PaletteItem_2.myitem" /&gt;
&lt;file name="PaletteItem_3.myitem" url="palette/PaletteItem_3.myitem" /&gt;
&lt;/folder&gt;
&lt;folder name="Category2"&gt;
&lt;attr name="isVisible" stringvalue="false"/&gt;
&lt;file name="PaletteItem_4.myitem" url="palette/PaletteItem_4.myitem" /&gt;
&lt;file name="PaletteItem_5.myitem" url="palette/PaletteItem_5.myitem" /&gt;
&lt;file name="PaletteItem_6.myitem" url="palette/PaletteItem_6.myitem" /&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;/filesystem&gt;
</pre>
</p>
<p>
<h4>Adding categories and items at runtime</h4>
<p>It is possible to add new palette categories and/or palette item at runtime
when the palette window is already visible.</p>
<p>Adding a <strong>new category</strong> is very straight-forward, it basically means creating
a new folder under palette's root folder in XML layer:</p>
<pre xml:space="preserve">
FileObject paletteRoot = FileUtil.getConfigFile( "MyModulePalette" );
paletteRoot.createFolder( "NewCategory" );
</pre>
<p>Adding a <strong>new item</strong> is a similar task:</p>
<pre xml:space="preserve">
FileObject paletteRoot = FileUtil.getConfigFile( "MyPalette" );
FileObject targetCategoryFO = paletteRoot.getFileObject( "CategoryName" );
DataFolder targetCategoryDF = DataFolder.findFolder( targetCategoryFO );
DataObject dobj = (DataObject)itemNode.getLookup().lookup( DataObject.class );
dobj.copy( targetCategoryFolder );
</pre>
<p>Please refer to Nodes API in case the palette content is defined as a
hierarchy of arbitrary Nodes.</p>
</p>
<p>
<h4>Palette content for text-based editors</h4>
<p>The following steps must be taken when writing the item using the support provided by this module:</p>
<ol>
<li>
Create XML file with item definition according to
the <a href="org-netbeans-spi-palette/architecture-summary.html#dtd-editor-palette-item-1_0.dtd" shape="rect">editor-palette-item-1_0.dtd</a>.
</li>
<li>
Register it in the editor's layer file (see Basic usage).
</li>
<li>
Provide custom item implementation of the ActiveEditorDrop interface if needed. I must be
referenced from the definition file.
</li>
</ol>
</p>
<hr>
<h2>
<a name="usecase-Quick Search API">How to use </a><a href="overview-summary.html#def-api-Quick Search API">Quick Search API</a>?
</h2>
<description>
QuickSearch API and its implementations provides way for end user to learn
system earlier and easier and also to find various things in the system more
quickly, conveniently and in standard way.
Main project page is on nb wiki, http://wiki.netbeans.org/QuickSearch
</description>
<p></p>
<p>
<h4>How To Add New Quick Search Provider</h4>
In order to plug in a new Quick Search provider and new category of results,
module writers need to complete following steps:
<h5>1. Implement <a href="org-netbeans-spi-quicksearch/org/netbeans/spi/quicksearch/SearchProvider.html" shape="rect">SearchProvider</a>
</h5>
<ul>
<li>Implement body of <b><code>SearchProvider.evaluate</code></b> method
like suggested in its <a href="org-netbeans-spi-quicksearch/org/netbeans/spi/quicksearch/SearchProvider.html" shape="rect">javadoc</a>.
</li>
</ul>
<h5>2. Register SearchProvider implementation in xml layer</h5>
Register your SearchProvider implementation in your module's xml layer file under
main <b>"/QuickSearch"</b> folder. Registration xml syntax is following:
<pre xml:space="preserve">
&lt;folder name="QuickSearch"&gt;
&lt;folder name="Category1_ID"&gt;
&lt;attr name="position" intvalue="300"/&gt;
&lt;file name="org-netbeans-module1-package1-Provider1Impl.instance"/&gt;
&lt;/folder&gt;
&lt;folder name="Category2_ID"&gt;
&lt;!--Attribute for localization - provide localized display name of category!--&gt;
&lt;attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.yourmodule.YourBundle"/&gt;
&lt;!--Attribute for command prefix - used to narrow search to this category only!--&gt;
&lt;attr name="command" stringvalue="p"/&gt;
&lt;!--Attribute for category ordering!--&gt;
&lt;attr name="position" intvalue="200"/&gt;
&lt;!--Note that multiple providers can contribute to one category!--&gt;
&lt;file name="org-netbeans-module2-package2-Provider2Impl.instance"/&gt;
&lt;file name="org-netbeans-module2-package3-Provider3Impl.instance"/&gt;
&lt;/folder&gt;
&lt;/folder&gt;
</pre>
<b>Syntax explanation:</b>
<ul>
<li>Subfolders of "QuickSearch" define search result categories and their order.</li>
<li>Providers can share category by putting themselves under same subfolder.</li>
<li>Ordering of categories is done through NetBeans standard FileSystem API ordering
"position" attribute</li>
<li>Display name of category folder uses NetBeans standard FileSystem API
"SystemFileSystem.localizingBundle" attribute.</li>
<li>"command" attribute defines command prefix for category, which is used
to narrow Quick Search to only one category. Provide short prefix, ideally
containing one or two prefix, that will serve as command to narrow search
only this category. In above syntax example, if
user types 'p' and space key and then text, only "Category2_ID" category
will be searched.</li>
<li>If several providers share one category, then only one provider needs to
specify above attributes. Note however that if your provider shares
category with provider from different module, you should have dependency
on module which actually define those attributes. Dependency assures
there will always be category "description" for category that you are
sharing.</li>
</ul>
<h4>How To Share Category Of Results</h4>
<p>Quick Search UI shows search results divided into visually separeted sections,
called categories. Several <code>SearchProvider</code> implementations may decide to display
their results in one shared category of results in Quick Search UI.</p>
<p>In order to share category, module writers have to agree on shared
category and its properties, especially its name.
It means that all providers (possibly in different NetBeans modules)
need to be registered under the same folder, as shown below:</p>
<h5>Provider 1</h5>
Provider 1 is category "owner", which defines properties of <code>SharedCategory</code> such as
display name, position and command prefix.
<pre xml:space="preserve">
&lt;folder name="QuickSearch"&gt;
&lt;folder name="SharedCategory"&gt;
&lt;attr name="SystemFileSystem.localizingBundle" stringvalue="org.netbeans.modules.yourmodule.YourBundle"/&gt;
&lt;attr name="command" stringvalue="p"/&gt;
&lt;attr name="position" intvalue="200"/&gt;
&lt;file name="org-netbeans-module1-package1-Provider1Impl.instance"&gt;
&lt;attr name="position" intvalue="300"/&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
</pre>
<h5>Provider 2</h5>
Other providers from other modules are sharing category with Provider 1.
Provider 2 does not define properties of <code>SharedCategory</code>,
as they were already defined by Provider 1.
Note that module dependency on the module of Provider 1 is needed
to ensure that <code>SharedCategory</code> is fully defined.
<pre xml:space="preserve">
&lt;folder name="QuickSearch"&gt;
&lt;folder name="SharedCategory"&gt;
&lt;file name="org-netbeans-module2-package2-Provider2Impl.instance"/&gt;
&lt;attr name="position" intvalue="200"/&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
</pre>
<h5>Provider 3</h5>
The same rules apply like for Provider 2. Note that position attribute
can be used to control position of provider's results in shared category.
Results from provider with lowest position will go first and so on.
<pre xml:space="preserve">
&lt;folder name="QuickSearch"&gt;
&lt;folder name="SharedCategory"&gt;
&lt;file name="org-netbeans-module2-package3-Provider3Impl.instance"/&gt;
&lt;attr name="position" intvalue="100"/&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
</pre>
<h4>How To Define and Modify Order of Categories</h4>
Order of categories of results can be set by using "position" attribute
of category xml folder definition. Following example will result in
<code>FirstCategory</code> to be first, and <code>SecongCategory</code> to be second :),
which means that <code>FirstCategory</code> and its results will be
displayed above <code>Secondcategory</code> in QuickSearch results window.
<pre xml:space="preserve">
&lt;folder name="QuickSearch"&gt;
&lt;folder name="SecondCategory"&gt;
&lt;attr name="position" intvalue="300"/&gt;
...
&lt;/folder&gt;
&lt;folder name="FirstCategory"&gt;
&lt;attr name="position" intvalue="200"/&gt;
...
&lt;/folder&gt;
&lt;/folder&gt;
</pre>
<h4>How To Hide Recent Searches Results and Others</h4>
"Recent Searches" provider is contained directly in <code>spi.quicksearch</code>
module, so its functionality is automatically always available by default.
However, if your module wants to disable "Recent Searches" or any other
category, follow the steps below:
<h5>Define module dependency</h5>
Your module have to depend on module where provider you want to disable
is contained. In case of "Recent Searches" provider, it's <code>spi,quicksearch</code>,
on which you probably already depend.
<h5>Disable provider using "_hidden"</h5>
For example, to disable "Recent Searches" provider, write into your layer:
<pre xml:space="preserve">
&lt;folder name="QuickSearch"&gt;
&lt;folder name="Recent_hidden"&gt;
&lt;/folder&gt;
&lt;/folder&gt;
</pre>
"Recent" is a name of category for "Recent Searches" provider and by appending
"_hidden" suffix you are telling system to "hide" it. This technique
can be used also to disable invidual search providers.
<h4>How To Use Quick Search in Platform Application</h4>
Quick Search UI is disabled by default in application built on top of
NetBeans platform. To enable Quick Search feature in your application,
complete following steps:
<h5>1. Write XML layer registration</h5>
Add the following lines to XML layer of some of your modules in your
application suite:
<pre xml:space="preserve">
&lt;folder name="Toolbars"&gt;
&lt;folder name="QuickSearch"&gt;
&lt;attr name="SystemFileSystem.localizingBundle" stringvalue="com.myapp.mymodule.MyBundle"/&gt;
&lt;file name="org-netbeans-modules-quicksearch-QuickSearchAction.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Edit/org-netbeans-modules-quicksearch-QuickSearchAction.instance"/&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
</pre>
<h5>2. Localize Toolbar Name</h5>
Replace <code>com.myapp.mymodule.MyBundle</code> in the xml registration
above with path to your properties file, in which you'll define
localized name of Quick Search toolbar:
<pre xml:space="preserve">
Toolbars/QuickSearch=Quick Search
</pre>
<p>By default, providers for searching in actions and recent searches
will be enabled. Web search provider is disabled by default, see use case
below for info how to turn it on.</p>
<h4>How To Add a Default Web Search Provider</h4>
There is a default implementation of web search provider which uses Google
to search for the given text on the web. Simply add the following lines to your XML layer
to enable this search provider in your application:
<pre xml:space="preserve">
&lt;folder name="QuickSearch"&gt;
&lt;folder name="WebSearch"&gt;
&lt;!--Attribute for localization - provide localized display name of category!--&gt;
&lt;attr name="SystemFileSystem.localizingBundle" stringvalue="com.myapp.mymodule.MyBundle"/&gt;
&lt;!--Attribute for command prefix - used to narrow search to this category only!--&gt;
&lt;attr name="command" stringvalue="g"/&gt;
&lt;!--Attribute for category ordering!--&gt;
&lt;attr name="position" intvalue="200"/&gt;
&lt;!--Note that multiple providers can contribute to one category!--&gt;
&lt;file name="org-netbeans-modules-quicksearch-web-WebQuickSearchProviderImpl.instance"/&gt;
&lt;/folder&gt;
&lt;/folder&gt;
</pre>
You can also add branding for <code>org.netbeans.modules.quicksearch.web</code> Bundle to restrict
the search to a particular site only:
<pre xml:space="preserve">
quicksearch.web.site=mywebsite.com
</pre>
And you can also restrict the search to some parts your website only:
<pre xml:space="preserve">
quicksearch.web.url_patterns=mywebsite.com/docs,mywebsite.com/files/tutorials
</pre>
<h4>How to customize Look&amp;Feel properties</h4>
If you need to adjust border of the Quick Search component for your
Look&amp;Feel, you can put a <code>Border</code> instance into
<code>UIManager</code> under key <code>nb.quicksearch.border</code>.
</p>
<hr>
<h2>
<a name="usecase-Task List API">How to use </a><a href="overview-summary.html#def-api-Task List API">Task List API</a>?
</h2>
<description>
This module provides SPI for third parties that want to display some sort information for
the user in the Task List / Problems window. A typical example are Java errors, warnings, TODOs etc.
Part of the integration are several implementation modules that provider task list user interface,
TODO task scanning, Java integration.
</description>
<p></p>
<h4>Task Scanners</h4>
<p>The main feature of the Task List SPI is the ability to 'plug-in' additional task providing
modules that generate tasks for the task list window.</p>
<p>The plugable task scanners can either <a href="org-netbeans-spi-tasklist/org/netbeans/spi/tasklist/PushTaskScanner.Callback.html#setTasks-org.openide.filesystems.FileObject-java.util.List-" shape="rect">push</a>
new <a href="org-netbeans-spi-tasklist/org/netbeans/spi/tasklist/Task.html" shape="rect">Task</a>s to the Task List window whenever they want -
<a href="org-netbeans-spi-tasklist/org/netbeans/spi/tasklist/PushTaskScanner.html" shape="rect">PushTaskScanner</a> - or they
can inherit from <a href="org-netbeans-spi-tasklist/org/netbeans/spi/tasklist/FileTaskScanner.html" shape="rect">FileTaskScanner</a>
and the Task List framework will actively <a href="org-netbeans-spi-tasklist/org/netbeans/spi/tasklist/FileTaskScanner.html#scan-org.openide.filesystems.FileObject-" shape="rect">poll</a>
them for new tasks for each file under the current scanning scope (see below).</p>
<p>Scanner instances are registered in XML layer in folder "/TaskList/Scanners". The framework keeps track of modified files
and notifies the scanners whenever a file under the scanning scope needs to be rescanned.</p>
<h4>Task Scanning Scope</h4>
<p>Scanning scope defines which files/folders will be scanned for tasks. The default implementation
includes scopes for currently edited file, scope for files and folders in the main project and projects
that depend on it and scope for all opened projects.</p>
<p>Additional scopes may be provided by extending
<a href="org-netbeans-spi-tasklist/org/netbeans/spi/tasklist/TaskScanningScope.html" shape="rect">TaskScanningScope</a> class
and registering instances in folder "/TaskList/ScanningScopes" in XML layer.</p>
<h4>Task Groups</h4>
<p>Tasks are organized into Groups according to their importance. Each task can be in one group only.
The default implementation includes "Error", "Warning" and "TODO" groups. Additional groups can be
registered in XML layer in folder "/TaskList/Groups". Each task group is identified by its unique name.</p>
<hr>
<h2>
<a name="usecase-TreeTableView Model">How to use </a><a href="overview-summary.html#def-api-TreeTableView Model">TreeTableView Model</a>?
</h2>
<description>
The debuggercore/<b>ViewModel</b>
module (View Model) allows to share one TreeTableView among different modules.
</description>
<p></p>
Used by debugger to display various information - threads, call stack, variables, etc.
<hr>
<h2>
<a name="usecase-ETable and Outline">How to use </a><a href="overview-summary.html#def-api-ETable and Outline">ETable and Outline</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-Look &amp; Feel Customization Library">How to use </a><a href="overview-summary.html#def-api-Look &amp; Feel Customization Library">Look &amp; Feel Customization Library</a>?
</h2>
<description>
The plaf library consists primarily of code that used to be in core. What it does:
Installs a custom look and feel if a custom look and feel class is passed to it
Sets the correct fonts in the Swing UIDefaults if a custom fontsize is desired for the application's UI
Loads a UI theme if a URL for the theme file (no format changes since NetBeans 3.4) is passed to it
Installs custom UI keys and values used by other components of NetBeans, such as colors and UI delegate class names used by
other parts NetBeans. Examples of these:
Tab control UI delegate class name, depending on the look and feel, for the window system
Definitions of colors which the tab control, property sheet and output window will use, if present in
UIDefaults, to color themselves in accordance with the UI spec for them on a given look and feel
Custom border implementations NetBeans uses for scroll panes to reduce "border-buildup"
A custom implementation of ToolbarUI which NetBeans uses for its toolbars, and a custom UI for
toolbar buttons which sizes them correctly (GTK and Aqua only, currently)
Insets definition for the editor scrollbar, used to get the height of the upper and lower button of the scrollbar
for purposes of the Error Stripe. The appropriate key value is "Nb.Editor.ErrorStripe.ScrollBar.Insets".
Compensate for missing elements on some (GTK) look and feels, which standard Swing code expects to be
present, i.e. UIManager.getColor ("control"), to enable older code to run unmodified on newer
look and feels.
Its API consists of a single method, org.netbeans.swing.plaf.Startup.run (Class lookAndFeel, int fontSize, URL themeFile),
which should be called early in NetBeans startup sequence by core, to initialize UIDefaults values before any main window
GUI is constructed. It provides a minimal SPI in the form of the abstract class LFCustoms, which an alternate look and
feel could use to provide lists of keys and values which should be installed into UIDefaults, via the mechanism documented
in the documentation for LFCustoms.
<b>PlafAPI</b>
</description>
<p></p>
Used by NetBeans to customize the UI to conform to UI design specifications; can be used by
third parties who are employing parts of the NetBeans platform in their applications, such as
the windowing system.
<hr>
<h2>
<a name="usecase-Tab Control">How to use </a><a href="overview-summary.html#def-api-Tab Control">Tab Control</a>?
</h2>
<description>
The tab control is a swing control used by NetBeans window system, similar in function to a JTabbedPane, which
allows the user to see and select tabs that contain different components. It defines two GUI components:
TabbedContainer (similar to JTabbedPane) and TabDisplayer, a generic component for displaying tabs which
is not associated with any particular container. Several different types of UIs (view, editor, sliding)
are provided, each of which is handled by a different UI delegate class; UI delegate subclasses designed
to fit with Windows, Metal, Aqua and GTK look and feels are provided.
<b>TabbedContainerAPI</b>
<b>PopupSwitcherAPI</b>
</description>
<p></p>
Primary use cases are in the NetBeans window system, as top level containers in the main window; future use cases
include providing a consistent UI for tabs in the property sheet, the component inspector and the output window, but
this probably will not happen for 4.0.
<hr>
<h2>
<a name="usecase-Actions APIs">How to use </a><a href="overview-summary.html#def-api-Actions APIs">Actions APIs</a>?
</h2>
<description>
Actions provides system of support and utility classes
for 'actions' usage in NetBeans.
</description>
<p></p>
First see the <a href="org-openide-actions/org/openide/actions/doc-files/api.html" shape="rect">API description</a>. Here is just
a list of frequently asked or interesting questions slowly expanding as
people ask them:
<h3>Actions faq:</h3>
<h4>How to define configurable Shortcut for Component based shortcut?</h4>
<em><b>Q:</b>
The usual Swing way of defining Actions for your component is to create an Action instance and put it into the Input and Action maps of your component.
However how to make this Action's shortcut configurable from the Tools/Keyboard Shortcuts dialog?</em>
<p>
In order for the action to show up in Keyboards Shortcut dialog you need the action defined in the
layer file under "Actions" folder and have the shortcut defined there under "Keymaps/&lt;Profile Name&gt;" linking to your action.
</p>
<pre xml:space="preserve">
&lt;folder name="Actions" &gt;
&lt;folder name="Window"&gt;
&lt;file name="org-netbeans-core-actions-PreviousViewCallbackAction.instance"/&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;folder name="Keymaps"&gt;
&lt;folder name="NetBeans"&gt;
&lt;file name="S-A-Left.shadow"&gt;
&lt;attr name="originalFile" stringvalue="Actions/Window/org-netbeans-core-actions-PreviousViewCallbackAction.instance"/&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
</pre>
<p>
The mentioned Action has to be a subclass of <code>org.openide.util.actions.CallbackSystemAction</code>. It does not necessarily has to
perform the action, it's just a placeholder for linking the shortcut. You might want to override it's <code>getActionMapKey()</code> and give it a
reasonable key.
</p>
<p>
The actual action that does the work in your component (preferably a simple Swing <code>javax.swing.Action</code>)
is to be put into your <code>TopComponent</code>'s <code>ActionMap</code>. The key for the <code>ActionMap</code>
has to match the key defined in the global action's <code>getActionMapKey()</code> method.
</p>
<pre xml:space="preserve">
getActionMap().put("PreviousViewAction", new MyPreviousTabAction());
</pre>
<p>
This way even actions from multiple <code>TopComponent</code>s with the same gesture (eg. "switch to next tab") can share the same configurable shortcut.
</p>
<p>
Note: Don't define your action's shortcut and don't put it into any of the <code>TopComponent</code>'s
<code>javax.swing.InputMap</code>. Otherwise the component would not pick up the changed shortcut from the
global context.
</p>
<hr>
<h2>
<a name="usecase-UI Utilities API">How to use </a><a href="overview-summary.html#def-api-UI Utilities API">UI Utilities API</a>?
</h2>
<description>
The <b>org.openide.awt</b>
provides API/SPI for UI related aspects of application.
</description>
<p></p>
<p>
<a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">
<img alt="Cover of NetBeans Platform for Beginners book" height="70" src="http://wiki.apidesign.org/images/0/03/NetBeansPlatformForBeginners.jpg" style="float: right" width="60">
</a>
For general overview of the concepts of NetBeans action system and related UI elements,
together with code samples, see chapter 5,
of <a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">NetBeans Platform for Beginners</a>
by Jason Wexbridge and Walter Nyland.
</p>
<hr>
<h2>
<a name="usecase-Compatibility APIs">How to use </a><a href="overview-summary.html#def-api-Compatibility APIs">Compatibility APIs</a>?
</h2>
<description>
XXX no answer for arch-what
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-Dialogs API">How to use </a><a href="overview-summary.html#def-api-Dialogs API">Dialogs API</a>?
</h2>
<description>
The
<b>DialogsAPI</b>
allows creating a user notification, a dialog's description
and also permits it to be displayed. The wizard framework allows create a sequence
of panels which leads a user through the steps to complete any task.
This API is part of package org.openide.
</description>
<p></p>
There is a <a href="./org-openide-dialogs/org/openide/doc-files/wizard-guidebook.html" shape="rect">Wizard Guide Book</a>
providing the introductionary information, moreover here is a list
of frequently asked questions and their answers:
<h4>How to change the title of a wizard?</h4>
<em>
<b>Q:</b> Although none of my panels have names set (using setName() method) and the method name() in the WizardDescriptor.Iterator
returns an empty string, I'm getting "wizard ( )" as the title of each panel in my wizard.
When I set the name of the panel and return a string from the method name() I get: "panelName wizard (myName)".
The wizard steps are labeled correctly, it just the panel title/name that looks like it adds "wizard ()" to
any of my panels. I don't mind the "( )", but I would like to rid of the word "wizard".
</em>
<p>
<b>A:</b> You can change the format of your wizard's title by
<a href="org-openide-dialogs/org/openide/WizardDescriptor.html#setTitleFormat-java.text.MessageFormat-" shape="rect">WizardDescriptor.setTitleFormat(MessageFormat format)</a>
and rid of 'wizard' word in the default wizard's title.
</p>
<hr>
<h2>
<a name="usecase-Explorer &amp; Property Sheet API">How to use </a><a href="overview-summary.html#def-api-Explorer &amp; Property Sheet API">Explorer &amp; Property Sheet API</a>?
</h2>
<description>
The
<b>ExplorerAPI</b>
is build around Explorer - solely a user-interface device: it has no particular knowledge
of the structure of the IDE. Rather, it provides the physical user interface for
the Node hierarchy, as described in the
<b>NodesAPI</b>.
A given Explorer instance will be some visual component (such as a Swing panel)
displaying some representation of a subtree of the complete Node hierarchy;
the topmost node being displayed is said to be the root of the Explorer.
Be careful not to confuse the root of a particular Explorer instance, which is
selected according to what the user wishes to see, with the root(s) of
the entire Node hierarchy, which generally are fixed.
</description>
<p></p>
<p>
<a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">
<img alt="Cover of NetBeans Platform for Beginners book" height="70" src="http://wiki.apidesign.org/images/0/03/NetBeansPlatformForBeginners.jpg" style="float: right" width="60">
</a>
For general overview of the concepts related to <a href="./org-openide-nodes/overview-summary.html" shape="rect">nodes</a> and explorers,
together with code samples, see chapter 7,
of <a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">NetBeans Platform for Beginners</a>
by Jason Wexbridge and Walter Nyland.
</p>
<hr>
<h2>
<a name="usecase-File System API">How to use </a><a href="overview-summary.html#def-api-File System API">File System API</a>?
</h2>
<description>
The Filesystems API provides a common API to access files in a uniform manner.
It is available as standalone library and
also is bundled together with other parts of the openide.
Specification
</description>
<p></p>
<p>
<a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">
<img alt="Cover of NetBeans Platform for Beginners book" height="70" src="http://wiki.apidesign.org/images/0/03/NetBeansPlatformForBeginners.jpg" style="float: right" width="60">
</a>
For general overview of the filesystem concepts, related topics,
together with code samples, see chapter 3,
of <a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">NetBeans Platform for Beginners</a>
by Jason Wexbridge and Walter Nyland.
Many of the usecases are described at the
<a href="org-openide-filesystems/org/openide/filesystems/doc-files/api.html" shape="rect">overall documentation</a>,
in a way how to
<a href="org-openide-filesystems/org/openide/filesystems/doc-files/HOWTO-MIME.html" shape="rect">register a mime type</a>.
Some of the additional usecases are covered here.
</p>
<h4>How to change menus, etc. after login?</h4>
<p>
See <a href="org-openide-filesystems/org/openide/filesystems/FileSystem.html" shape="rect">documentation</a>
about dynamically changing the system filesystem.
</p>
<hr>
<h2>
<a name="usecase-I/O APIs - Swing">How to use </a><a href="overview-summary.html#def-api-I/O APIs - Swing">I/O APIs - Swing</a>?
</h2>
<description>
The Input/Output API is a small API module
which contains InputOutput and related interfaces used in
driving the Output Window. The normal implementation is org.netbeans.core.output2.
</description>
<p></p>
<p>There is an SPI but additional implementations are not expected. The API is most important.</p>
<p>
Simple usage example:
</p>
<pre xml:space="preserve">
<span class="type">InputOutput</span> <span class="variable-name">io</span> = IOProvider.getDefault().getIO(<span class="string">"My Window"</span>, true);
io.select();
<span class="type">OutputWriter</span> <span class="variable-name">w</span> = io.getOut();
w.println(<span class="string">"Line of plain text."</span>);
<span class="type">OutputListener</span> <span class="variable-name">listener</span> = <span class="keyword">new</span> <span class="type">OutputListener</span>() {
<span class="keyword">public</span> <span class="type">void</span> <span class="function-name">outputLineAction</span>(<span class="type">OutputEvent</span> <span class="variable-name">ev</span>) {
StatusDisplayer.getDefault().setStatusText(<span class="string">"Hyperlink clicked!"</span>);
}
<span class="keyword">public</span> <span class="type">void</span> <span class="function-name">outputLineSelected</span>(<span class="type">OutputEvent</span> <span class="variable-name">ev</span>) {
<span class="comment">// Let's not do anything special.
</span> }
<span class="keyword">public</span> <span class="type">void</span> <span class="function-name">outputLineCleared</span>(<span class="type">OutputEvent</span> <span class="variable-name">ev</span>) {
<span class="comment">// Leave it blank, no state to remove.
</span> }
};
w.println(<span class="string">"Line of hyperlinked text."</span>, listener, true);
</pre>
<hr>
<h2>
<a name="usecase-Datasystems API">How to use </a><a href="overview-summary.html#def-api-Datasystems API">Datasystems API</a>?
</h2>
<description>
In summary, the <b>LoadersAPI</b>
is responsible for scanning files in a directory on disk,
weeding out irrelevant files of no interest to the IDE,
and grouping the rest into logical chunks, or just determining
what type of data each represents. It does this scanning 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.
</description>
<p></p>
A lot of usecases is described <a href="org-openide-loaders/org/openide/loaders/doc-files/api.html" shape="rect">in the javadoc</a>. Here
is the list of some faqs:
<h4>Using Scripting and Templating Languages</h4>
<p>
Often many people require ability to create a "clever" template - e.g.
write piece of simple text and at the time of its
<a href="org-openide-loaders/org/openide/loaders/DataObject.html#createFromTemplate-org.openide.loaders.DataFolder-java.lang.String-java.util.Map-" shape="rect">
processing
</a>
do some advanced changes to it using either
<a name="script" shape="rect">scripting or templating</a> languages.
</p>
<p>
This traditionally used to be a bit complicated task, however since
version 6.1 there are new interfaces
<api category="deprecated" group="lookup" name="org.openide.loaders.CreateFromTemplateHandler" type="export" url="org-openide-loaders/org/openide/loaders/CreateFromTemplateHandler.html">
can be registered as a services in a lookup and it is reponsible
for handling the whole copy of the template file(s) to the destination
folder.
</api> and
<api category="deprecated" group="lookup" name="org.openide.loaders.CreateFromTemplateAttributesProvider" type="export" url="org-openide-loaders/org/openide/loaders/CreateFromTemplateAttributesProvider.html">
can be registered as a services in a lookup and it is reponsible
for providing "hints" - e.g. map mapping strings to various objects.
</api> and these interfaces allow anyone to extend the behaviour during
creation of new files without writing new
<a href="org-openide-loaders/org/openide/loaders/DataLoader.html" shape="rect">DataLoader</a> and co.
</p>
<p>
The support was moved to a new module; please see <a href="./org-netbeans-api-templates/architecture-summary.html" shape="rect">api.templates</a>
module for more information.
</p>
<h4>How to add action to folder's popup menu?</h4>
<api category="stable" group="layer" name="Loaders-folder-any-Actions" type="export">
The actions that the default folder loader shows in its popup menu are read from
a layer folder <code>Loaders/folder/any/Actions</code>
so if any module wishes
to extend, hide or reorder some of them it can just register its actions there.</api>
As code like this does:
<pre xml:space="preserve">
&lt;folder name="Loaders" &gt;
&lt;folder name="folder" &gt;
&lt;folder name="any" &gt;
&lt;folder name="Actions" &gt;
&lt;file name="org-mymodule-MyAction.instance" &gt;
&lt;attr name="instanceCreate" stringvalue="org.mymodule.MyAction" /&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;/folder&gt;
</pre>
As described in general <a href="./org-openide-actions/org/openide/actions/doc-files/api.html#adv-install" shape="rect">
actions registration tutorial</a>.
<p></p>
This functionality is available since version 5.0 of the loaders module. Please use
<code>OpenIDE-Module-Module-Dependencies: org.openide.loaders &gt; 5.0</code> in your
module dependencies.
<p>
In version 5.8 all the standard loaders were changed to read actions
from layer:
</p>
<ul>
<li>
<api category="stable" group="layer" name="Loaders-text-xml-Actions" type="export">
The actions that the standard XML loader shows in its popup menu are read from
a layer folder <code>Loaders/text/xml/Actions</code>
</api>
</li>
<li>
<api category="stable" group="layer" name="Loaders-content-unknown-Actions" type="export">
The actions that the loader for unrecognized files shows in its popup menu are read from
a layer folder <code>Loaders/content/unknown/Actions</code>
</api>
</li>
<li>
<api category="stable" group="layer" name="Loaders-application-x-nbsettings-Actions" type="export">
The actions that the loader for instance and settings files shows in its popup menu are read from
a layer folder <code>Loaders/application/x-nbsettings/Actions</code>
</api>
</li>
</ul>
<h4>How to allow others to enhance actions of your loader?</h4>
If you want other modules to enhance or modify actions that are visible on
<code>DataObject</code>s produced by your <code>DataLoader</code> and you
are either using <code>DataNode</code> or its subclass, you can just override
<code>protected String actionsContext()</code> method to return non-null
location of context in layers from where to read the actions.
<p></p>
The usual value should match <code>Loaders/mime/type/Actions</code> scheme,
for example java is using <code>Loaders/text/x-java/Actions</code>, but
the name can be arbitrary.
<p></p>
This functionality is available since version 5.0 of the loaders module. Please use
<code>OpenIDE-Module-Module-Dependencies: org.openide.loaders &gt; 5.0</code> in your
module dependencies.
<hr>
<h2>
<a name="usecase-Module System API">How to use </a><a href="overview-summary.html#def-api-Module System API">Module System API</a>?
</h2>
<description>
The Modules API lies at the core of NetBeans and describes how plug-in
modules are added and managed.
<b>ModulesAPI</b>
</description>
<p></p>
<a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">
<img alt="Cover of NetBeans Platform for Beginners book" height="70" src="http://wiki.apidesign.org/images/0/03/NetBeansPlatformForBeginners.jpg" style="float: right" width="60">
</a>
For general overview of the concepts,
together with code samples, see chapter 2,
of <a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">NetBeans Platform for Beginners</a>
by Jason Wexbridge and Walter Nyland.
Gory technical details are explained on <a href="org-openide-modules/org/openide/modules/doc-files/api.html" shape="rect">
API overview page
</a>. Other interesting topic(s) follow:
<h4>How a classpath of my module is constructed?</h4>
The NetBeans is defacto a container that manages individual module's
lifecycle and other runtime aspects. One of the important things is
that it creates a runtime classpath for provided modules based on
dependencies they specify in their manifests. The
<a href="org-openide-modules/org/openide/modules/doc-files/classpath.html" shape="rect">
overview of the runtime infrastructure</a> is a good starting place for
everyone who wishes to learn more about the NetBeans runtime container
behaviour.
<h4>Runtime compatibility patches</h4>
<p>
To maintain binary compatibility, method implementations may be injected
at runtime, in a form of a superclass in the class' inheritance hierarchy.
Modules compiled against older version of APIs which contains MethodReferences to
methods removed from the oficial APIs will be then linked according to JVM Resolution
algorithm to a matching method present in the superclass of the referenced type.
</p>
<p>
Annotations are used to instruct the ClassLoader to make transformations to the API
classes. <a href="org-openide-modules/org/openide/modules/PatchFor.html" shape="rect">PatchFor</a> causes the annotated
class to be injected as a superclass of the API class identified by the annotation's value.
<a href="org-openide-modules/org/openide/modules/ConstructorDelegate.html" shape="rect">ConstructorDelegate</a> marks
a method, which is called as constructor implementation in the case that it is necessary
to preserve a constructor for binary compatibility.
</p>
<hr>
<h2>
<a name="usecase-Nodes API">How to use </a><a href="overview-summary.html#def-api-Nodes API">Nodes API</a>?
</h2>
<description>
Nodes API serves as the main aparatus for visualisation of objects
in NetBeans. Nodes augment objects with standard aspects used for
visualisation (e.g. name, displayName, icons, set of proerties,
subnodes hierarchy, etc.) Once a Node is defined for given object
it can be visualised using diferent views e.g. trees, lists, tables etc.
Descripion of nodes can be found
here.
</description>
<p></p>
<p>
<a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">
<img alt="Cover of NetBeans Platform for Beginners book" height="70" src="http://wiki.apidesign.org/images/0/03/NetBeansPlatformForBeginners.jpg" style="float: right" width="60">
</a>
For general overview of the concepts related to nodes and <a href="./org-openide-explorer/overview-summary.html" shape="rect">explorers</a>,
together with code samples, see chapter 7,
of <a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">NetBeans Platform for Beginners</a>
by Jason Wexbridge and Walter Nyland.
</p>
<hr>
<h2>
<a name="usecase-Settings Options API">How to use </a><a href="overview-summary.html#def-api-Settings Options API">Settings Options API</a>?
</h2>
<description>
<b>org.openide.options</b>
</description>
<p></p>
<p>
N/A
</p>
<hr>
<h2>
<a name="usecase-Text API">How to use </a><a href="overview-summary.html#def-api-Text API">Text API</a>?
</h2>
<description>
The <b>EditorAPI</b> is used for accessing editor-related functionality from within the IDE
for use by other modules and the core IDE itself.
</description>
<p></p>
<p>
XXX no answer for arch-usecases
</p>
<hr>
<h2>
<a name="usecase-Base Utilities API">How to use </a><a href="overview-summary.html#def-api-Base Utilities API">Base Utilities API</a>?
</h2>
<description>
Described in the overall answer.
</description>
<p></p>
<p>
Use-cases can be found in <a href="./org-openide-util-ui/architecture-summary.html" shape="rect">org.openide.util.ui module</a> arch summary.
</p>
<hr>
<h2>
<a name="usecase-Old Enumeration API">How to use </a><a href="overview-summary.html#def-api-Old Enumeration API">Old Enumeration API</a>?
</h2>
<description>
<b>OldEnumerationsAPI</b>
</description>
<p></p>
<p>
Most of the functionality is deprecated, so it is better to go
and use <a href="./org-openide-util/org/openide/util/Enumerations.html" shape="rect">the
replacement API</a> in <code>org-openide-util.jar</code>.
</p>
<hr>
<h2>
<a name="usecase-Lookup API">How to use </a><a href="overview-summary.html#def-api-Lookup API">Lookup API</a>?
</h2>
<description>
Described in the overall answer.
</description>
<p></p>
<a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">
<img alt="Cover of NetBeans Platform for Beginners book" height="70" src="http://wiki.apidesign.org/images/0/03/NetBeansPlatformForBeginners.jpg" style="float: right" width="60">
</a>
There is a great introduction to Lookup and its usage in its
<a href="org-openide-util-lookup/org/openide/util/Lookup.html" shape="rect">javadoc</a>.
For details on this topic,
together with code samples, see chapter 4,
of <a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">NetBeans Platform for Beginners</a>
by Jason Wexbridge and Walter Nyland.
In addition to that here is
a list of frequently asked or interesting questions slowly expanding as
people ask them:
<h3>Lookup faq:</h3>
<h4>How to specify that a service in Lookup should be available only on Windows?</h4>
<em><b>Q:</b>
Most of the time I specify interfaces that I want to add to the Lookup class in the layer.xml file.
But, let's say I have a platform-specific interface (something on Windows only, for instance).</em>
<p>
<em>
How can I specify (in the xml, or programmatically) that this service should only be added to the Lookup if the platform is Windows?
</em>&gt;
</p>
In general there are three ways to achieve this.
<ul>
<li>
<p>It is possible to write a specific module and enable it only on windows.
See <a href="./org-openide-modules/org/openide/modules/doc-files/api.html#how-os-specific" shape="rect">os specific modules</a> documentation.
Then you can put a registration of your instance into your module's
<a href="./org-openide-util/org/openide/util/doc-files/api.html#service-lookup" shape="rect">META-INF/services</a> directory and it
will be available only on Windows.</p>
</li>
<li>
<p>Another possibility that does not require new module, but which executes
a code on startup (which may have performance implications) is to use <code>methodvalue</code>
attribute. Register your instance in layer using <code>your-Object.instance</code> file
as described at
<a href="./org-openide-util/org/openide/util/doc-files/api.html#ido-methodvalue" shape="rect">services
</a> documentation and in your factory method either return the instance
your want or <code>null</code> depending on result of <a href="./org-openide-util/org/openide/util/BaseUtilities.html#isWindows--" shape="rect">
Utilities.isWindows()</a> call.</p>
</li>
<li>
<p>
In some cases, the interface for which you will register an implementation permits a
no-operation semantics. For example, <code>InstalledFileLocator.locate(...)</code> can
return a valid <code>File</code>, or null. You could always register an
<code>InstalledFileLocator</code> instance yet disable it on non-Windows platforms
(always returning null).
</p>
</li>
</ul>
<h4>How shall I write an extension point for my module?</h4>
<p>
<em><b>Q:</b>
I have more modules one of them providing the core functionality and
few more that wish to extend it. What is the right way to do it?
How does the Netbeans platform declare such extension point?
</em>
</p>
<p>
Start with declaring an extension interface in your
core module and put it into the module's <em>public packages</em>. Imagine
for example that the core module is in JAR file <code>org-my-netbeans-coremodule.jar</code>
and already contains in manifests line like
<code>OpenIDE-Module: org.my.netbeans.coremodule/1</code> and wants
to display various tips of the day provided by other modules and thus defines:
</p>
<pre xml:space="preserve">
<span class="java-keywords">package</span> <span class="java-identifier">org</span><span class="java-operators">.</span><span class="java-identifier">my</span><span class="java-operators">.</span><span class="java-identifier">netbeans</span><span class="java-operators">.</span><span class="java-identifier">coremodule</span><span class="java-operators">;</span>
<span class="java-keywords">public</span> <span class="java-keywords">interface</span> <span class="java-identifier">TipsOfTheDayProvider</span> <span class="java-operators">{</span>
<span class="java-keywords">public</span> <span class="java-identifier">String</span> <span class="java-layer-method">provideTipOfTheDay</span> <span class="java-operators">(</span><span class="java-operators">)</span><span class="java-operators">;</span>
<span class="java-operators">}</span>
</pre>
<p>
And in its manifest adds line
<code>OpenIDE-Module-Public-Packages: org.my.netbeans.coremodule.*</code>
to specify that this package contains exported API and shall be
accessible to other modules.
</p>
<p>
When the core module is about to display the tip of the day it can ask
the system for all registered instances of the <code>TipsOfTheDayProvider</code>,
randomly select one of them:
</p>
<pre xml:space="preserve">
<span class="java-keywords">import</span> <span class="java-identifier">java</span><span class="java-operators">.</span><span class="java-identifier">util</span><span class="java-operators">.</span><span class="java-identifier">Collection</span><span class="java-operators">;</span>
<span class="java-keywords">import</span> <span class="java-identifier">java</span><span class="java-operators">.</span><span class="java-identifier">util</span><span class="java-operators">.</span><span class="java-identifier">Collections</span><span class="java-operators">;</span>
<span class="java-keywords">import</span> <span class="java-identifier">org</span><span class="java-operators">.</span><span class="java-identifier">openide</span><span class="java-operators">.</span><span class="java-identifier">util</span><span class="java-operators">.</span><span class="java-identifier">Lookup</span><span class="java-operators">;</span>
<a href="org-openide-util-lookup/org/openide/util/Lookup.Result.html" shape="rect"><span class="java-identifier">Lookup</span><span class="java-operators">.</span><span class="java-identifier">Result</span></a> <span class="java-identifier">result</span> <span class="java-operators">=</span> <a href="org-openide-util-lookup/org/openide/util/Lookup.html" shape="rect"><span class="java-identifier">Lookup</span></a><span class="java-operators">.</span><span class="java-layer-method">getDefault</span> <span class="java-operators">(</span><span class="java-operators">)</span><span class="java-operators">.</span><span class="java-layer-method">lookup</span> <span class="java-operators">(</span><span class="java-keywords">new</span> <a href="org-openide-util-lookup/org/openide/util/Lookup.Template.html" shape="rect"><span class="java-identifier">Lookup</span><span class="java-operators">.</span><span class="java-layer-method">Template</span></a> <span class="java-operators">(</span><span class="java-identifier">TipsOfTheDayProvider</span><span class="java-operators">.</span><span class="java-keywords">class</span><span class="java-operators">)</span><span class="java-operators">)</span><span class="java-operators">;</span>
<span class="java-identifier">Collection</span> <span class="java-identifier">c</span> <span class="java-operators">=</span> <span class="java-identifier">result</span><span class="java-operators">.</span><a href="org-openide-util-lookup/org/openide/util/Lookup.Result.html#allInstances--" shape="rect"><span class="java-layer-method">allInstances</span></a> <span class="java-operators">(</span><span class="java-operators">)</span><span class="java-operators">;</span>
<span class="java-identifier">Collections</span><span class="java-operators">.</span><span class="java-layer-method">shuffle</span> <span class="java-operators">(</span><span class="java-identifier">c</span><span class="java-operators">)</span><span class="java-operators">;</span>
<span class="java-identifier">TipsOfTheDayProvider</span> <span class="java-identifier">selected</span> <span class="java-operators">=</span> <span class="java-operators">(</span><span class="java-identifier">TipsOfTheDayProvider</span><span class="java-operators">)</span><span class="java-identifier">c</span><span class="java-operators">.</span><span class="java-layer-method">iterator</span> <span class="java-operators">(</span><span class="java-operators">)</span><span class="java-operators">.</span><span class="java-layer-method">next</span> <span class="java-operators">(</span><span class="java-operators">)</span><span class="java-operators">;</span>
</pre>
<p>
and then display the tip. Simple, trivial, just by the usage of
<a href="org-openide-util-lookup/org/openide/util/Lookup.html" shape="rect">Lookup</a> interface once
creates a registry that other modules can enhance. But such enhancing
of course requires work on the other side. Each module that would like
to register its <code>TipsOfTheDayProvider</code> needs to depend on the
core module - add
<code>OpenIDE-Module-Module-Dependencies: org.my.netbeans.coremodule/1</code>
into its manifest and write a class with its own implementation of the
provider:</p>
<pre xml:space="preserve">
<span class="java-keywords">package</span> <span class="java-identifier">org</span><span class="java-operators">.</span><span class="java-identifier">my</span><span class="java-operators">.</span><span class="java-identifier">netbeans</span><span class="java-operators">.</span><span class="java-identifier">extramodule</span><span class="java-operators">;</span>
<span class="java-keywords">class</span> <span class="java-identifier">ExtraTip</span> <span class="java-keywords">implements</span> <span class="java-identifier">TipsOfTheDayProvider</span> <span class="java-operators">{</span>
<span class="java-keywords">public</span> <span class="java-identifier">String</span> <span class="java-layer-method">provideTipOfTheDay</span> <span class="java-operators">(</span><span class="java-operators">)</span> <span class="java-operators">{</span>
<span class="java-keywords">return</span> <span class="java-string-literal">"Do you know that in order to write extension point you should use Lookup?"</span><span class="java-operators">;</span>
<span class="java-operators">}</span>
<span class="java-operators">}</span>
</pre>
<p>
Then, the only necessary thing is to register such class by using the
J2SE standard <api category="standard" group="java" name="ProviderRegistrationMechanism" type="import"></api> into plain text file
<code>META-INF/services/org.my.netbeans.coremodule.TipsOfTheDayProvider</code>
in the module JAR containing just one line: </p>
<pre xml:space="preserve">
org.my.netbeans.extramodule.ExtraTip
</pre>
<p>
and your modules are now ready to communicate
using your own <em>extension point</em>.
</p>
<hr>
<h2>
<a name="usecase-Utilities API">How to use </a><a href="overview-summary.html#def-api-Utilities API">Utilities API</a>?
</h2>
<description>
Described in the overall answer.
</description>
<p></p>
<h4>How shall I do or influence logging in NetBeans?</h4>
<p>
If you are interested in logging from inside your module, or in writing
your own log handler or in configuring the whole system, then best place
to start is the <a href="org-openide-util-ui/org/openide/util/doc-files/logging.html" shape="rect">NetBeans logging guide</a>.
</p>
<hr>
<h2>
<a name="usecase-Window System API">How to use </a><a href="overview-summary.html#def-api-Window System API">Window System API</a>?
</h2>
<description>
Window System API is used to display and control application GUI: Main window,
frames, components.
</description>
<p></p>
<p>
<a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">
<img alt="Cover of NetBeans Platform for Beginners book" height="70" src="http://wiki.apidesign.org/images/0/03/NetBeansPlatformForBeginners.jpg" style="float: right" width="60">
</a>
For general overview of the concepts,
together with code samples, see chapter 6,
of <a href="https://leanpub.com/nbp4beginners" onclick="target='_blank'" shape="rect">NetBeans Platform for Beginners</a>
by Jason Wexbridge and Walter Nyland.
</p>
<h4>General Usecases</h4>
General usecases
can be read in the <a href="http://core.netbeans.org/windowsystem/changes.html#4" shape="rect">design document</a>
created before work on new window system design started.
<h4>How to create a '.settings' file for a TopComponent?</h4>
Either write it by hand (not that hard if you copy other file and
tweak it to match your TC), or start the IDE, instantiate the TC
somehow (You have a "Window-&gt;Show My TC", right? ),
copy the file that gets created in $userdir/config/Windows2Local/Component
and cleanup the serialdata section - replace it with proper "&lt;instance class='..." /&gt; tag.
<h4>How to make a TopComponentGroup?</h4>
<p></p>
<b>Q:</b> I'm trying to make a TopComponentGroup. I've just read http://ui.netbeans.org/docs/ui/ws/ws_spec.html#3.9
I want to make a group that uses the first invocation strategy.
That is, I want the group to open/close when I activate a certain subclass of TopComponent.
Say, for example, I have a FooTopComponent, and when it's active,
I want to open a FooPropertySheetComponent, docked in a mode on the right-hand side.
I know I have to:
<ol>
<li>declare the group in the layer file (Windows2/Groups)</li>
<li>have code for opening the group</li>
<li>have code for closing the group</li>
</ol>
I think I do #2 in FooTopComponent.componentActivated() and #3 in
FooTopComponent.componentDeactivated(). Is that right?
<p></p>
<b>A:</b>Yes it is correct way. You can check
<a href="http://www.netbeans.org/source/browse/platform/samples/window-system-groups/" shape="rect">simple test module</a>.
First you must get TopComponentGroup instance using find method then call TopComponentGroup.open()/close().
Here is the code in your componentDeactivated method:
<pre xml:space="preserve">
protected void componentDeactivated ()
{
// close window group containing propsheet, but only if we're
// selecting a different kind of TC in the same mode
boolean closeGroup = true;
Mode curMode = WindowManager.getDefault().findMode(this);
TopComponent selected = curMode.getSelectedTopComponent();
if (selected != null &amp;&amp; selected instanceof FooTopComponent)
closeGroup = false;
if (closeGroup)
{
TopComponentGroup group = WindowManager.getDefault().findTopComponentGroup(TC_GROUP);
if (group != null)
{
group.close();
}
}
}
</pre>
<hr>
<h2>
<a name="usecase-Deprecated, old search API">How to use </a><a href="overview-summary.html#def-api-Deprecated, old search API">Deprecated, old search API</a>?
</h2>
<description>
It allows other modules to define how the nodes they define should be
searched, without depending on any concrete module containing the search
feature.
</description>
<p></p>
<p>
The SearchInfo API+SPI allows other modules to specify whether and how
should nodes they define be searched.
</p>
<p>
The definition is represented by objects implementing interface
<code>SearchInfo</code>. To enable searching on a custom node,
a <code>SearchInfo</code> object must be added to the node's lookup.
In most cases, there is no need to define own class implementing the
interface - one can use factory methods of class
<code>SearchInfoFactory</code>.
</p>
<p>
Example:
</p>
<blockquote>
<pre xml:space="preserve">import org.openide.util.lookup.Lookups;
public class MyNode extends AbstractNode {
public MyNode(FileObject folder) {
super( new MyNodeChildren(folder),
Lookups.singleton(SearchInfoFactory.createSearchInfo(
folder,
true,
new FileObjectFilter[] {
SearchInfoFactory.VISIBILITY_FILTER
}) );
}
...
}</pre>
</blockquote>
<p>
One of the factory methods - <code>createSearchInfoBySubnodes(...)</code>
- requires that a reference to the node itself. In this case, it is not
possible to fully define the lookup in the <code>super(...)</code>
statement of the constructor because a reference to the node is not
available until the call of <code>super(...)</code> returns.
In this case, a special technique must be used:
</p>
<blockquote>
<pre xml:space="preserve">import org.openide.util.lookup.AbstractLookup;
import org.openide.util.lookup.InstanceContent;
public class MyNode extends AbstractNode {
public MyNode() {
this(new InstanceContent());
}
public MyNode(InstanceContent ic) {
super(new AbstractLookup(ic));
ic.add(SearchInfoFactory.createSearchInfoBySubnodes(this));
}
...
}</pre>
</blockquote>
<api category="deprecated" group="java" name="deprecated-SearchAPI" type="export" url="org-openidex-util/index.html">
defines interfaces <code>SearchInfo</code>, <code>FileObjectFilter</code>
and a factory class <code>SearchInfoFactory</code>
</api>
</body>
</html>