<!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) 2009, 2010, Oracle and/or its affiliates. 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>

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

   <p><b>Contents</b></p>
   
   <p><img src="../images/articles/69/netbeans-stamp7-8-9.png" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 6.5, 6.7, 6.8" title="Content on this page applies to NetBeans IDE 6.5, 6.7, 6.8"/></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.7 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 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>
 
 <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. </p>
         
         <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>
     
     <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>
     
     <li>Type <tt>org.netbeans.modules.copyfqn</tt> in Code Name Base
         and <tt>CopyFQN</tt> in Module Display Name. 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>Datasystems API</li>
         <li>Editor Library 2</li>
         <li>File System API</li>
         <li>Javac API Wrapper</li>
         <li>Java Source</li>
         <li>Nodes API</li>
         <li>Text API</li>
         <li>UI Utilities API</li>
         <li>Utilities API</li>
         <li>Window System API</li>
             </ul>
     
         <p>You should now see this:</p>
     
         <p><img src="../images/tutorials/copyfqn/proj-props-copyfqn-60.png" alt="copy fqn"/></p>
     
         <p>Click OK.</p></li>
     
 </ol>
 
 <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.</p>
 
 <ol>
     <li>Right-click the module project, choose
     New &gt; Other and choose Action from the
     Module Development category. Click Next.</li>
     
     <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><img src="../images/tutorials/copyfqn/cookie-action-60.png" alt="cookie action"/></p>
     
     <p>Click Next. </p></li>
     
     <li><p>Choose Edit in Category and Edit in Toolbar. </p>
     
     <p>You should now see the following:</p>
     
     <p><img src="../images/tutorials/copyfqn/gui-registration-60.png" alt="gui registration"/></p>
     
     <p>Click Next.</p> </li>
     
     <li>Type <tt>CopyFQNAction</tt> in Class Name
         and <tt>CopyFQN</tt> in Display Name. </li>
         
         <li><p>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><img src="../images/tutorials/copyfqn/icon.png" alt="icon"/></p>
     
     <p>Click Finish.</p>
     
     <p>You should now see the following code in your new
     <tt>CopyFQNAction.java</tt> class:</p>
     
<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.</p></li>
     
     <li><p>Right-click the module and choose Install.</p>
     
         <p>Once the module is installed, you should see a new button in the toolbar. </p></li>
     
          <li><p>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><img src="../images/tutorials/copyfqn/ctx-sensitive-on.png" alt="icon"/></p>
    
          <p>However, if you select a node representing a project,
          the button is disabled, as shown below:</p>
         
          <p><img src="../images/tutorials/copyfqn/ctx-sensitive-off.png" alt="icon"/></p>
         
     </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.</p>
 
 <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>
      
<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>

     <li>Install the module again.</li>
     
     <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><img src="../images/tutorials/copyfqn/message-java-file-60.png" alt="message-java-file-60"/></p>

<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></li>

 </ol>

 <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.</p>
 
 <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>
      
    <p><img src="../images/tutorials/copyfqn/runuserasactiontask-60.png" alt="icon"/></p></li>
         
      <li>Click the lightbulb. Alternatively, put the caret in the line and press Alt-Enter.
       Then let the IDE implement the method.</li>
      
      <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>

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

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

     <li>Install the module again.</li>
     
     <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 that is open in the Java editor, as shown here:</p>
     
     <p><img src="../images/tutorials/copyfqn/message-java-file-open-60.png" alt="message-java-file-open-60"/></p></li>

 </ol>


 <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.</p>
 
 <ol>
     
     <li>Begin by declaring a dependency on the I/O APIs, so
     that we can print our results to the Output window.</li>
     
     <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>   </li>
 
    
<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>
    
    <li><p>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><img src="../images/tutorials/copyfqn/output-window-60.png" alt="message-constructor-60"/></p></li>
  
 <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>
   
      <li>Install the module.</li>
    
    <li><p>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><img src="../images/tutorials/copyfqn/message-constructor-60.png" alt="message-constructor-60"/></p></li>
   
   <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>
    
<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.</li>
    
 </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>


<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. </p>
 
 <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>
      
     <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>

     <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.</p></li>

     <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></li>

 </ol>
 
<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: </p>
  <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>
