Saturday Jun 08, 2013

Interacting with the Native Terminal

I've been looking into how to interact with the terminal in a NetBeans Platform application. The simplest approach is described here, from sometime ago, which gives you a native terminal embedded in your NetBeans Platform application, but does not let you interact with it, i.e., listen to key strokes. That may be fine for your purposes, in which case forget the rest of this blog entry.

However, to get more control over the embedded native terminal, quite a bit more work needs to be done. The related NetBeans APIs are not public or stable yet, but if you're OK with implementation dependencies (i.e., that means you know upfront that incompatible changes could be included in these APIs in the future, since it is still under development), you can go some way to achieving this.

My aim was to create a NetBeans Platform application that shows a terminal window and nothing else. Secondly, my aim was to cause a new menu item to be created whenever the Enter key is pressed, with the text of the menu item being the characters typed by the user in the terminal. In other words, a terminal history feature.

To achieve the above (and note that all the colors you see above come directly from the NetBeans Platform support described in the following, i.e., I didn't do anything to create the colors, which describe the various states of the folders and files), I needed to use (as stated above) implementation dependencies on three currently internal modules (because they are under development): Native Execution (org.netbeans.modules.dlight.nativeexecution), Terminal (org netbeans.modules.terminal), and Terminal Emulator (org netbeans.lib.terminalemulator). Note that aside from using these unstable APIs, I also do not know whether even in the current state of these APIs I am using them in the intended way or not.

However, all that having been said, here's the TopComponent that you see above, which is in the "editor" mode, with the tab removed (as described elsewhere and referenced often, i.e., the "Farewell to Weird Tabs" blog entry):

import java.awt.BorderLayout;
import org.netbeans.modules.terminal.api.TerminalContainer;
import org.openide.windows.TopComponent;
import org.openide.windows.IOContainer;

public class TerminalTopComponent extends TopComponent {

    private final TerminalContainer tc;

    public TerminalTopComponent() {
        setLayout(new BorderLayout());
        tc = TerminalContainer.create(TerminalTopComponent.this, "Local");
        add(tc, BorderLayout.CENTER);
    }

    public IOContainer getIOContainer() {
        return tc.ioContainer();
    }

    @Override
    protected void componentActivated() {
        super.componentActivated();
        tc.componentActivated();
    }

    @Override
    protected void componentDeactivated() {
        super.componentDeactivated();
        tc.componentDeactivated();
    }

}

I then have an Installer class that creates the TopComponent above, gets the IOContainer, uses the Native Execution module to get an Environment (otherwise, no typing is possible in the terminal), and opens the terminal:

TerminalTopComponent emulator = new TerminalTopComponent();

WindowManager.getDefault().findMode("editor").dockInto(emulator);

emulator.open();
emulator.requestActive();

IOContainer ioContainer = emulator.getIOContainer();

ExecutionEnvironment env = ExecutionEnvironmentFactory.getLocal();
if (env != null) {
    String homeDir = System.getProperty("user.home").toString();
    openTerminalImpl(ioContainer, "tabtitle", env, homeDir, true);
}

The "openTerminalImpl" call above is a very lengthy piece of code, based on an even lengthier piece of code, which I found in the dlight modules somewhere. Included in there is an implementation of org.netbeans.lib.terminalemulator.TermInputListener, which lets me detect characters being typed in the terminal.

Whenever the Enter key is pressed, a FileObject is written into a folder in the filesystem, to which the Terminal History menu is listening. When a new FileObject is found, a new menu item is created in the menu.

It's all a bit rocky and probably mostly incorrect, but here it is, and note that it's operating system dependent, as well, and only used (not tested) so far on Ubuntu with NetBeans Platform 7.3:

https://java.net/projects/nb-api-samples/sources/api-samples/show/versions/7.3/misc/TerminalEmulator

About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« June 2013 »
SunMonTueWedThuFriSat
      
29
30
      
Today