JavaFXのTextAreaにおけるタブの制御方法に代替無し
問題
JavaFXのTextAreaにおいて、タブキーを押した場合にタブ文字を入れるのではなく、次のフィールドにフォーカスを写してほしいのだが、タブ文字として入力されてしまう。これを以下のように制御したい。
- タブのみの場合は次のフィールドへフォーカスを移す。
- CTRLと同時の場合にタブ文字を入力する。
- Shiftと同時の場合に前のフィールドにフォーカスを移す。
Java8での解決策とJava9の対応
/** これはJava8でコンパイルする */
import com.sun.javafx.scene.control.behavior.*;
import com.sun.javafx.scene.control.skin.*;
......
textArea.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
@SuppressWarnings("restriction")
@Override
public void handle(KeyEvent event) {
if (event.getCode() != KeyCode.TAB) return;
if (!tabTraverse) return;
try {
TextAreaSkin skin = (TextAreaSkin)textArea.getSkin();
BehaviorBase<?> bb = skin.getBehavior();
if (!(bb instanceof TextAreaBehavior)) return;
TextAreaBehavior behavior = (TextAreaBehavior)bb;
if (event.isControlDown()) {
behavior.callAction("InsertTab");
} else if (event.isShiftDown()) {
behavior.callAction("TraversePrevious");
} else {
behavior.callAction("TraverseNext");
}
event.consume();
} catch (NoClassDefFoundError ex) {
// Java9でJavaFXの仕様変更。代替策なし
}
}
});
Java9で仕様変更されており、TextAreaSkinが正規のクラスとなったのは良いのだが、getBehavior()メソッドがなくなり、同じ動作をさせることができなくなってしまった。上のコードは、Java9での実行においては単純に何もしない。
ディスカッション
コメント一覧
すみせん、分かりきった部分で省略されているのだと思いますが、
tabTraverseif (!tabTraverse) return;
の変数tabTraerseがどこで宣言すべきで、どのように値の取得するのかが分かりかねております。
真に恐縮ではございますがお書き添え頂ければ幸に存じます。
どうかよろしくお願い致します。
まだかなり変更する予定なので、紹介記事を書いていないのですが、以下にあります。
https://github.com/ysugimura/fxwrapper/blob/master/src/com/cm55/fx/FxTextArea.java
fxwrapperというオープンソースラッパライブラリです。
https://github.com/ysugimura/fxwrapper
ただ、かえってわかりにくいと感じるかもしれません。