<!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>Code Completion Tutorial for the NetBeans Platform</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="gwielenga@netbeans.org"/>
        <meta name="indexed" content="y"/>
        <meta name="description"
              content="A short guide to using the Editor Code Completion API."/>
        <!--     Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Oracle and/or its affiliates. All rights reserved. -->
        <!--     Use is subject to license terms.-->
    </head>
    <body>
        <h1>NetBeans Code Completion Tutorial</h1>

        <p>This tutorial shows you how to implement the <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/overview-summary.html">Editor
                Code Completion API</a>. You will be shown how to implement the API
            in the context of HTML files. When the user invokes the
            code completion feature, a code completion box will appear,
            displaying words that can complete the text typed in the editor. At the 
            end of this tutorial, HTML files will have a code completion
            box as follows:</p>

        <p>The content of the code completion box will come from
            country names retrieved from the JDK's
            <tt>java.util.Locale</tt> package.</p>


        <p><strong class="notes">Note: </strong>This document uses NetBeans IDE 8.0
            and NetBeans Platform 8.0. If you
            are using an earlier version, see <a href="74/nbm-code-completion.html">the previous version
                of this document</a>.</p>

        <p><b>Contents</b></p>

        <p><img src="../images/articles/80/netbeans-stamp.png" class="stamp" width="114" height="114" alt="Content on this page applies to NetBeans IDE 7.2" title="Content on this page applies to NetBeans IDE 7.2"/></p>
        <ul class="toc">
            <li><a href="#intro">Introduction to Code Completion Integration</a></li>
            <li><a href="#creating-the-module-project">Creating the Module Project</a></li>
            <li><a href="#implementing-the-code-completion-provider">Implementing the Completion Provider Class</a>
                <ul>
                    <li><a href="#completiontask">Implementing the createTask Method</a></li>
                    <li><a href="#autoquerytype">Implementing the getAutoQueryTypes Method</a></li>
                </ul></li>
            <li><a href="#implementing-the-code-completion-item">Implementing the Completion Item Class</a>
                <ul>
                    <li><a href="#defining-the-action">Implementing the Action</a></li>
                    <li><a href="#defining-the-filter">Implementing the Filter</a></li>
                    <li><a href="#defining-the-tooltip-documentation">Implementing the Tooltip and Documentation Task</a></li>
                </ul></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 8.0 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 7 or above</td>
                </tr>
            </tbody>
        </table>
        <p class="tips">For troubleshooting purposes, you are welcome to download the <a href="http://java.net/projects/nb-api-samples/sources/api-samples/show/versions/8.0/tutorials/CountryCodeCompleter">completed tutorial source code</a>.</p>

        <h2 class="tutorial"><a name="intro"></a>Introduction to Code Completion Integration</h2>

        <p>Two classes apply to code completion and these will be developed in this tutorial:</p>
        <ul>
            <li><tt><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionItem.html">CompletionItem</a></tt></li>
            <li><tt><a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionProvider.html">CompletionProvider</a></tt></li>
        </ul>

        <p class="tips">Both of these come from the
            <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-completion/overview-summary.html">Editor
                Code Completion API</a> and are implemented in this tutorial's module as
            CountriesCompletionItem and CountriesCompletionProvider.</p>

        <!-- ===================================================================================== -->
        <h2 class="tutorial"><a name="creating"></a>Creating the Module Project</h2>

        <p>In this section, we use a wizard to create the source structure that every NetBeans module requires. The
            source structure consists of certain folders in specific places and a set of files that are
            always needed. For example, every Ant-based NetBeans module requires
            a <tt>nbproject</tt> folder, which holds
            the project's metadata.</p>

        <div class="indent">

            <ol>

                <li>Choose File &gt; New Project (Ctrl-Shift-N). Under Categories, select NetBeans Modules. Under Projects, 
                    select Module. Click Next.</li>
                <li>In the Name and Location panel, type <tt>CountryCodeCompleter</tt> in Project Name.
                    Change the
                    Project Location to any directory on your computer. Click Next.</li>

                <li>In the Basic Module Configuration panel, type <tt>org.netbeans.modules.countries</tt>
                    as the Code Name Base. Click Finish.</li>
            </ol>

        </div>

        <p> The IDE creates the <tt>CountryCodeCompleter</tt>
            project. The project contains all of your sources and
            project metadata, such as the project's Ant build script. The project
            opens in the IDE. You can view its logical structure in the Projects window (Ctrl-1) and its
            file structure in the Files window (Ctrl-2).</p>

        <!-- ===================================================================================== -->
        <h2><a name="implementing-the-code-completion-provider"></a>Implementing the Completion Provider Class</h2>

        <p>The first class we will deal with when creating a code completion feature
            for HTML files is the <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionProvider.html">CompletionProvider</a></tt>.
            As the user types in an editor, the code completion infrastructure asks all code
            completion providers registered in the XML layer file to create <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionTask.html">CompletionTasks</a></tt>.
            The tasks are created by the <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionProvider.html#createTask(int,%20javax.swing.text.JTextComponent)">CompletionProvider.createTask</a></tt>
            method. What <i>happens</i> when the method is invoked is up to the implementation. In <i>our</i>
            implementation, we will create a <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionItem.html">CompletionItem</a></tt>
            for a list of countries.
        </p>

        <div class="indent">

            <ol>
                <li><p>Right-click the LIbraries node of the <tt>CountryCodeCompleter</tt> project and choose Add Module Dependency:</p>
                    <br/>
                    <p><img src="../images/tutorials/cc/72/deps.png" alt="Code completion in text file"/></p>
                    <br/>
                    <p>Set dependencies on the following:</p>

                    <br/>
                    <ul>
                        <li>"Editor Code Completion", which provides the API classes that we need in this tutorial.</li>
                        <li>"MIME Lookup API", which provides the Java annotation for registering
                            completion providers.</li>
                        <li>"Utilities API".</li>
                    </ul>
                </li>
                <li>Right-click the <tt>CountryCodeCompleter</tt> project and choose New &gt; Java Class. In
                    Class Name, type <tt>CountriesCompletionProvider</tt>. In Package, choose <tt>org.netbeans.modules.countries</tt>.
                    Click Finish.</li>
                <li><p>In the <tt>CountriesCompletionProvider</tt> class, change the signature so that
                        the class <tt>implements CompletionProvider</tt>. Place the cursor on the line
                        that defines the signature. A lightbulb appears. Click it and the
                        IDE adds an import statement for <tt>org.netbeans.spi.editor.completion.CompletionProvider</tt>. 
                        The lightbulb appears again. Click it again and the IDE creates
                        skeleton methods for the two methods required by the CompletionProvider class. You should now see this:</p>

                    <pre class="examplecode">package org.netbeans.modules.countries;

import javax.swing.text.JTextComponent;
import org.netbeans.spi.editor.completion.CompletionProvider;
import org.netbeans.spi.editor.completion.CompletionTask;

public class CountriesCompletionProvider implements <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionProvider.html">CompletionProvider</a> {
    
    public CountriesCompletionProvider() {
    }

    @Override
    public <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionTask.html">CompletionTask</a> <a href="http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionProvider.html#createTask(int,%20javax.swing.text.JTextComponent)">createTask(int queryType, JTextComponent jtc)</a> {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionProvider.html#getAutoQueryTypes(javax.swing.text.JTextComponent,%20java.lang.String)">getAutoQueryTypes(JTextComponent component, String typedText)</a> {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
}
                    </pre></li>

                <li>Before coding the 
                    <tt>CompletionProvider</tt> class, let's 
                    register it in the XML layer file,
                    via a NetBeans Platform annotation:

                    <pre class="examplecode">package org.netbeans.modules.countries;

import javax.swing.text.JTextComponent;
<b>import org.netbeans.api.editor.mimelookup.MimeRegistration;</b>
import org.netbeans.spi.editor.completion.CompletionProvider;
import org.netbeans.spi.editor.completion.CompletionTask;

<b>@MimeRegistration(mimeType = "text/html", service = CompletionProvider.class)</b>
public class CountriesCompletionProvider implements CompletionProvider {

    @Override
    public CompletionTask createTask(int queryType, JTextComponent jtc) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getAutoQueryTypes(JTextComponent component, String typedText) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
}</pre>

                    <p class="tips"> Read <a href="http://netbeans.dzone.com/news/mimelocation-mimeregistration">@MimeLocation, @MimeRegistration and @MimeRegistrations added</a> for details
                        on the annotation above.</p>
                </li>
            </ol>

        </div>

        <div class="indent">
            <h3 class="tutorial"><a name="completiontask"></a>Implementing the createTask Method</h3>
            <p>In this section we create a skeleton implementation of
                <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/support/AsyncCompletionTask.html">AsyncCompletionTask</a></tt>.
                In the next sections, we will fill this skeleton method out.</p>

            <div class="indent">

                <ol>       

                    <li>In the createTask method, 
                        below the code from the previous section, add the following lines:

                        <pre class="examplecode">return new AsyncCompletionTask(new AsyncCompletionQuery() {
});</pre>

                        <p>Here, we're returning <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/support/AsyncCompletionTask.html">AsyncCompletionTask</a></tt>,
                            which will allow for the asynchronous creation of our task. The class
                            comes from the <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/support/package-summary.html">org.netbeans.spi.editor.completion.support</a></tt> package, 
                            which provides several useful supporting classes for code completion implementations. We will
                            use several of 
                            them in this tutorial.</p></li>

                    <li>Place the cursor on the line. Click the lightbulb that appears and let
                        the IDE add import statements. Also let it create a skeleton method for the
                        <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/support/AsyncCompletionTask.html#query(org.netbeans.spi.editor.completion.CompletionResultSet)">query</a> method.</li>

                    <li>Next, we need to specify which code completion type we are working with. When
                        the user clicks Ctrl-Space, or an alternative key combination defined by the user,
                        our code completion entries should appear. This is the COMPLETION_QUERY_TYPE. Alternative
                        query types exist, such as DOCUMENTATION_QUERY_TYPE and TOOLTIP_QUERY_TYPE. We need to test
                        whether the user pressed the keys applicable to the COMPLETION_QUERY_TYPE. Therefore add
                        the following test to the start of the <tt>createTask</tt> method:

                        <pre class="examplecode">if (queryType != CompletionProvider.COMPLETION_QUERY_TYPE)
   return null;</pre>

                        <p>At this stage, the <tt>createTask</tt> method should look as follows:</p>

                        <pre class="examplecode">@Override
public CompletionTask createTask(int queryType, JTextComponent jtc) {
    
    if (queryType != CompletionProvider.COMPLETION_QUERY_TYPE)
        return null;
    
    return new AsyncCompletionTask(new AsyncCompletionQuery() {
        protected void query(CompletionResultSet completionResultSet, Document document, int caretOffset) {
        }
    });

}</pre>
                    </li>
                </ol>
            </div>
        </div>
        <div class="indent">
            <h3 class="tutorial"><a name="autoquerytype"></a>Implementing the getAutoQueryTypes Method</h3>
            <p>In this section we return 0 as our <tt>AutoQueryType</tt>, so that
                the code completion box does not appear automatically, but only
                when requested by the user.</p>
            <p>Before filling out the <tt>query</tt> method, let's look at the <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionProvider.html#getAutoQueryTypes(javax.swing.text.JTextComponent,%20java.lang.String)">getAutoQueryTypes(JTextComponent jTextComponent, String string)</a></tt>
                method. This method determines whether the code completion box appears <i>automatically</i>
                or not. For now, let's return 0. This means that the code completion box
                will never appear unless the user explicitly asks for it. So, this method should
                now look as follows:</p>

            <pre class="examplecode">@Override
public int getAutoQueryTypes(JTextComponent component, String string) {
    return 0;
}</pre>      

            <p class="tips">By default, the
                user would press Ctrl-Space to make the code completion box appear. Later, we
                can add a new option to our Options window extension, such as a checkbox which
                will change the int returned in this method from 0 to 1, so that the code completion
                box appears automatically. (There are also other types of queries, as
                shown <a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/constant-values.html#org.netbeans.spi.editor.completion.CompletionProvider.COMPLETION_QUERY_TYPE">here</a>.)
            </p></li>
            </ol>
        </div>
        </div>

        <!-- ===================================================================================== -->
        <h2><a name="implementing-the-code-completion-item"></a>Implementing the Completion Item Class</h2>


        <p>In this section
            we will create a class that implements <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionItem.html">CompletionItem</a></tt>.
            Once we have defined this class, we will fill out the query method in the
            <tt>CompletionProvider</tt> class. The <tt>CompletionProvider</tt> will create instances of
            our <tt>CompletionItem</tt>.</p>
        <div class="indent">
            <ol><li>Right-click the 
                    <tt>CountryCodeCompleter</tt> project and choose New &gt; Java Class.
                    In Class Name, type <tt>CountriesCompletionItem</tt>. In Package, choose 
                    <tt>org.netbeans.modules.countries</tt>. Click Finish.</li>

                <li>We will return to this class in later steps. For now, we 
                    will fill out the query method that we defined in the CompletionProvider class.
                    Fill out the AsyncCompletionTask as follows, and note
                    the explanatory comments in the code:

                    <pre class="examplecode">return new <a href="http://bits.netbeans.org/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/support/AsyncCompletionTask.html">AsyncCompletionTask</a>(new AsyncCompletionQuery() {

    @Override
    protected void query(CompletionResultSet completionResultSet, Document document, int caretOffset) {

        //Iterate through the available locales
        //and assign each country display name
        //to a CompletionResultSet:
        Locale[] locales = Locale.getAvailableLocales();
        for (int i = 0; i < locales.length; i++) {
            final Locale locale = locales[i];
            final String country = locale.getDisplayCountry();
            if (!country.equals("")) {
                completionResultSet.addItem(new CountriesCompletionItem(country, caretOffset));
            }
        }

        completionResultSet.finish();
    }

}, jtc);</pre>

                    <p> A red underline remains, after you let the IDE add various import statements.
                        The error underline tells you that the CompletionItem's constructor does not expect the
                        values that you are passing to it. In the next step, we will fill out the CompletionItem
                        so that it meets the requirements of the CompletionProvider.</p>
                    <p class="tips"> Read <a href="http://blogs.oracle.com/geertjan/entry/java_classes_in_code_completion">Java Classes in Code Completion</a>
                        to learn how to put Java classes in the code completion box, instead of the locales that are used above.</p>          

                </li>

                <li>In the <tt>CountriesCompletionItem</tt> class, change the signature so that
                    the class  <tt>implements CompletionItem</tt>. Let the IDE create import statements and skeleton
                    implementations for
                    the class's required methods.
                    Read the entry in the NetBeans Javadoc for
                    <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionItem.html">CompletionItem</a></tt>
                    to begin to understand what each of the methods is for. For now, we will implement a
                    minimal completion item, just enough to
                    be able to compile the module and see the code completion box.</li>

                <li>In the CountriesCompletionItem class, define the constructor as follows:

                    <pre class="examplecode">private String text;
private static ImageIcon fieldIcon =
        new ImageIcon(ImageUtilities.loadImage("org/netbeans/modules/countries/icon.png"));
private static Color fieldColor = Color.decode("0x0000B2");
private int caretOffset;

public CountriesCompletionItem(String text, int caretOffset) {
    this.text = text;
    this.caretOffset = caretOffset;
}</pre>

                    <p>Note that here we're referencing an icon. This is the icon that will
                        appear next to each entry represented by the CompletionItem in the
                        code completion box. The icon can be any icon with a dimension of 16x16 pixels.
                        For example, you could make use of this icon:</p>

                    <p><img src="../images/tutorials/cc/icon.png" alt="icon"/></p>

                    <p>If you like, you can right-click the image above and save it to the location
                        specified in the ImageIcon definition above.</p></li>

                <li>Next define the <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionItem.html#getPreferredWidth(java.awt.Graphics,%20java.awt.Font)">getPreferredWidth()</a></tt>
                    and <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionItem.html#render(java.awt.Graphics,%20java.awt.Font,%20java.awt.Color,%20java.awt.Color,%20int,%20int,%20boolean)">render()</a></tt>
                    methods as follows:

                    <pre class="examplecode">@Override
public int getPreferredWidth(Graphics graphics, Font font) {
    return CompletionUtilities.getPreferredWidth(text, null, graphics, font);
}

@Override
public void render(Graphics g, Font defaultFont, Color defaultColor,
        Color backgroundColor, int width, int height, boolean selected) {
    CompletionUtilities.renderHtml(fieldIcon, text, null, g, defaultFont,
            (selected ? Color.white : fieldColor), width, height, selected);
}</pre>

                    <p>Define the <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionItem.html#getSortText()">getSortText()</a></tt> method as follows:</p>

                    <pre class="examplecode">@Override
public CharSequence getSortText() {
    return text;
}</pre>

                    <p>Next, define the <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionItem.html#getInsertPrefix()">getInsertPrefix()</a></tt> method:</p>

                    <pre class="examplecode">@Override
public CharSequence getInsertPrefix() {
    return text;
}</pre>

                    <p>Finally, create dummy implementations of the remaining methods. So,
                        return <tt>null</tt> for <tt>createDocumentationTask()</tt> and <tt>createToolTipTask()</tt>. Then return <tt>false</tt> for
                        <tt>instantSubstitution()</tt> and return <tt>0</tt> for <tt>getSortPriority()</tt>. Finally,
                        empty the methods <tt>defaultAction</tt> and <tt>processKeyEvent</tt>.</p></li>

                <li>Right-click the module and choose Run.
                    A new instance of the IDE starts up and installs your module. Open an HTML file in
                    the IDE. Type something and press Ctrl-Space. 
                    You should now see the following:</p>

                    <p><img src="../images/tutorials/cc/72/result-1.png" alt="icon"/></p>

                    <p class="tips"> When you press Enter in the list above, nothing happens. That is because
                        we have not defined the <tt><a href="https://netbeans.org/download/dev/javadoc/org-netbeans-modules-editor-completion/org/netbeans/spi/editor/completion/CompletionItem.html#defaultAction(javax.swing.text.JTextComponent)">defaultAction()</a></tt>
                        method yet. We will do so in the next section. Also note that the list does not narrow while you are typing. That
                        is because we have not created a filter yet. The filter will detect
                        what we are typing and adjust the entries in the list accordingly. We will create
                        a filter in a later section.</p></li>

            </ol>
        </div>

        <div class="indent">
            <h3 class="tutorial"><a name="defining-the-action"></a>Implementing the Action</h3>
            <p>In this section we specify what happens when the user
                presses the Enter key or clicks the mouse over an entry in the 
                code completion box.</p>
            <div class="indent">

                <ol>       

                    <li>Fill out the <tt>defaultAction()</tt> method
                        as follows:

                        <pre class="examplecode">@Override
public void defaultAction(JTextComponent jtc) {
    try {
        StyledDocument doc = (StyledDocument) jtc.getDocument();
        doc.insertString(caretOffset, text, null);
        //This statement will close the code completion box:
        Completion.get().hideAll();
    } catch (BadLocationException ex) {
        Exceptions.printStackTrace(ex);
    }
}</pre>     </li>


                    <li>Install the module again. Notice that when
                        you press Enter or click the mouse over an entry
                        in the code completion box, the selected text is added at the cursor
                        in your HTML file. However, the text that you typed
                        prior to calling up the code completion box is
                        not removed. Below, the "V" should be removed, because "Vietnam"
                        was selected from the code completion box:

                        <p><img src="../images/tutorials/cc/65-result-of-cc2.png" alt="icon"/></p>

                        <p>In the next section, we will add functionality to detect the number of
                            characters that have been typed and remove them when the selected country
                            is inserted into the document.</p></li>

                </ol>

            </div>
        </div>

        <div class="indent">
            <h3 class="tutorial"><a name="defining-the-filter"></a>Implementing the Filter</h3>
            <p>In this section we enable the code completion box
                to narrow while the user is typing. In this way, when the user types
                'hel', only words that begin with those letters are
                shown in the code completion box. The filter is defined
                in the <tt>CountriesCompletionProvider</tt> class.</p>
            <div class="indent">
                <ol>       
                    <li>In the CountriesCompletionProvider class,
                        rewrite the <tt>AsyncCompletionTask()</tt> method by
                        adding the statements highlighted in bold below:

                        <pre class="examplecode">return new AsyncCompletionTask(new AsyncCompletionQuery() {

    @Override
    protected void query(CompletionResultSet completionResultSet, Document document, int caretOffset) {

        <b>String filter = null;
        int startOffset = caretOffset - 1;

        try {
            final StyledDocument bDoc = (StyledDocument) document;
            final int lineStartOffset = getRowFirstNonWhite(bDoc, caretOffset);
            final char[] line = bDoc.getText(lineStartOffset, caretOffset - lineStartOffset).toCharArray();
            final int whiteOffset = indexOfWhite(line);
            filter = new String(line, whiteOffset + 1, line.length - whiteOffset - 1);
            if (whiteOffset > 0) {
                startOffset = lineStartOffset + whiteOffset + 1;
            } else {
                startOffset = lineStartOffset;
            }
        } catch (BadLocationException ex) {
            Exceptions.printStackTrace(ex);
        }</b>

        //Iterate through the available locales
        //and assign each country display name
        //to a CompletionResultSet:
        Locale[] locales = Locale.getAvailableLocales();
        for (int i = 0; i < locales.length; i++) {
            final Locale locale = locales[i];
            final String country = locale.getDisplayCountry();
            <b>//Here we test whether the country starts with the filter defined above:</b>
            if (!country.equals("") <b>&& country.startsWith(filter)</b>) {
                <b>//Here we include the start offset, so that we'll be able to figure out
                //the number of characters that we'll need to remove:</b>
                completionResultSet.addItem(new CountriesCompletionItem(country, <b>startOffset,</b> caretOffset));
            }
        }
        completionResultSet.finish();

    }

}, jtc);</pre>  </li>

                    <li>Right at the end of the CountriesCompletionProvider, add the
                        following two methods:

                        <pre class="examplecode">static int getRowFirstNonWhite(StyledDocument doc, int offset)
throws BadLocationException {
    Element lineElement = doc.getParagraphElement(offset);
    int start = lineElement.getStartOffset();
    while (start + 1 < lineElement.getEndOffset()) {
        try {
            if (doc.getText(start, 1).charAt(0) != ' ') {
                break;
            }
        } catch (BadLocationException ex) {
            throw (BadLocationException)new BadLocationException(
                    "calling getText(" + start + ", " + (start + 1) +
                    ") on doc of length: " + doc.getLength(), start
                    ).initCause(ex);
        }
        start++;
    }
    return start;
}</pre>                           

                        <pre class="examplecode">static int indexOfWhite(char[] line){
    int i = line.length;
    while(--i > -1){
        final char c = line[i];
        if(Character.isWhitespace(c)){
            return i;
        }
    }
    return -1;
}
                        </pre>     </li>

                    <li>Change the constructor of the <tt>CountriesCompletionItem</tt> to receive the start offset.
                        Then change the <tt>defaultAction</tt> so that the start offset will be used in
                        determining the characters that will be removed when the selected country is inserted.
                        Below, the statements highlighted in bold are those that should be added:

                        <pre class="examplecode"><b>private int dotOffset;</b>

public CountriesCompletionItem(String text, <b>int dotOffset,</b> int caretOffset) {
    this.text = text;
    <b>this.dotOffset = dotOffset;</b>
    this.caretOffset = caretOffset;
}

@Override
public void defaultAction(JTextComponent component) {
    try {
        StyledDocument doc = (StyledDocument) component.getDocument();
        //Here we remove the characters starting at the start offset
        //and ending at the point where the caret is currently found:
        doc.remove(dotOffset, caretOffset-dotOffset);
        doc.insertString(dotOffset, text, null);
        Completion.get().hideAll();
    } catch (BadLocationException ex) {
        Exceptions.printStackTrace(ex);
    }
}
    
...
...
...</pre></li>

                    <li>Install the module again and notice that this time the list of
                        words narrows while you are typing...

                        <p><img src="../images/tutorials/cc/65-result-of-cc.png" alt="Code completion in text file"/></p>

                        <p>...and that when you press Enter, the characters that you typed are removed and replaced by
                            the country selected from the code completion box.</p></li>

                </ol>
            </div>
        </div>

        <div class="indent">
            <h3 class="tutorial"><a name="defining-the-tooltip-documentation"></a>Implementing the Tooltip and Documentation Task</h3>

            <p>Some optional features can also be added, as described below.</p>
            <div class="indent">

                <ol>

                    <li>Optionally, you can implement the <tt>createToolTipTask</tt> method in the <tt>CountriesCompletionItem</tt>, with
                        this result when Ctrl-P is pressed:

                        <p><img src="../images/tutorials/cc/65-result-of-cc3.png" alt="Code completion in text file"/></p>

                        <p>Here is the code that will achieve the result shown in the screenshot above:</p>

                        <pre class="examplecode">@Override
public CompletionTask createToolTipTask() {
    return new AsyncCompletionTask(new AsyncCompletionQuery() {
        @Override
        protected void query(CompletionResultSet completionResultSet, Document document, int i) {
            JToolTip toolTip = new JToolTip();
            toolTip.setTipText("Press Enter to insert \"" + text + "\"");
            completionResultSet.setToolTip(toolTip);
            completionResultSet.finish();
        }
    });
}</pre>                       
                    </li>

                    <li>Optionally, you can provide documentation for the entries in the code completion box:

                        <p><img src="../images/tutorials/cc/65-result-of-cc4.png" alt="Code completion in text file"/></p>

                        <p>Make use of the documentation box like this, by implementing the <tt>createDocumentationTask</tt> method
                            in the <tt>CountriesCompletionItem</tt> class:</p>

                        <pre class="examplecode">@Override
public CompletionTask createDocumentationTask() {
    return new AsyncCompletionTask(new AsyncCompletionQuery() {
        @Override
        protected void query(CompletionResultSet completionResultSet, Document document, int i) {
            completionResultSet.setDocumentation(new CountriesCompletionDocumentation(CountriesCompletionItem.this));
            completionResultSet.finish();
        }
    });
}</pre>

                        <p>In the code above, the reference to the CountriesCompletionDocumentation class could be implemented as follows:</p>

                        <pre class="examplecode">public class CountriesCompletionDocumentation implements CompletionDocumentation {

    private CountriesCompletionItem item;

    public CountriesCompletionDocumentation(CountriesCompletionItem item) {
        this.item = item;
    }

    @Override
    public String getText() {
        return "Information about " + item.text;
    }

    @Override
    public URL getURL() {
        return null;
    }

    @Override
    public CompletionDocumentation resolveLink(String string) {
        return null;
    }

    @Override
    public Action getGotoSourceAction() {
        return null;
    }

}</pre>

                        <p>By implementing the <tt>getURL()</tt> in the code above, you can enable
                            the URL button, as shown below:</p>

                        <p><img src="../images/tutorials/cc/65-result-of-cc5.png" alt="Code completion in text file"/></p>

                        <p>When the user clicks the URL button, the browser set in the IDE will open, displaying
                            the content provided by the specified URL.</p>
                    </li>
                </ol>

            </div>
        </div>

        <p>Congratulations, you have now completed a simple implementation of a code completion
            integration module.</p>
      <br>
        <div class="feedback-box"><a name="feedback"></a>
            <a href="https://netbeans.org/about/contact_form.html?to=3&amp;subject=Feedback:%20NetBeans%20Code%20Completion%20Tutorial%208.0">
                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 plugins, see the following resources: 
        <ul>
            <li><a href="https://netbeans.org/kb/trails/platform.html">NetBeans Platform Learning Trail</a></li>
            <li><a href="http://bits.netbeans.org/dev/javadoc/">NetBeans API Javadoc</a></li>
        </ul>

        <!-- ======================================================================================== -->


    </body>
</html>
