There’s a few Java libraries for creating terminal and ncurses like applications. They abstract away the ANSI escape codes and low level control like tput. I’ve briefly looked at three of them: Lanterna, Charva and JCurses. They all come with basic terminal control, and some widgets and window managing to create terminal based GUI applications.

JCurses seems to be the oldest, and possibly unmaintained. It requires ncurses to be installed, and also a native library. It is available through the Maven Central repository, however, make sure to set up the path for access to the libjcurses.so (in the tar-ball from SourceForge, or within the .jar from Maven). Documentation is sparse, but it seems it’s possible to interface with the terminal with little code.

Charva is also ncurses based and requires a native lib. One of it’s selling points is that it can act as a drop-in replacement for java.awt UIs. It seems unlikely that that will work well for all but the simplest UIs, however, at least it offers an easy transition path.

Finally, Lanterna seems to be the best maintained, and clearly documented project of the three. It is unique in that is handles all terminal details itself, and does not require external libraries. It is compatible with Linux, Windows, Cygwin, OS X terminals. Furthermore, if launched from an X or similar GUI based environment instead of a terminal, it will create its own GUI window into which it will render the terminal. Neat.

The drawback with Lanterna is its rather verbose and involved API. For “serious” apps, maybe that’s OK, but for simple positioning of the cursor, it can get a bit too much. The follow renders a text label with a border:

  public void testWindow() throws IOException, InterruptedException {
    Terminal terminal = new DefaultTerminalFactory().createTerminal();
    Screen screen = new TerminalScreen(terminal);
    screen.startScreen();

    Label label = new Label("test");

    BasicWindow window = new BasicWindow();
    window.setComponent(label);

    MultiWindowTextGUI gui = new MultiWindowTextGUI(screen, new DefaultWindowManager(),
        new EmptySpace(TextColor.ANSI.BLACK));
    gui.setTheme(LanternaThemes.getRegisteredTheme("businessmachine"));
    gui.addWindowAndWait(window);
  }

Lanterna is available through Maven Central, so the following gradle.build lines will do.

repositories {
  mavenCentral()
}

dependencies {
  compile 'com.googlecode.lanterna:lanterna:3.0.0-beta3'
}

Here’s the full test example, including a main-method to easily run it stand-alone from the terminal.

LanternaCliTest.java
GitHub Raw
/* Copyright rememberjava.com. Licensed under GPL 3. See http://rememberjava.com/license */
package com.rememberjava.ui;

import java.io.IOException;

import org.junit.Test;

import com.googlecode.lanterna.TextColor;
import com.googlecode.lanterna.bundle.LanternaThemes;
import com.googlecode.lanterna.gui2.BasicWindow;
import com.googlecode.lanterna.gui2.DefaultWindowManager;
import com.googlecode.lanterna.gui2.EmptySpace;
import com.googlecode.lanterna.gui2.Label;
import com.googlecode.lanterna.gui2.MultiWindowTextGUI;
import com.googlecode.lanterna.screen.Screen;
import com.googlecode.lanterna.screen.TerminalScreen;
import com.googlecode.lanterna.terminal.DefaultTerminalFactory;
import com.googlecode.lanterna.terminal.Terminal;

public class LanternaCliTest {

  public static void main(String[] args) throws Exception {
    new LanternaCliTest().testWindow();
  }

  @Test
  public void testWindow() throws IOException, InterruptedException {
    Terminal terminal = new DefaultTerminalFactory().createTerminal();
    Screen screen = new TerminalScreen(terminal);
    screen.startScreen();

    Label label = new Label("test");

    BasicWindow window = new BasicWindow();
    window.setComponent(label);

    MultiWindowTextGUI gui = new MultiWindowTextGUI(screen, new DefaultWindowManager(),
        new EmptySpace(TextColor.ANSI.BLACK));
    gui.setTheme(LanternaThemes.getRegisteredTheme("businessmachine"));
    gui.addWindowAndWait(window);
  }
}