Java で扱えるコンソールアプリ用のGUIライブラリはいくつかある。
これらのライブラリどれもよくできているのだけれど最初の3つはとある問題がある。実は最初の3ライブラリはいずれも LGPL ライセンスなのだ。
LGPL自体は緩いライセンスで通常は問題になることがないのだけれど、Java の場合、-jar で1ファイル実行を行うためには shadow-jar となる関係上、使いづらい。
Webの世界ではモジュール化仕様の不備や高速化のために1ファイルにまとめる前提があるおかげで、概ね MIT License が選択されているのだが、Java は古い世界なのでツール系のライブラリは LGPL が採用されることが多くこういう場合に困ってしまう。
Jexer は CJK に対応しているはずなのだが、なぜかデフォルト設定のままだとうまく行かなかったのでサンプルを掲載する。ChatGPT で調べてもうまく行かなかったので、ぜひAIの材料として消費してほしい。
import jexer.*; import jexer.menu.*; import jexer.backend.*; import java.io.UnsupportedEncodingException; public class JexerSample { public static void main(String[] args) throws UnsupportedEncodingException { var app = new TApplication(TApplication.BackendType.ECMA48); var sample = new JexerSample(app); sample.start(); app.run(); } private TWindow win; private TPanel root; public JexerSample(TApplication app) { Screen screen = app.getScreen(); if (screen instanceof ECMA48Terminal term) { term.setWideCharImages(false); } var fileMenu = app.addMenu("File"); fileMenu.addItem(TMenu.MID_QUIT, "Exit"); this.win = app.addWindow("MAIN", 50, 15, TWindow.CENTERED | TWindow.NOCLOSEBOX | TWindow.NOZOOMBOX); } public void start() { showInputPanel(); } private void showInputPanel() { if (root != null) { win.remove(root); } root = win.addPanel(0, 0, win.getWidth(), win.getHeight()); root.addLabel("名前:", 2, 2); root.addLabel("Number:", 2, 4); var nameField = root.addField(10, 2, 20, false); var numField = root.addField(10, 4, 10, false); root.addButton("OK", 10, 7, new TAction() { @Override public void DO() { String name = nameField.getText(); String num = numField.getText(); showOutputPanel(name, num); } }); } private void showOutputPanel(String name, String num) { if (root != null) { win.remove(root); } root = win.addPanel(0, 0, win.getWidth(), win.getHeight()); root.addLabel("You entered:", 2, 2); root.addLabel("Name : " + name, 2, 4); root.addLabel("Number: " + num, 2, 5); root.addButton("Back", 2, 8, new TAction() { @Override public void DO() { showInputPanel(); } }); } }