ScriptingNetBeans

Contents


Scripting NetBeans In JavaScript

Disclaimer: this is purely an experiment, it is not a recommended and supported way of doing things at this point.

The current JavaScript support allow to extend NetBeans with code written in JavaScript. You can write and run JavaScript in NetBeans which makes it very easy to prototype and test the code live without any need to compile and start new instance of NetBeans. Just create an empty JavaScript file and use Run action in its popup menu to execute it. It runs in the context of NetBeans so you can actually do things to your IDE using NetBeans APIs (but be careful you can easily do damage to your IDE, too!!).

Simple examples

First a few examples - not really useful, just to demonstrate what you can do. Note that you will need JDK 6 to make JavaScript execution work.

Of course you can just script swing like this:

importPackage (javax.swing);
f = new JFrame();
f.add(new JButton("Hello"));
f.pack();
f.show();

You can call NetBeans API:

importClass(org.openide.awt.StatusDisplayer);
StatusDisplayer.getDefault().statusText = "Ahoj";

(Note that statusText is treated here as a bean property. default is a keyword in JavaScript so it cannot be used in this way.)

Like NetBeans windows API, just open a file:

obj = {
  run: function () {
    jfc = new Packages.javax.swing.JFileChooser();
    jfc.showOpenDialog(Packages.org.openide.windows.WindowManager.getDefault().mainWindow);
    fo = Packages.org.openide.filesystems.FileUtil.fromFile(jfc.selectedFile)[0];
    dataObject = Packages.org.openide.loaders.DataObject.find(fo);
    open = dataObject.lookup.lookup(Packages.org.openide.cookies.OpenCookie);
    open.open();
  }
}
Packages.javax.swing.SwingUtilities.invokeLater(new java.lang.Runnable(obj)); 

Groovier APIs

Compared to Java it is not only easier to test but there is also a bit less code to write - no type casting, no need to catch exceptions (wild, dangerous but this is scripting). But there is still a lot code to type just to open a file. It is possible to wrap some of the NetBeans APIs for the most common use cases into helper classes, like this:

public class Window {

    private TopComponent tc;

    Window(TopComponent tc) {
        this.tc = tc;
    }

    public Window(String title) {
        tc = new TopComponent();
        tc.setDisplayName(title);
    }
    
    public Window dock(String modeName) {
        Mode output = WindowManager.getDefault().findMode(modeName);
        output.dockInto(tc);
        return this;
    }
    
    public static Frame mainWindow() {
        return WindowManager.getDefault().getMainWindow();
    }
    
    public static String[] getDockingPlaces() {
       ...
    }

    public static void openFile(String name) {
       ...
    }
    etc.
}

(full source here)

Then the same JavaScript code could be written as:

importPackage(javax.swing);
jfc = new JFileChooser();
jfc.showOpenDialog(Window.mainWindow());
Window.openFile(jfc.selectedFile.path);

Implementing Actions

When you write a piece of useful code and test it with Run action the next question you will probably ask is how to plug the code into NetBeans. The code can of course be called via ScriptEngine.eval(), the plumbing needs to be done in Java. But is conceivable to create the plumbing generically so that an entire module could then be written in JavaScript.

An example shown here is a ScriptAction_ScriptingNetBeans.java utility class which can be placed in one module. Then another module uses this utility and implements the logic in JavaScript, this module contains only 3 files: open.js, layer.xml and Bundle.properties. Register an action into layer.xml using the ScriptAction utility class and parametrize it with script name and language, put a link to the script into layer (here in MyActions/open.js) then implement the logic in open.js file. ScriptAction will delegate the logic to open.js. There is a lot more work to make it really production quality, this is just a hint how it could be done.

layer.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
<filesystem>
    <folder name="Actions">
        <folder name="Tools">
            <file name="openWindow.instance">
                <attr name="instanceCreate" methodvalue="org.netbeans.platform.action.ScriptAction.createAction"/>
                <attr name="script" stringvalue="MyActions/open.js"/>
                <attr name="language" stringvalue="text/javascript"/>
            </file>
        </folder>
    </folder>
    <folder name="Menu">
        <folder name="Window">
            <file name="openWindow.shadow">
                <attr name="originalFile" stringvalue="Actions/Tools/openWindow.instance"/>
            </file>
        </folder>
    </folder>
    <folder name="MyActions">
        <file name="open.js" url="open.js">
            <attr name="SystemFileSystem.localizingBundle" stringvalue="org.yourorghere.scriptedmodule.Bundle"/>
        </file>
    </folder>
</filesystem>

open.js

importPackage(org.netbeans.platform);
importPackage(javax.swing);

jfc = new JFileChooser();
jfc.showOpenDialog(Window.mainWindow());

Window.openFile(jfc.selectedFile.path);

Bundle.properties

OpenIDE-Module-Name=Pavel's First JS Module 
MyActions/open=Open file

Scripting from an external shell

See http://blogs.sun.com/jglick/entry/jrunscript_in_a_target_vm for an idea how to interact with a NetBeans process using an external shell. Can work even if the NetBeans process is deadlocked, etc.

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo