<!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 Java Language Infrastructure Tutorial for NetBeans Platform 6.5</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="geertjan.wielenga@sun.com">
  <meta name="indexed" content="y">
  <meta name="description"
 content="A walk-through of the Retouche approach.">
<!--      Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. -->
<!--     Use is subject to license terms.-->
</head>
<body>
<h1>NetBeans Java Language Infrastructure Tutorial</h1>

<p>In this tutorial, you will be introduced to aspects of the NetBeans "Retouche" APIs,
which give you access to the NetBeans Java editor.


  <p><strong class="notes">Note: </strong>This document uses the NetBeans IDE 6.5 Release. If you
    are using an earlier version, see <a href="60/nbm-copyfqn.html">the 6.0/6.1 version
    of this document</a>.

   <p><b>Contents</b></p>
   
       <img  src="../images/articles/65/netbeans-stamp65.gif" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 6.5" title="Content on this page applies to NetBeans IDE 6.5"> </p>
      <ul class="toc">
            <li><a href="#intro">Introduction to the Java Language Infrastructure</a></li>
            <li><a href="#setting-up-the-module">Setting Up the Module</a></li>
            <li><a href="#creating-a-context-sensitive-toolbar-button">Creating a Context-Sensitive Toolbar Button</a></li>
            <li><a href="#identifying-java-source-files">Identifying Java Source Files</a></li>
            <li><a href="#determining-open-state">Determining Open State</a></li>
            <li><a href="#detecting-the-element-under-the-caret">Detecting the Element Under the Caret</a></li>
            <li><a href="#doing-something-useful">Doing Something Useful</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.5</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 or<br/>version 5</td>
            </tr>
        </tbody>
    </table>
    
      <p class="tips">Optionally, for troubleshooting purposes, you can <a href="http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=2753">download the
   completed sample</a> and inspect the sources.

<p><h2><a name="intro"></a>Introduction to the Java Language Infrastructure</h2>

 <p>Prior to NetBeans IDE 6.0,
 the Java language infrastructure that supported the Java editor, including Java code generation and
 Java refactoring, was based on something called "JMI for Java" (also known as "MDR").  JMI for Java 
 had a few architectural issues such as single-read lock. In other words, a lock had to be acquired just to read
 information from its model, while this is normally required when doing write actions only. Over a period of a
 few years, JMI was debugged and improved in terms of performance. But another issue was that it used its own internal
 copy of the Java parser, which meant it had its own approach to interpreting Java source, which differed from 
 the JDK's Java compiler. With the introduction of generics in JDK 5, which introduced a lot more complicated 
 and subtle Java constructs, that divergence became harder to manage. Therefore, because of JMI's performance issues
 and because a formal language model was developed to make the JDK Java compiler a programmatically accessible tool,
 the JMI for Java was replaced with a new approach, based on the JDK Java compiler. 
 
 <p>That is when Retouche, a French word
 meaning "touch up", was born. Retouche is the new and fast Java language infrastructure in NetBeans IDE, capable of
 supporting all the cool Java editor features that have been realised in NetBeans 6.0. At the heart of it, Retouche
 wraps an instance of the JDK Java compiler and consumes its artifacts, such as the abstract syntax tree (also known as "AST")
 and the symbolic resolutions that are emitted in various phases of parsing. When working with Retouche, you need to deal
 with some of these artifacts. The <a href="http://java.sun.com/javase/6/docs/jdk/api/javac/tree/index.html">Compiler Tree API</a> is one of these, for example. The package naming of 
 classes in the Compiler Tree API is <tt>com.sun.*</tt>. Therefore, technically, this is a non-JDK API, but it does come from the JDK Java compiler. 
 Another example of the JDK Java compiler's artifacts that you work with in relation to Retouche is the formal language model
 in the JDK APIs, provided by the <tt>javax.language.model.*</tt> packages.
 

<p><h2><a name="setting-up-the-module"></a>Setting Up the Module</h2>

     <p>In this section, we use wizards to create a module project and
         to set dependencies on relevant NetBeans modules. 
         
         <ol>
         
         <li>Choose File &gt; New Project. In the New Project wizard,
         choose NetBeans Modules under Categories and Module Project
     under Projects and click Next. 
     
     <li>Type <tt>CopyFQN</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>Type <tt>org.netbeans.modules.copyfqn</tt> in Code Name Base
     and <tt>CopyFQN</tt> in Module Display Name. Click Finish.
     
     <li>Right-click the project, choose Properties, click Libraries 
     in the Project Properties dialog box and declare a dependency on the following APIs:
     
     <p><ul>
         <li>Datasystems API
         <li>Editor Library 2
         <li>File System API
         <li>Javac API Wrapper
         <li>Java Source
         <li>Nodes API
         <li>Text API
         <li>UI Utilities API
         <li>Utilities API
         <li>Window System API
     </ul>
     
     <p>You should now see this:
     
<p align="left"><img border="1" src="../images/tutorials/copyfqn/proj-props-copyfqn-60.png" alt="copy fqn">
     
     
     
     <p>Click OK.
     
 </ol>
 
 <p><h2><a name="creating-a-context-sensitive-toolbar-button"></a>Creating a Context-Sensitive Toolbar Button</h2>

 <p>In this section, we create a context-aware button
  in the toolbar. This has nothing to do with the new
  Retouche APIs, but gives us a user interface element
  for interacting with our implementation of the Retouche APIs, later in this
  tutorial.
 
 <ol>
     <li>Right-click the module project, choose
     New &gt; Other and choose Action from the
     Module Development category. Click Next.
     
     <li><p>Choose Conditionally Enabled, and keep
     all the defaults, as shown below, so that
     the action will be sensitive to <tt>DataObjects</tt>
     and so that it will only be enabled when one <tt>DataObject</tt>
     is selected.</p>
     
     
     <p align="left"><img border="1" src="../images/tutorials/copyfqn/cookie-action-60.png" alt="cookie action">
     
     <p>Click Next. 
     
     <li>Choose Edit in Category and Edit in Toolbar. </p>
     
     <p>You should now see the following:
     
     <p align="left"><img border="1" src="../images/tutorials/copyfqn/gui-registration-60.png" alt="gui registration">
     
     <p>Click Next.</p> 
     
     <li>Type <tt>CopyFQNAction</tt> in Class Name
         and <tt>CopyFQN</tt> in Display Name. 
         
         <li>Browse to an icon that will be displayed in the toolbar button. For example, use the one that
          will be used throughout this tutorial:</p>
     
     <p align="left"><img border="1" src="../images/tutorials/copyfqn/icon.png" alt="icon">
     
     <p>Click Finish.</p>
     
     <p>You should now see the following code in your new
     <tt>CopyFQNAction.java</tt> class:
     
<pre class="examplecode">public final class CopyFQNAction extends CookieAction {
    
    protected void performAction(Node[] activatedNodes) {
        DataObject dataObject = activatedNodes[0].getLookup().lookup(org.openide.loaders.DataObject.class);
        // TODO use dataObject
    }
    
    protected int mode() {
        return CookieAction.MODE_EXACTLY_ONE;
    }
    
    public String getName() {
        return NbBundle.getMessage(CopyFQNAction.class, "CTL_CopyFQNAction");
    }
    
    protected Class[] cookieClasses() {
        return new Class[] {
            DataObject.class
        };
    }
    
    protected String iconResource() {
        return "org/netbeans/modules/copyfqn/icon.png";
    }
    
    public HelpCtx getHelpCtx() {
        return HelpCtx.DEFAULT_HELP;
    }
    
    protected boolean asynchronous() {
        return false;
    }
    
}</pre>     
     
     <p><b class="notes">Note:</b> All the work we will do in the remainder
         of this tutorial will focus on the <tt>performAction()</tt>
     method above.</p>

     <p>You have now created an action that is sensitive to data objects. Let's see what that means right away. 
     
     <li>Right-click the module and choose Install.</p>
     
     <p>Once the module is installed, you should see a new button in the toolbar. 
     
          <li>Select a node in the Projects window and then look at the button in the toolbar. If you select
          a node representing a file or folder (including a package) the button is enabled, as shown here:</p>
         
          <p align="left"><img border="1" src="../images/tutorials/copyfqn/ctx-sensitive-on.png" alt="icon">
    
          <p>However, if you select a node representing a project,
          the button is disabled, as shown below:</p>
         
          <p align="left"><img border="1" src="../images/tutorials/copyfqn/ctx-sensitive-off.png" alt="icon">
         
     </li>
 </ol>
 <p>In the next section, we will go further than distinguishing between project nodes and file/folder nodes&#8212;we will
  distinguish between file nodes for Java classes versus all other kinds of file nodes.
  
  
 <p><h2><a name="identifying-java-source-files"></a>Identifying Java Source Files</h2>

 <p>In this section, we begin using one of the
 new "Retouche" APIs, called <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-java-source/overview-summary.html">Java Source</a>.
 Here we use the <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-java-source/org/netbeans/api/java/source/JavaSource.html">JavaSource</a> class,
 which represents a Java source file. We return an instance of
 this class for the file object associated with our data object.
 If null is returned, the file object is not a Java source file.
 We display the result in the status bar, when the button
 is clicked while a file is selected.
 
 <ol>
     
     <li>Fill out the <tt>performAction()</tt> method by
      adding the lines highlighted below:
     
     <pre class="examplecode">protected void performAction(Node[] activatedNodes) {
    DataObject dataObject = activatedNodes[0].getLookup().lookup(org.openide.loaders.DataObject.class);
    // TODO use dataObject

    <b>FileObject fileObject = dataObject.getPrimaryFile();

    <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-java-source/org/netbeans/api/java/source/JavaSource.html">JavaSource</a> javaSource = <a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-java-source/org/netbeans/api/java/source/JavaSource.html#forFileObject(org.openide.filesystems.FileObject)">JavaSource.forFileObject(fileObject)</a>;
    if (javaSource == null) {
        StatusDisplayer.getDefault().setStatusText("Not a Java file: " + fileObject.getPath());
    } else {
        StatusDisplayer.getDefault().setStatusText("Hurray! A Java file: " + fileObject.getPath());
    }</b>
}</pre>
      
<li>Check that your import statements are as follows:

<pre class="examplecode">import org.netbeans.api.java.source.JavaSource;
import org.openide.awt.StatusDisplayer;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataObject;
import org.openide.nodes.Node;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CookieAction;</pre>

     <li>Install the module again.
     
     <li><p>Select a file node and press the button.</p>
     
     <p>Notice that the "Hurray!" message only appears when
     you select a Java file, as shown below:</p>
     
<p align="left"><img border="1" src="../images/tutorials/copyfqn/message-java-file-60.png" alt="message-java-file-60">
     

<p>An alternative approach would be to <i>only enable the button when a Java file is selected</i>. To
implement this, override the <tt>CookieAction.enable()</tt> method as follows:</p>

<pre class="examplecode">@Override
protected boolean enable(Node[] activatedNodes) {
    if (super.enable(activatedNodes)) {
        DataObject dataObject = activatedNodes[0].getLookup().lookup(org.openide.loaders.DataObject.class);
        FileObject fileObject = dataObject.getPrimaryFile();
        JavaSource javaSource = JavaSource.forFileObject(fileObject);
        if (javaSource == null) {
            return false;
        }
        return true;
    }
    return false;
}</pre>

<p>The above method filters out any file that is <i>not</i> a Java file. As a result, the button is
only enabled if the current file is a Java file.</p>

 </ol>


 <p><h2><a name="determining-open-state"></a>Determining Open State</h2>

 <p>In this section, we are introduced to our first explicitly invoked "Retouche" task.
 Such a task is provided by the JavaSource class's <tt>runUserActionTask</tt> method.
  A task of this kind lets you control the phases of a parsing process, which is applicable
  when you want to respond immediately to the user's input. Everything done within the
  task is done as a single unit. In our case, we want the invocation of our action, represented
  by a button in the toolbar, to be immediately followed by the display of a text in
  the status bar.
 
 <ol>
     
     <li>Replace the "Hurray!" message in the <tt>performAction()</tt> method with
      this line:

<pre class="examplecode"><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-java-source/org/netbeans/api/java/source/JavaSource.html#runUserActionTask(org.netbeans.api.java.source.Task,%20boolean)">javaSource.runUserActionTask</a>(new <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-java-source/org/netbeans/api/java/source/Task.html">Task</a>&lt;<a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-java-source/org/netbeans/api/java/source/CompilationController.html">CompilationController</a>&gt;());</pre>       

<p>You should now see a lightbulb in the editor's left sidebar, as shown here:
      
 <p align="left"><img border="1" src="../images/tutorials/copyfqn/runuserasactiontask-60.png" alt="icon">
         
      <li>Click the lightbulb. Alternatively, put the caret in the line and press Alt-Enter.
       Then let the IDE implement the method.
      
      <li>Tweak the method slightly, by adding a <tt>true</tt> boolean to the end of the
      method and letting the IDE wrap the snippet in a try/catch block. At the end, the result should be as follows:
      
     <pre class="examplecode">protected void performAction(Node[] activatedNodes) {
    DataObject dataObject = activatedNodes[0].getLookup().lookup(org.openide.loaders.DataObject.class);
    // TODO use dataObject

    FileObject fileObject = dataObject.getPrimaryFile();

    JavaSource javaSource = JavaSource.forFileObject(fileObject);
    if (javaSource == null) {
        StatusDisplayer.getDefault().setStatusText("Not a Java file: " + fileObject.getPath());
     } else {
     
            <b>try {
                javaSource.runUserActionTask(new Task&lt;CompilationController&gt;() {

                    public void run(CompilationController arg0) throws Exception {
                        throw new UnsupportedOperationException("Not supported yet.");
                    }
                }, true);
            } catch (IOException ex) {
                Exceptions.printStackTrace(ex);
            }</b>
            
     }

}</pre>

      <li>Implement the <tt>run()</tt> method as follows:
     
     <pre class="examplecode">public void run(CompilationController compilationController) throws Exception {
     
      <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-java-source/org/netbeans/api/java/source/CompilationController.html#toPhase(org.netbeans.api.java.source.JavaSource.Phase)">compilationController.toPhase(Phase.ELEMENTS_RESOLVED)</a>;
      
      <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/text/Document.html">Document</a> document = <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-java-source/org/netbeans/api/java/source/CompilationController.html#getDocument()">compilationController.getDocument()</a>;
      if (document != null) {
         StatusDisplayer.getDefault().setStatusText("Hurray, the Java file is open!");
      } else {
         StatusDisplayer.getDefault().setStatusText("The Java file is closed!");
      }
      
}</pre>

<li>Make sure that your import statements are as follows:

<pre class="examplecode">import java.io.IOException;
import javax.swing.text.Document;
import org.netbeans.api.java.source.CompilationController;
import org.netbeans.api.java.source.JavaSource;
import org.netbeans.api.java.source.JavaSource.Phase;
import org.netbeans.api.java.source.Task;
import org.openide.awt.StatusDisplayer;
import org.openide.filesystems.FileObject;
import org.openide.loaders.DataObject;
import org.openide.nodes.Node;
import org.openide.util.Exceptions;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.CookieAction;</pre>

     <li>Install the module again.
     
     <li>Select a file node and press the button.</p> 
     
     <p>Notice that the "Hurray!" message only appears when
     you select a Java file that is open in the Java editor, as shown here:
     
     <p align="left"><img border="1" src="../images/tutorials/copyfqn/message-java-file-open-60.png" alt="message-java-file-open-60">

 </ol>


 <p><h2><a name="detecting-the-element-under-the-caret"></a>Detecting the Element Under the Caret</h2>

 <p>In this section, now that we know that we are dealing with a Java file and that it is
  open, we can begin detecting the type of element that is under the caret at any given
  time.
 
 <ol>
     
     <li>Begin by declaring a dependency on the I/O APIs, so
     that we can print our results to the Output window.
     
     <li>Replace the "Hurray!" message in the <tt>run()</tt> method with
      the lines highlighted below:
  
 <pre class="examplecode">public void run(CompilationController compilationController) throws Exception {
    
    compilationController.toPhase(Phase.ELEMENTS_RESOLVED);
    Document document = compilationController.getDocument();
    
    if (document != null) {
        <b>new MemberVisitor(compilationController).scan(compilationController.getCompilationUnit(), null);</b>
    } else {
        StatusDisplayer.getDefault().setStatusText("The Java file is closed!");
    }
    
}</pre>   
 
    
<p><li>And here is the <tt>MemberVisitor</tt> class, which
    is defined as an inner class of our <tt>CopyFQNAction</tt> class:
    
                                                                                                                                                                                       
 <pre class="examplecode">private static class MemberVisitor extends TreePathScanner&lt;Void, Void&gt; {

    private CompilationInfo info;

    public MemberVisitor(CompilationInfo info) {
        this.info = info;
    }

    @Override
    public Void visitClass(ClassTree t, Void v) {
        Element el = info.getTrees().getElement(getCurrentPath());
        if (el == null) {
            StatusDisplayer.getDefault().setStatusText("Cannot resolve class!");
        } else {
            TypeElement te = (TypeElement) el;
            List<? extends Element> enclosedElements = te.getEnclosedElements();
            InputOutput io = IOProvider.getDefault().getIO("Analysis of "  
                        + info.getFileObject().getName(), true);
            for (int i = 0; i < enclosedElements.size(); i++) {
            Element enclosedElement = (Element) enclosedElements.get(i);
                if (enclosedElement.getKind() == ElementKind.CONSTRUCTOR) {
                    io.getOut().println("Constructor: " 
                        + enclosedElement.getSimpleName());
                } else if (enclosedElement.getKind() == ElementKind.METHOD) {
                    io.getOut().println("Method: " 
                        + enclosedElement.getSimpleName());
                } else if (enclosedElement.getKind() == ElementKind.FIELD) {
                    io.getOut().println("Field: " 
                        + enclosedElement.getSimpleName());
                } else {
                    io.getOut().println("Other: " 
                        + enclosedElement.getSimpleName());
                }
            }
            io.getOut().close();
        }
        return null;
    }

}</pre>
    
    <li>Install the module again, and open a Java class.
    Then click the button and notice that the
    constructors, methods, and fields are written
to the Output window, as shown below:</p>
     
 
 <p align="left"><img border="1" src="../images/tutorials/copyfqn/output-window-60.png" alt="message-constructor-60">
         
  
 <li>Next, instead of printing all the elements
  to the Output window, we will only print
  the element under the caret. Only replace the
  <tt>visitClass</tt> method, with the code highlighted below:
                                                                                                                                                        
 <pre class="examplecode">private static class MemberVisitor extends TreePathScanner&lt;Void, Void&gt; {

    private CompilationInfo info;

    public MemberVisitor(CompilationInfo info) {
        this.info = info;
    }

    <b>@Override
    public Void visitClass(ClassTree t, Void v) {
        try {
            JTextComponent editor = EditorRegistry.lastFocusedComponent();
            if (editor.getDocument() == info.getDocument()) {
                int dot = editor.getCaret().getDot();
                TreePath tp = info.getTreeUtilities().pathFor(dot);
                Element el = info.getTrees().getElement(tp);
                if (el == null) {
                    StatusDisplayer.getDefault().setStatusText("Cannot resolve class!");
                } else {
                    InputOutput io = IOProvider.getDefault().getIO("Analysis of " 
                            + info.getFileObject().getName(), true);
                    if (el.getKind() == ElementKind.CONSTRUCTOR) {
                        io.getOut().println("Hurray, this is a constructor: " 
                            + el.getSimpleName());
                    } else if (el.getKind() == ElementKind.METHOD) {
                        io.getOut().println("Hurray, this is a method: " 
                            + el.getSimpleName());
                    } else if (el.getKind() == ElementKind.FIELD) {
                        io.getOut().println("Hurray, this is a field: " 
                            + el.getSimpleName());
                    } else {
                        io.getOut().println("Hurray, this is something else: " 
                            + el.getSimpleName());
                    }
                    io.getOut().close();
                }
            }
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        }
        return null;
    }</b>

}</pre>  
   
      <li>Install the module.
    
    <li>Put the caret somewhere within your Java code and press the button. The Output window
      displays information about the code under the caret, if applicable. For example, if you
      press the button after you put the caret in a method, as shown below, the Output window
  tells you that the caret is in a method:</p> 
 
   <p align="left"><img border="1" src="../images/tutorials/copyfqn/message-constructor-60.png" alt="message-constructor-60">

   
   <li>But we can detect a lot more than just the name
   of the element under the caret. In the <tt>visitClass</tt>
   method, replace the lines in bold below:
     
    
   <pre class="examplecode">@Override
public Void visitClass(ClassTree t, Void v) {
    try {
        JTextComponent editor = EditorRegistry.lastFocusedComponent();
        if (editor.getDocument() == info.getDocument()) {
            int dot = editor.getCaret().getDot();
            TreePath tp = info.getTreeUtilities().pathFor(dot);
            Element el = info.getTrees().getElement(tp);
            if (el == null) {
                StatusDisplayer.getDefault().setStatusText("Cannot resolve class!");
            } else {
                InputOutput io = IOProvider.getDefault().getIO("Analysis of " 
                    + info.getFileObject().getName(), true);
                <b>String te = null;
                if (el.getKind() == ElementKind.CONSTRUCTOR) {
                    te = ((TypeElement) ((ExecutableElement) el).getEnclosingElement()).getQualifiedName().toString();
                    io.getOut().println("Hurray, this is a constructor's qualified name: " + te);
                } else if (el.getKind() == ElementKind.METHOD) {
                    te = ((ExecutableElement) el).getReturnType().toString();
                    io.getOut().println("Hurray, this is a method's return type: " + te);
                } else if (el.getKind() == ElementKind.FIELD) {
                    te = ((VariableElement) el).asType().toString();
                    io.getOut().println("Hurray, this is a field's type: " + te);
                }</b> else {
                    io.getOut().println("Hurray, this is something else: " 
                        + el.getSimpleName());
                }
                io.getOut().close();
            }
        }
    } catch (IOException ex) {
        Exceptions.printStackTrace(ex);
    }
    return null;
}</pre>
    
<li>Install the module again. This time, when you click
 the button while the caret is over a constructor, method,
  or field, more detailed information about the element
  is printed to the Output window.
    
 </ol>

<p>At this stage, we are able to detect whether we are dealing with a Java file, whether the
 document is open, and the type of element that is under the caret. But what can we do with
 this information? In the next section, a simple scenario is presented where our newly acquired
 knowledge will prove useful.</p>


<p><h2><a name="doing-something-useful"></a>Doing Something Useful</h2>

<p>In this section, we set the contents of the clipboard, provided by <tt>java.awt.datatransfer.Clipboard</tt>,
 based on the element under the caret. When you press the button, the element under the caret will
 be put in the clipboard, so that you can paste the content elsewhere in your code. 
 
 <ol>
     
     <li>Begin by declaring the clipboard and defining a constructor:
     
     <pre class="examplecode">private Clipboard clipboard;

public CopyFQNAction() {
    clipboard = Lookup.getDefault().lookup(ExClipboard.class);
    if (clipboard == null) {
        clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    }
}</pre>
      
     <li>Next, replace each "Hurray!" line in your code, with a line that sends the element as a string
     to a method that we will define in the next step. We will call our method <tt>setClipboardContents</tt>.
     Therefore, for example, replace the first "Hurray!" line with the following:
     
<pre class="examplecode">setClipboardContents(te);</pre>

<p>Do the same for the other "Hurray!" lines, making sure to pass the correct string to the method.

     <p><b class="notes">Note:</b> Because you have not defined the <tt>setClipboardContents</tt> method yet, each of the
      lines you add in this step is underlined in red. In the next step, we add the new method.

     <li>Finally, add the following to the end of the class. This method receives the
 string and puts it in the clipboard:
     
     <pre class="examplecode">private void setClipboardContents(String content) {
    if (clipboard != null) {
        if (content == null) {
            StatusDisplayer.getDefault().setStatusText("");
            clipboard.setContents(null, null);
        } else {
            StatusDisplayer.getDefault().setStatusText("Clipboard: " + content);
            clipboard.setContents(new StringSelection(content), null);
        }
    }
}</pre>


 </ol>
 
<br>
<div class="feedback-box"><a href="https://netbeans.org/about/contact_form.html?to=3&amp;subject=Feedback:%20Java%20Language%20Infrastructure%20Tutorial">Send Us Your Feedback</a></div>
<br style="clear:both;" />

    
 <!-- ======================================================================================== -->

<h2><a name="nextsteps"></a>See Also</h2>

<p>For more information about creating and developing NetBeans Module, see the following resources: 
  <ul>
	  <li><a href="http://wiki.netbeans.org/Java_DevelopersGuide">Java Developer's Guide</a></li>
	  <li><a href="http://wiki.netbeans.org/RetoucheDeveloperFAQ">Retouche Developer FAQ</a></li>
	  <li><a href="https://netbeans.org/kb/trails/platform.html">Other Related Tutorials</a></li>
	  <li><a href="https://netbeans.org/download/dev/javadoc/">NetBeans API Javadoc</a></li>
  </ul>
    
    <!-- ======================================================================================== -->

    </body>
</html>
