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

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

ただいまの
回答率

88.92%

JavaFx ファンクションキーでボタンクリック時と同じイベントを実行させたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 93

pyoon.

score 8

前提・実現したいこと

タイトルの通りです。
マウスでボタンをクリックしてイベントを実行するのはSceneBuilderのOn Actionで追加していますが、
ファンクションキーで同一イベントを実行させたいときの処理が上手くできません。

試したこと

Scene追加部分に    

scene.setOnKeyPressed(e -> press(e));


KeyCodeのグローバル変数Keyに取得したキーを保存しています。

public static void press(KeyEvent event) {
        switch (event.getCode()) {
        case F2:
            event.getCode();
            Hensu.Key = event.getCode();
            System.out.println(event.getCode());
            break;
        case F3:
            event.getCode();
            Hensu.Key = event.getCode();
            System.out.println(event.getCode());
            break;
        case F4:
            event.getCode();
            Hensu.Key = event.getCode();
            System.out.println(event.getCode());
            break;
        case F5:
            event.getCode();
            Hensu.Key = event.getCode();
            System.out.println(event.getCode());
            break;
        case F6:
            event.getCode();
            Hensu.Key = event.getCode();
            System.out.println(event.getCode());
            break;
        case F9:
            event.getCode();
            Hensu.Key = event.getCode();
            System.out.println(event.getCode());
            break;
        case ESCAPE:
            event.getCode();
            Hensu.Key = event.getCode();
            System.out.println(event.getCode());
            break;
        default:
            break;
        }
    }

分からないこと

・変数で取得したあとの判定と実行のさせかた
・多数の画面遷移があるのでSceneの部分の追加は都度やらなければいけないのか

追記

 void On_buttonF2Click(ActionEvent event) {    
     /*
         * 新しい画面を生成する
         */
        try {
            Parent parent = FXMLLoader.load(getClass().getResource("Ndenpyo.fxml"));
            Scene scene = new Scene(parent);
            Stage stage = new Stage();
            KANRIMENUController controller = scene.<KANRIMENUController>getController();
            scene.getAccelerators().put(KeyCodeCombination.valueOf("F2"), () -> controller.buttonF2.fire());
            stage.setScene(scene);
            stage.setTitle("入荷伝票一覧");
            stage.show();


        }catch(IOException e) {
            e.printStackTrace();
        }
}

追記2

try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Ndenpyo.fxml"));
            Parent parent = loader.load();
            Scene scene = new Scene(parent);
            Stage stage = new Stage();
            KANRIMENUController controller = loader.<KANRIMENUController>getController();
            scene.getAccelerators().put(KeyCodeCombination.valueOf("F2"), () ->controller.buttonF2.fire());
            stage.setScene(scene);
            stage.setTitle("入荷伝票一覧");
            stage.show();


        }catch(IOException e) {
            e.printStackTrace();
        }

コンソール

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1787)
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8879)
    at javafx.controls/javafx.scene.control.ToggleButton.fire(ToggleButton.java:257)
    at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
    at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3851)
    at javafx.graphics/javafx.scene.Scene$MouseHandler.access$1200(Scene.java:3579)
    at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1849)
    at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2588)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434)
    at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:390)
    at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433)
    at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
    at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
    at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
    at com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782)
    ... 47 more
Caused by: java.lang.ClassCastException: class application.Ndenpyo cannot be cast to class application.KANRIMENUController (application.Ndenpyo and application.KANRIMENUController are in unnamed module of loader 'app')
    at application.KANRIMENUController.On_buttonF2Click(KANRIMENUController.java:97)
    ... 58 more

追記3

    FXMLLoader loader = new FXMLLoader(getClass().getResource("KANRIMENU.fxml")); //KANRIMENU→例で行くとmain
            Parent parent = loader.load();
            Scene scene = new Scene(parent);
            KANRIMENUController controller = loader.<KANRIMENUController>getController();
            scene.getAccelerators().put(KeyCodeCombination.valueOf("ESCAPE"), () -> controller.buttonEsc.fire()); //ここで指定するボタンは例で行くとappの画面にあるものです

            Stage stage = new Stage();
            stage.setScene(scene);
            stage.setTitle("メインメニュー");//メインメニューは例で行くとappです
            stage.show();
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

アクセラレータがいいんじゃないでしょうか。
シーンが複数ある場合は、おそらくシーンごとに設定するしかなさそうです。

App.java

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.KeyCodeCombination;
import javafx.stage.Stage;

public class App extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml"));
        Parent parent = loader.load();
        Scene scene = new Scene(parent);
        MainController controller = loader.<MainController>getController();
        scene.getAccelerators().put(KeyCodeCombination.valueOf("F2"), () -> controller.button.fire());
        primaryStage.setScene(scene);
        primaryStage.setTitle("メイン");
        primaryStage.show();
    }

    public static void main(String[] args) { launch(args); }
}

main.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.BorderPane?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
            prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="sample.MainController">
    <center>
        <Button fx:id="button" mnemonicParsing="false" onAction="#onButtonClick" text="サブへ"
                BorderPane.alignment="CENTER"/>
    </center>
</BorderPane>


MainController.java

package sample;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCodeCombination;
import javafx.stage.Stage;
import javafx.stage.Window;

public class MainController {
    @FXML
    Button button;

    @FXML
    protected void onButtonClick(ActionEvent evt) throws Exception {
        Scene s = ((Node) evt.getSource()).getScene();
        Window w = s.getWindow();
        w.hide();

        FXMLLoader loader = new FXMLLoader(getClass().getResource("sub.fxml"));
        Parent parent = loader.load();
        Scene scene = new Scene(parent);
        SubController controller = loader.<SubController>getController();
        scene.getAccelerators().put(KeyCodeCombination.valueOf("F2"), () -> controller.button.fire());
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.setTitle("サブ");
        stage.show();
    }
}

sub.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.BorderPane?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0"
            prefWidth="400.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="sample.SubController">
    <center>
        <Button fx:id="button" mnemonicParsing="false" onAction="#onButtonClick" text="メインへ"
                BorderPane.alignment="CENTER"/>
    </center>
</BorderPane>


SubController.java

package sample;

import java.io.IOException;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCodeCombination;
import javafx.stage.Stage;
import javafx.stage.Window;

public class SubController {
    @FXML
    Button button;

    @FXML
    protected void onButtonClick(ActionEvent evt) throws IOException {
        Scene s = ((Node) evt.getSource()).getScene();
        Window w = s.getWindow();
        w.hide();

        FXMLLoader loader = new FXMLLoader(getClass().getResource("main.fxml"));
        Parent parent = loader.load();
        Scene scene = new Scene(parent);
        MainController controller = loader.<MainController>getController();
        scene.getAccelerators().put(KeyCodeCombination.valueOf("F2"), () -> controller.button.fire());
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.setTitle("メイン");
        stage.show();
    }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/09/18 13:23

    追加で申し訳ありません!ESCAPE以外のキーはTN8001様のおかげで全て希望通り動くようになりました・・・本当にありがとうございます!!
    ですがやはりESCAPEだけ判定してもらえず、無反応な状態です・・・
    ご教授お願いします;;

    キャンセル

  • 2020/09/18 16:43

    追加で申し訳ないです!!ESCAPEはEscで通りました・・・
    ありがとうございました。本当に助かりました。

    キャンセル

  • 2020/09/18 16:58

    んと目的通り動いたってことでいいんですか?
    3段版もちまちま書いていたんですがもういいですね^^;

    キャンセル

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

  • ただいまの回答率 88.92%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る