2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Javaでコンソールでのキー入力を1文字ずつハンドルしたいときにJLineを使う

Posted at

概要

このエントリでは、Javaでコンソール入出力で動作するプログラムを書くときに、1文字ずつ入力をハンドリングしたい場合の方法について扱います。

背景

Javaでは、標準入出力を扱うStreamがありますが、1文字ずつ入力を「読み込む」ことはできますが、キー入力のイベントを直接ハンドルすることはできません。

このため、例えば「電卓」プログラムを作るときに「+」を押したらすぐに何かの処理を行う、といったことは標準のライブラリだけでは実現できません。

JLineを使う

JLineとは

JLine3は、CUIアプリケーションを開発するときに使えるライブラリです。いくつかの有名どころのOSSでも利用されています。

JLine3は、Windows環境などでのプラットフォーム独自のターミナルの制御にも対応します。ここではプラットフォームネイティブのライブラリが必要となるため、JNAもしくはJANSIを使用する方式が提供されています。このエントリでは、JNAを使用しています。

コードサンプル

下記のコードを使うと、1文字ずつターミナルから入力し、即時に標準出力に表示しています。

package com.hrkt.commandlinecalculator;

import lombok.extern.slf4j.Slf4j;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
@Slf4j
public class CommandlineInterface {
    public void run(String... args) {
        log.info("hello");

        try(Terminal terminal = TerminalBuilder.terminal()) {
            int ch = 0;
            while ((ch = terminal.reader().read()) != 0x09){
                // TAB(0x09)で抜ける
                char c = (char)ch;
                System.out.println(String.format("%d, %c", ch, ch));
            }
        } catch(IOException e) {
            log.error(e.getMessage(), e);
        }
    }
}

下図のような動きとなります。

char-by-char.png

おわりに

このエントリでは、Javaでコンソールからのキー入力をハンドルする方法について紹介しました。
JLine2を利用した記事も見かけますが、開発が終わっているものであり、JLine3を使うことが推奨されています。

コードのサンプル

動作するサンプルは、下記に置いてあります。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?