X

Geertjan's Blog

  • October 12, 2012

JEditorPane Code Completion (Part 2)

Geertjan Wielenga
Product Manager

Figured it out! No need to create a fake Java file, unlike what I said in part 1, no need to depend on all the Java Editor modules, if you use DialogBinding.bindComponentToDocument, instead of DialogBinding.bindComponentToFile:

public final class CountryEditorTopComponent extends TopComponent {
    public CountryEditorTopComponent() {
        initComponents();
        setName(Bundle.CTL_CountryEditorTopComponent());
        setToolTipText(Bundle.HINT_CountryEditorTopComponent());
        EditorKit kit = CloneableEditorSupport.getEditorKit("text/plain");
        jEditorPane1.setEditorKit(kit);
        DialogBinding.bindComponentToDocument(jEditorPane1.getDocument(), 0, 0, jEditorPane1);
        jEditorPane1.setText("Egypt");
    }

The above requires a dependency on Editor Library 2, which is where DialogBinding is found. Aside from that, you need all the dependencies required by the Code Completion API, as described in the Code Completion tutorial on the NetBeans Platform Learning Trail.

Once you've done that, go to the Project Properties dialog of the application and then in the "ide" cluster, include "Plain Editor" and "Plain Editor Library". I.e., two additional JARs only. These two are needed because you've set the MIME type to "text/plain", which is needed because DialogBinding expects the JEditorPane to have a MIME type.

And now everything works. Press Ctrl-Space in your JEditorPane and, because your CompletionProvider is registered in "text/x-dialog-binding" (via the annotation on CompletionProvider), your completion items are displayed. (The only MIME type for binding a document to a component, by default, is "text/x-dialog-binding", which means the next step is for someone to figure out how to support multiple different of such MIME types, since each JEditorPane in your application is likely to require its own specific code completion support.)

I think this is a really workable solution for real scenarios where JEditorPanes in NetBeans Platform applications require code completion.

Update. Part 3 shows how to register multiple CompletionProviders in text/x-dialog-binding, while ensuring that only the appropriate items appear in the code completion.

Join the discussion

Comments ( 4 )
  • pramoth Friday, October 12, 2012

    Great blog. I was never easy with autocomplete in Swing. This blog help me alot.

    Thank.


  • Steven Yi Tuesday, November 20, 2012

    I've figured out how to do this per mime-type. You can get rid of using DialogBinding altogether and just use something like:

    jEditorPane1.setContentType("text/x-csound-orc");

    EditorKit kit = CloneableEditorSupport.getEditorKit("text/x-csound-orc");

    jEditorPane1.setEditorKit(kit);

    jEditorPane1.getDocument().putProperty("mimeType", "text/x-csound-orc");

    I don't know for sure, but it seem like that getDocument().putProperty() is all that is needed. (I sort of guessed at this from looking at the source code to DocumentBinding). I'm using this in my test CompletionProvider:

    @MimeRegistration(mimeType = "text/x-csound-orc", service = CompletionProvider.class)

    and the completion popup is showing up as desired.


  • Steven Yi Wednesday, November 21, 2012

    One other note, I did the above after adding a DataObject using the New Filetype wizard. That generated a DataObject that used annotations, but I did the rest of the plumbing using layer.xml:

    <?xml version="1.0" encoding="UTF-8"?>

    <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">

    <filesystem>

    <folder name="Editors">

    <folder name="text">

    <folder name="x-csound-orc">

    <attr name="SystemFileSystem.localizingBundle" stringvalue="com.kunstmusik.syntax.Bundle"/>

    <!-- <file name="language.instance">

    <attr name="instanceCreate" methodvalue="com.sqlraider.editor.lexer.SqlTokenId.getLanguage"/>

    <attr name="instanceOf" stringvalue="org.netbeans.api.lexer.Language"/>

    </file>-->

    <file name="EditorKit.instance">

    <attr name="instanceClass" stringvalue="org.netbeans.modules.editor.plain.PlainKit"/>

    <attr name="instanceOf" stringvalue="javax.swing.text.EditorKit,org.netbeans.modules.editor.plain.PlainKit"/>

    <attr name="beaninfo" boolvalue="false"/>

    </file>

    <folder name="TokenListProvider">

    <file name="org-netbeans-modules-spellchecker-plain-PlainTokenListProvider.instance" />

    </folder>

    <folder name="FontsColors">

    <folder name="NetBeans">

    <folder name="Defaults">

    <file name="FontAndColors.xml" url="FontAndColors.xml">

    <attr name="SystemFileSystem.localizingBundle" stringvalue="com.kunstmusik.syntax.Bundle"/>

    </file>

    </folder>

    </folder>

    </folder>

    </folder>

    </folder>

    </folder>

    </filesystem>


  • Steven Yi Wednesday, November 21, 2012

    One other note, I did the above after adding a DataObject using the New Filetype wizard. That generated a DataObject that used annotations, but I did the rest of the plumbing using layer.xml. (I can't seem to post that XML here due to Spam checker). Essentially, under Editors/text/x-csound-orc, I added an EditorKit.instance pointing to PlainKit, a TokenListProvider pointing to PlainTokenListProvider, and a FontsColors pointing to a simple FontAndColors.xml. Having the plainkit registered to the text/x-csound-orc type allowed me to grab it using CloneableEditSupport, and having that mime-type makes it possible to target it for adding a CompletionProvider.


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.