Java Basic GUI作成 〜コマンド画面 フォーカス移動させる修正を行う〜

イントロダクション

前回は、コマンド画面の入力チェック部分を作成しました。
今回は、入力チェックに引っかかった場合の処理を実装します。

設計

入力チェックに引っかかった場合、何も実装していないと
カーソルは移動してしまうので、それを動かないように修正します。
・入力した時点でのカーソルの位置を取得する
・入力したキーが入力禁止の場合にカーソルの位置を戻す
※上下のボタンを押下した時に移動しないようにする

実装しているコードはGitからダウンロードできます

しかし、中途半端になっているのが現状です。動きとしては下のような感じで動きます。

前回のソースコード

public class CmdView extends Application {
    /** 画面の横サイズ */
    private static final int VIEW_WIDTH = 300;
    /** 画面のたてサイズ */
    private static final int VIEW_HEIGHT = 300;
    /** コマンドの入力開始文字 */
    private static final String CMD_START = "Cmd $ ";
    /** 改行コード */
    private static final String LINE_SEPARETOR = System.getProperty("line.separator");

    @Override
    public void start(Stage primary) {
        TextArea area = createTextArea();
        Group root = new Group();
        root.getChildren().add(area);
        Scene scene = new Scene(root, VIEW_WIDTH, VIEW_HEIGHT);
        primary.setScene(scene);
        primary.show();
    }

    /**
     * TextAreaを作成して返却する
     * @return TextArea
     */
    private TextArea createTextArea() {
        TextArea area = new TextArea();
        // 縦横の幅を設定する
        area.setPrefWidth(VIEW_WIDTH);
        area.setPrefHeight(VIEW_HEIGHT);
        area.setOnKeyPressed(createKeyPressEvent());
        // 初期表示文字を設定する
        area.setText("Hello user please input command!" + LINE_SEPARETOR + CMD_START);
        // テキストエリアの文字列数
        int textLen = area.getText().length();
        area.positionCaret(textLen);

        return area;
    }

    private EventHandler<KeyEvent> createKeyPressEvent() {
        return new EventHandler<KeyEvent>() {
            public void handle(KeyEvent evt) {
                // 入力を無効にする
                if (isDisabledInput(evt)) {
                    System.out.println("*** isDisable ***");

                    return;
                }
                if (KeyCode.ENTER.equals(evt.getCode())) {
                    // Enter キーを謳歌した時の処理、テキストエリアを取得する
                    TextArea src = (TextArea) evt.getSource();
                    // テキストエリア内の文字列を全て取得
                    String allText = src.getText();
                    // "Cmd $ "の文字列の位置を取得
                    int startPoint = allText.indexOf(CMD_START);

                }
                // チェック用のコンソール出力処理
                System.out.println("EventType: " + evt.getCode());
                System.out.println("Input: " + evt.getCharacter());
            }
        };
    }

    /**
     * キーボードより入力したキーで受け付けないものを<BR/>
     * 判定する
     * @param evt
     * @return true: 受け付けない入力  /  false: 受け付ける入力
     */
    private boolean isDisabledInput(KeyEvent evt) {
        boolean isDisable = false;
        // 入力許可キーのKeyCodeリスト
        List<KeyCode> acList = createAcceptList();

        // チェック処理: 入力禁止するキーの有無をチェック
        return acList.contains(evt.getCode());
    }
    /**
     * プロパティファイル、キーを指定して対象のプロパティを<BR/>
     * 取得する
     *
     * @param propNane プロパティファイル名
     * @param key プロパティのキー
     * @return プロパティの値
     */
    @Depulicated // 使用しないメソッド
    private String getTargetProperty(String propNane, String key) {
        String propStr = null;
        return propStr;
    }

    /**
     * チェック用のリストを作成して返却します<BR/>
     * 入力禁止のKeyCodeを追加
     * @return チェック用のリスト

 続きを読む Java Basic GUI作成 〜コマンド画面 フォーカス移動させる修正を行う〜

Java Basic GUI作成 〜コマンド画面を作る〜

イントロダクション

前回は、IntelliJ IDEAの使い方を兼ねて、Javaでの画面作成を
行いました。プログラムの作成はこちらです。
今回はその続きで、コマンドを入力してその値を返却する実装をやりたいと思います。

ちなみに、画面の作成にはJava言語を使用してJavaFXというライブラリを使用します。つまり、フレームワークを使用するということですね。

JavaFXは、プログラムでHTMLのように文字列を表示するラベルや、ボタン、テキストフィールド、テキストエリア、イメージなどを表示できます。アニメーションも作成できるすぐれものです。

現状

JavaFXを使用して、テキストエリアを表示、コマンドプロンプトのように「$ Cmd」と表示するプログラムができている状態です。
今回の記事では、エンターキーを押下したときの動き(アクション)を実装しようというところです。

プログラムの内容としては、area.setOnKeyPressed(createKeyPressEvent());の部分で渡しているメソッドcreateKeyPressEvent()の処理を実装しようというところです。

処理概要

  1. メインメソッドが動きApplication#launch()が起動する。
  2. CmdViewクラスのstartメソッドが動き、画面の描画を行う。
  3. startメソッドの処理中にある「createKeyPressEvent()」で操作時の処理を実装。

ソースと動画

実装しているコードはGITにあります。

そして、実行したら最終的には、こんな感じです。この記事ではここに向けてプログラムを作っているところです。

設計〜修正する場所〜

現状は以下のようになっています。

public class CmdView extends Application {
    /** 画面の横サイズ */
    private static final int VIEW_WIDTH = 300;
    /** 画面のたてサイズ */
    private static final int VIEW_HEIGHT = 300;

    @Override
    public void start(Stage primary) {
        TextArea area = createTextArea();
        Group root = new Group();
        root.getChildren().add(area);

        Scene scene = new Scene(root, VIEW_WIDTH, VIEW_HEIGHT);
        primary.setScene(scene);
        primary.show();
    }

    /**
    * TextAreaを作成して返却する
    * @return TextArea
    */
    private TextArea createTextArea() {
        TextArea area = new TextArea();
        // 縦横の幅を設定する
        area.setPrefWidth(VIEW_WIDTH);
        area.setPrefHeight(VIEW_HEIGHT);
        area.setOnKeyPressed(createKeyPressEvent());
        return area;
    }

    private EventHandler createKeyPressEvent() {
        return new EventHandler<KeyEvent>() {
            public void handle(KeyEvent evt) {
                if (KeyCode.ENTER.equals(evt.getCode())) {
                    // Enter キーを謳歌した時の処理、テキストエリアを取得する
                    TextArea src = (TextArea) evt.getSource();
                    System.out.println("Press Enter: " + src.getText());
                }
                // チェック用のコンソール出力処理
                System.out.println("EventType: " + evt.getCode());
                System.out.println("Input: " + evt.getCharacter());
            }
        };
    }
    /** メインメソッド */
    public static void main(String[] args) {
        launch();
    }
}

現状は、画面にテキストエリアを表示しただけなので、ユーザー的には
おもしろくありません。。。

なので、「ここに入力したらなんかする」という部分を作成しようと思います。
具体的には、コマンドプロンプトのように「Cmd $ 」を表示して「入力待ちですよ」ということを示したいと思います。

実装概要

今回は、以下のような機能を作成しようと思います。

  • 文字を入力して、エンターキーを押下したときに処理を実行
  • 初期表示は「Hello user please input command!」という文字列
  • 矢印キーの上下は操作不能
  • 一番下の行には「Cmd $ 」という文字列を入れる

※$の後にスペースがあります

つまり、初期表示を行い、入力はコマンドの1行のみ。
そして、今回は赤文字のメソッドcreateKeyPressEventを追加修正します。

追加修正箇所

上記のコードに追加・修正した部分が下のコードになります。

/**
 * キーボードより入力したキーで受け付けないものを<BR/>
 * 判定する
 * @param evt
 * @return true: 受け付けない入力  /  false: 受け付ける入力
 */
private boolean isDisabledInput(KeyEvent evt) {
    boolean isDisable = false;
    // 入力許可キーのKeyCodeリスト
    List<KeyCode> acList = createAcceptList();
    // チェック処理: 入力禁止するキーの有無をチェック
    return acList.contains(evt.getCode());
}

/**
 * チェック用のリストを作成して半客します<BR/>
 * 入力禁止のKeyCodeを追加
 * @return チェック用のリスト
 */
private List<KeyCode> createAcceptList() {
    List<KeyCode> acList = new ArrayList<KeyCode>();
    acList.add(KeyCode.UP);
    acList.add(KeyCode.DOWN);
    return acList;
}

チェック用のリストを作成して、そのリストに入力したキーが
含まれる場合は、trueを返すメソッドです。(二つのメソッドを使用)
今回は、入力チェック部分を作成しました。

作成したメソッドは、下のようにイベントハンドラの部分で使用します。
言葉を変えていうならば無視したい操作と受容したい操作を判別するということです。
実装としては、以下のようになります。

無視したい処理があるとき=isDisabledInputの返り値がTRUEになります。
このメソッドでTRUEが返るときに操作を無効にします。

if (isDisabledInput(evt)) {
    System.out.println("*** isDisable ***");
    resetCursor(src);
    return;
}

まとめ

画面が表示されているだけだったところに、操作を限定するようにチェックを追加、指定の操作以外はできないようにプログラムを修正しました。

でわでわ。。。