blob: 0c81a07c2bb9fdf27fef4883d01c0af66c7b667f [file] [log] [blame]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!-- -*- xhtml -*- -->
<title>NetBeans Hyperlink Navigation Tutorial</title>
<link rel="stylesheet" type="text/css" href="https://netbeans.org/netbeans.css"/>
<meta name="AUDIENCE" content="NBUSER"/>
<meta name="TYPE" content="ARTICLE"/>
<meta name="EXPIRES" content="N"/>
<meta name="developer" content="tboudreau@netbeans.org"/>
<meta name="indexed" content="y"/>
<meta name="description"
content="A hyperlink in/to HTML files."/>
<!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. -->
<!-- Use is subject to license terms.-->
</head>
<body>
<h1>NetBeans Hyperlink Navigation Tutorial</h1>
<p>In this tutorial, you learn how to programmatically define hyperlinks in HTML files. You will
do this by implementing the NetBeans API <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-lib/org/netbeans/lib/editor/hyperlink/spi/HyperlinkProvider.html">HyperlinkProvider</a> class.
The hyperlink will be visible when the user holds down the Ctrl key and then uses
the mouse to move over a predefined identifier in an HTML document, as shown here:</p>
<p><img alt="" src="../images/tutorials/hyperlink/hyperlink-69-1.png"/></p>
<p>When the hyperlink is clicked, something happens relevant to the identifier,
for example, a related file can open or a message can be displayed.</p>
<p>Though the focus of this tutorial is on hyperlinking in an HTML file,
the principles shown here could equally be applied to other types of files,
such as to Java source files, XML files, JSP files, Properties files, or Manifest files.</p>
<!-- ===================================================================================== -->
<p><b class="notes">Note:</b> This document is applicable to NetBeans Platform 6.9 and above. If you
are using an earlier version, see <a href="68/nbm-hyperlink.html">the previous version
of this document</a>.</p>
<p><b>Contents</b></p>
<p><img src="../images/articles/69/netbeans-stamp69.png" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 6.9 and above" title="Content on this page applies to NetBeans IDE 6.9 and above"/></p>
<ul class="toc">
<li><a href="#getting">Getting Started</a></li>
<li><a href="#implementing">Implementing the HyperlinkProvider Class</a></li>
<li><a href="#registering">Registering the HyperlinkProvider Implementation Class</a></li>
</ul>
<p><b>To follow this tutorial, you need the software and resources listed in the following
table.</b></p>
<table>
<tbody>
<tr>
<th class="tblheader" scope="col">Software or Resource</th>
<th class="tblheader" scope="col">Version Required</th>
</tr>
<tr>
<td class="tbltd1"><a href="https://netbeans.org/downloads/index.html">NetBeans IDE</a></td>
<td class="tbltd1">version 6.9 or above</td>
</tr>
<tr>
<td class="tbltd1"><a href="http://java.sun.com/javase/downloads/index.jsp">Java Developer Kit (JDK)</a></td>
<td class="tbltd1">Version 6</td>
</tr>
</tbody>
</table>
<p></p>
<h2><a name="getting"></a>Getting Started</h2>
<p>In this section, we use a wizard to create a module project.
We declare dependencies on modules that provide the NetBeans API classes
needed by our hyperlink module.</p>
<ol>
<li>Choose File &gt; New Project. In the New Project wizard,
choose NetBeans Plug-in Modules under Categories and Module Project
under Projects. Click Next. Type <tt>MySpecialHyperlink</tt> in Project Name
and set Project Location to an appropriate folder on your disk. If they
are not selected, select
Standalone Module and Set as Main Project. Click Next.</li>
<li>Type <tt>org.netbeans.modules.myspecialhyperlink</tt> in Code Name Base.</li>
<li>Select "Generate XML Layer" and then click Finish.</li>
<li>Right-click the project, choose Properties, click Libraries
in the Project Properties dialog box and declare a dependency on the following APIs:
<ul>
<li>Dialogs API</li>
<li>Editor Library</li>
<li>Editor Library 2</li>
<li>HTML Lexer</li>
<li>Lexer</li>
</ul>
</li>
</ol>
<!-- ===================================================================================== -->
<h2><a name="implementing"></a>Implementing the HyperlinkProvider Class</h2>
<p>The <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-lib/org/netbeans/lib/editor/hyperlink/spi/HyperlinkProvider.html">HyperlinkProvider</a> class
implements three methods, each of which is discussed in detail below, accompanied by a
practical example in the context of our module. First we set up the class and then
we implement each of the three methods in turn.</p>
<div class="indent">
<h3 class="tutorial"><a name="method1"></a>Setting Up the HyperlinkProvider Class</h3>
<p>Setting up our class means implementing <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-lib/org/netbeans/lib/editor/hyperlink/spi/HyperlinkProvider.html">HyperlinkProvider</a>
and initializing the values we will need in our implementation.</p>
<ol>
<li>Create a Java class in <tt>org.netbeans.modules.myspecialhyperlink</tt>,
and name it <tt>MySpecialHyperlinkProvider</tt>.</li>
<li>Change the class signature so that <tt>HyperlinkProvider</tt> is implemented.</li>
<li>Note that the following import statements will be needed:
<pre class="examplecode">import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.text.Document;
import org.netbeans.api.html.lexer.HTMLTokenId;
import org.netbeans.api.lexer.Token;
import org.netbeans.api.lexer.TokenHierarchy;
import org.netbeans.api.lexer.TokenSequence;
import org.netbeans.lib.editor.hyperlink.spi.HyperlinkProvider;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;</pre>
</li>
<li>Add the following initial values at the top of the class:
<pre class="examplecode">public static final Pattern MY_SPECIAL_PATTERN =
Pattern.compile(".*\\[myspecial:(.*?):myspecial\\].*");
private String target;
private int targetStart;
private int targetEnd;</pre></li>
</ol>
</div>
<div class="indent">
<h3 class="tutorial"><a name="method1"></a>isHyperlinkPoint(Document doc, int offset)</h3>
<p><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-lib/org/netbeans/lib/editor/hyperlink/spi/HyperlinkProvider.html#isHyperlinkPoint(javax.swing.text.Document,%20int)">isHyperlinkPoint(Document doc, int offset)</a>
determines whether there should be a hyperlink at the given offset within the given document.</p>
<pre class="examplecode">@Override
public boolean isHyperlinkPoint(Document doc, int offset) {
return verifyState(doc, offset);
}
public boolean verifyState(Document doc, int offset) {
TokenHierarchy hi = TokenHierarchy.get(doc);
TokenSequence&lt;HTMLTokenId&gt; ts = hi.tokenSequence(HTMLTokenId.language());
if (ts != null) {
ts.move(offset);
ts.moveNext();
Token&lt;HTMLTokenId&gt; tok = ts.token();
int newOffset = ts.offset();
String matcherText = tok.text().toString();
Matcher m = MY_SPECIAL_PATTERN.matcher(matcherText);
if (m.matches()) {
target = m.group(1);
int idx = matcherText.indexOf(target);
targetStart = newOffset + idx;
targetEnd = targetStart + target.length();
return true;
}
}
return false;
}</pre>
</div>
<div class="indent">
<h3 class="tutorial"><a name="method2"></a>getHyperlinkSpan(Document doc, int offset)</h3>
<p><tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-lib/org/netbeans/lib/editor/hyperlink/spi/HyperlinkProvider.html#getHyperlinkSpan(javax.swing.text.Document,%20int)">getHyperlinkSpan(Document doc, int offset)</a></tt> determines the length of the hyperlink.</p>
<pre class="examplecode">@Override
public int[] getHyperlinkSpan(Document document, int offset) {
if (verifyState(document, offset)) {
return new int[]{targetStart, targetEnd};
} else {
return null;
}
}</pre>
</div>
<div class="indent">
<h3 class="tutorial"><a name="method3"></a>performClickAction(Document doc, int offset)</h3>
<a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-lib/org/netbeans/lib/editor/hyperlink/spi/HyperlinkProvider.html#performClickAction(javax.swing.text.Document,%20int)">performClickAction(Document doc, int offset)</a>
determines what happens when the hyperlink is clicked. In general, a document
should open, the cursor should move to a certain place in a document, or both.
Here a simple message is displayed with the identified special content:
<pre class="examplecode">@Override
public void performClickAction(Document document, int offset) {
if (verifyState(document, offset)) {
NotifyDescriptor.Message msg = new NotifyDescriptor.Message(target);
DialogDisplayer.getDefault().notify(msg);
}
}</pre>
</div>
<!-- ===================================================================================== -->
<h2><a name="registering"></a>Registering the HyperlinkProvider Implementation Class</h2>
<p>Finally, you need to register the hyperlink provider implementation class
in the module's <tt>layer.xml</tt> file. Do this as follows, while making sure
that the line in bold below is the fully qualified class name of the class that
implements HyperlinkProvider:</p>
<pre class="examplecode">&lt;folder name="Editors"&gt;
&lt;folder name="text"&gt;
&lt;folder name="html"&gt;
&lt;folder name="HyperlinkProviders"&gt;
&lt;file name="MySpecialHyperlinkProvider.instance"&gt;
<b>&lt;attr name="instanceClass" stringvalue="org.netbeans.modules.myspecialhyperlink.MySpecialHyperlinkProvider"/&gt;</b>
&lt;attr name="instanceOf" stringvalue="org.netbeans.lib.editor.hyperlink.spi.HyperlinkProvider"/&gt;
&lt;/file&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;/folder&gt;
&lt;/folder&gt;</pre>
<p>If you create a hyperlink for a different MIME type, you need to change the
<tt>text/html</tt> folders above to the appropriate MIME type.</p>
<p>Now that the HyperlinkProvider is registered, you can install the module and
try out your new hyperlinks. </p>
<div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&amp;subject=Feedback:%20Hyperlink%20Module%20Tutorial">Send Us Your Feedback</a></div>
<!-- ===================================================================================== -->
</body>
</html>