質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

2回答

1757閲覧

JavaFXに於いて、デフォルトで作動するコントロールをなくしたい。

Yossy_

総合スコア11

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

0クリップ

投稿2018/01/05 01:21

###前提・実現したいこと
Kotlin実装で、JavaFXのTextAreaで、vim等のキーバインドを真似て実装しようとしたところ、追加したイベントハンドラとは別に、OSかなにかの元々の動作が同時に実行されてしまいます。これをなくしたいです。

###発生している問題・エラーメッセージ

###該当のソースコード
JavaとありますがただしくはKotlinです

java

1controller.mainTextArea.setOnKeyPressed { 2 3 if(event.isControlDown){ 4 5 val area = controller.mainTextArea 6 when (event.code) { 7 8 KeyCode.S -> controller.menu_file_save.onAction.handle(ActionEvent())//無視 9 KeyCode.H -> area.backward()//バックスペースの挙動が同時に出てしまう!該当部分 10 KeyCode.L -> area.forward 11 12 else -> {} 13 } 14 } 15 16}

###試したこと
どうやらTextAreaのスーパーを探してもそれらしきソースは見当たらず、OS依存のものではどうすればよいかわからずなにも出来ていません。

###補足情報(言語/FW/ツール等のバージョンなど)
JavaFX8-151 Java8 IntelliJ-idea

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

JavaFXのイベントはシーンのルート階層から下の階層に向かってイベントのハンドリングをするキャプチャリングーフェーズと一番下から逆に上に向かってハンドリングするバブリングフェーズにわかれています。(JavaFX固有ではなくブラウザーのイベントハンドリングも似た感じのようです)

setOnKeyPressedなどの多くのハンドラー設定メソッドはバブリングフェーズ用のハンドラーを登録します。TextAreaの実装を確認したわけではないのですが、例えばキャプチャリングフェーズで何かのハンドリングが行われている場合はバブリングフェーズで独自の実装を入れてもご質問のようなことが起きます。そこでこうした場合キャプチャリングフェーズの方でハンドリングをするとよいと思います。

Javaの例で書きますと以下のような感じです。(Kotlinでなくてすみませんがやることは同じなので意図は伝わると思います)

Java

1import javafx.application.Application; 2import javafx.event.EventDispatcher; 3import javafx.scene.Scene; 4import javafx.scene.control.TextArea; 5import javafx.scene.input.KeyEvent; 6import javafx.scene.layout.VBox; 7import javafx.stage.Stage; 8 9public class Life5 extends Application { 10 @Override 11 public void start(Stage stage) throws Exception { 12 TextArea ta = new TextArea(); 13 EventDispatcher orginalDispatcher = ta.getEventDispatcher(); 14 ta.setEventDispatcher((ev, tail) -> { 15 if (ev instanceof KeyEvent) { 16 KeyEvent event = (KeyEvent)ev; 17 if (event.isControlDown()) { 18 switch (event.getCode()) { 19 case H: 20 if (event.getEventType() == KeyEvent.KEY_PRESSED) { 21 ta.backward(); 22 event.consume(); 23 } 24 return null; 25 } 26 } 27 } 28 return orginalDispatcher.dispatchEvent(ev, tail); 29 }); 30 VBox box = new VBox(ta); 31 stage.setScene(new Scene(box, 300, 200)); 32 stage.show(); 33 } 34}

投稿2018/01/05 01:58

編集2018/01/05 01:59
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2018/01/05 02:08

ちなみにevent.consumeを呼び出してはいますが、キャプチャリングフェーズだと意味はないかも知れません。このあたりそうまで詳しく調べたことがないので・・・すみません。
guest

0

ベストアンサー

Kotlinの知識がないので当てはまるかどうか不明ですが…

UI系のイベントで、「独自の処理を行ったからOSのネイティブ動作はしないでほしい」という場合、イベントに「これはうちで処理したからそっちはもうなにもしなくてよい」と伝えなければなりません。JavaFXにおいてその処理はEvent#consume()というメソッドが担っています。なので、OS依存の処理を起こしてほしくない分岐の際にこのメソッドを呼んで、OS依存の処理をキャンセルしてみてください。
https://docs.oracle.com/javase/jp/8/javafx/api/javafx/event/Event.html#consume--

投稿2018/01/05 01:49

masaya_ohashi

総合スコア9206

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問