java来做CLI

使用java来做CLI的话,就要用java来接管terminal,来处理用户的输入和将结果显示给用户,还有可能要去的terminal的宽度和高度

等属性,但是这些在java里坐起来都是力不从心的,那该怎么办了?

只能使用java来调用系统的命令来控制terminal了,有一个现成的jar可以支持java来控制terminal,那就是jline,参考网址是:

http://jline.sourceforge.net/

使用它可以实现命令补全等功能,只要实现Completor类中的complete方法就行了;

将Escape Sequences print到terminal,可以控制terminal的行为;

(Escape Sequences有很多 标准,而且每个terminal emulator实现的方式都不一样,所以要使用的话,

必须在自己所有使用到的terminal emulator进行测试; 比方说putty支持DECTCEM 的实现在Terminal.c中的L2378
)

下面是实现Completro的具体例子:

//buf使用户输入的字符串;

//cursor是光标所处的位置;

//candidates是需要在当前状态下,用户按tab可以候选的值,所放入的列表;

public int complete(final String buf, final int cursor, final List candidates)
{
int length = 0;
String target = null;
int tgtpos = 0;

// Get current buffer to complete
String buffer = (buf == null) ? “” : buf.substring(0, cursor);
// Remove the first blank string
while (buffer.startsWith(this.delimit))
{
buffer = buffer.substring(this.delimit.length());
}

//add your candidate to list

// the index of the completion is always from the beginning of the buffer.
return (candidates.size() == 0) ? (-1) : cursor - tgtpos);
}

下面是实现控制terminal的具体例子(忽略了异常处理):

/**

  • Use escape sequences to control Terminal emulator
  • @param code
    */
    public static void esc(String code)
    {

jlineReader.printString(((char) 27) + code);
jlineReader.flushConsole();
}

/**

  • Move cursor position to home (1,1)
    */
    public static void moveCursorHome()
    {
    esc(“[1;1f”);
    }

/**

  • Move cursor position to footer (height,1)
    */
    public static void moveCursorFooter()
    {
    int height = jlineReader.getTermheight();
    esc(“[“ + height + “;1f”);
    }

/**

  • Erases the current line
    */
    public static void eraseLine()
    {
    esc(“[2K”);
    }

/**

  • Hides the cursor
    */
    public static void hideCursor()
    {
    esc(“[?25l”);
    }

/**

  • Shows the cursor
    */
    public static void showCursor()
    {
    esc(“[?25h”);
    }

/**

  • Shows the cursor
    */
    public static void resetTerminal()
    {
    esc(“c”);
    }

/**

*这个方法是相当于翻页;相当于linux中的clear命令

*/

public static void clearScreen()
{

jlineReader.clearScreen();
}

/**

*这个方法是将当前页页,清空,同时将光标移动到当前页的开始位置;注意它和clearScreen不同;

*/

public static void redrawScreen()
{
int width = jlineReader.getTermwidth();
int height = jlineReader.getTermheight();

int count = width * height;
char[] bufs = new char[count];
Arrays.fill(bufs, ‘ ‘);
try
{
jlineReader.printString(new String(bufs));
jlineReader.flushConsole();
}
catch (IOException ex)
{
logger.error(ex);
}
moveCursorHome();
}