Javaでクイズ暗記ツール作成(13)
自分のPCはタッチ対応だからこの作りかけの「きよツール(仮称)」はとても使いやすいのだけど、普通のPCからマウスで操作する分には、(特に並べ替えが) ものすごくめんどくさくて不愉快だった。
キーボード操作に対応したいと願っていたけど知識がなかったので、イベントについて学んだ。
キーボード操作への対応方法がわかったので対応を始めた。
やったことや、今の画面の状態をメモ:
Actionオブジェクトの追加
いままでに作った機能画面は基本的にマウス操作に反応し、キーボード操作には反応しない。
ザックリ書くと以下のようなイメージ:
(即興で雰囲気だけ書いたので誤字とかで動かないかも)
Outer.java
public class Outer extends JPanel implements ActionListener { public Outer() { JToggleButton b = new JButton("o_o"); b.addActionListener(this); } @override public void actionPerformed(ActionEvent e) { System.out.println("hello,world"); } }
これをキーボード操作に対応させるにはキーストロークとアクションをひもづける必要があって、そのためにはActionMap・InputMapといったクラスを使えばいいらしい。
基本的には、
- inputMapにキーストロークと識別用オブジェクトXを登録し、
- ActionMapにキーXから↑の識別用オブジェクトと起爆するActionオブジェクトを登録
するという。
この2段階の登録操作によって、画面上でキーストロークに指定されたキーをクリックすれば、Xに紐付けられたActionのActionPerformedが呼ばれ、イベントが処理できるようになる。
で、Actionを書く必要があるが、これはOuterクラスの中にInnerクラスとして書くことにした。
おおまかに方針として、
- InnerのActionPerformedには、キーボード操作のときだけやらなきゃならない処理を書く。
- 例えば、OuterではイベントのJToggleButtonで、マウス操作ならボタンが膨らむか凹むかするが、キーボード操作だとそれはない。なのでInnerのActionPerformedでマウスの真似してボタン状態を切り替える。
- あとはInnerもOuterもやりたいことは一緒だから、InnerからOuterのActionPerformedを呼び出す。内側から外側のクラスのメンバーを呼ぶには、「Outer.this.メンバー名」でいいらしい。
上記をまとめて、だいたいこうなった:
Outer.java
public class Outer extends JPanel implements ActionListener { public Outer() { JToggleButton b = new JButton("o_o"); b.addActionListener(this); // どのコンポーネントにフォーカスがあっても反応できるようにする b.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) .put(KeyStroke.getKeyStroke("X"), "hello"); b.getActionMap().put("hello", new Inner()); } @override public void actionPerformed(ActionEvent e) { System.out.println("hello,world"); } class Inner extends AbstractAction() { @override public void actionPerformed(ActionEvent e) { JToggleButton b = (JToggleButton) e.getSource(); b.setSelected(!b.getSelected()); Outer.this.actionPerformed(e); } } }
工夫の余地はありそうだし、将来的にかえるかもしれないが今のところこんな感じのコードを今まで作ったクイズパネルに順次適用していって、キーボード操作出来る内容を増やしてく。
画面表示部品を作る
せっかくだし、Enter=OKなどなんとなく自明なもの以外は、画面に「どのキーはどの操作」というのを表示するようにする。
キーボードアイコンをExcelで作った。InkScapeとかならもっといろいろできそうだけど、正直めんどくさいからオートシェイプで十分すぎる。
そのあとExcelから透明化PNGが出力できないことに思い至って、クリスタで透明化PNGに加工した。
画像の通り、通常キーと、ホームポジションでデザインを分けた。
なんのことはないちっぽけな工夫だが、そういうのを考慮しておくと、あとからじわじわと効いてくる。
できたもの
ボタン近隣に対応したキーが表示される。
キーアサインを考えるのに以前とは変えて、できるだけホームポジション中心で選ぶようにした。このほうがモーパイしやすくて入力がぐっと楽になる。
とりあえずいくつか組み込んだ結果がこれ:
操作感はそこそこで、たぶんそのうち慣れる。