簡體   English   中英

如何設置在 JavaFX 中按下任何鍵盤鍵時發生的動作?

[英]How to set an action to occur on pressing of any keyboard key in JavaFX?

所以我想為大學的視頻游戲項目做一個標題菜單。 我想顯示一條消息按任意鍵繼續...然后當用戶按任意鍵(包括鼠標)時,將運行一個方法以將舞台設置為下一個菜單。

在此處輸入圖片說明

我在下面發布了所有相關代碼,但簡短版本是:

  • BackgroundImangeDisplayPane擴展顯示窗格並添加背景圖像。
  • TitleCard擴展了BackgroundImangeDisplayPane為 VBox 添加了一個 VBox 和 2 個標簽
  • 我使用public void start(Stage primaryStage) throws Exception作為主要,我在這里設置了setOnActionxxx方法

我曾嘗試在 root 和 Vbox 上使用 set on action 方法,但它們都不起作用……當我單擊時什么也沒有發生……但是當我調整窗口大小時root.setOnActionXXX “激活”。

如果我在TitleCard類上編寫 setOnAction 方法它有點工作,但我無法切換舞台。

我將在下面發布代碼以及對場景結構的解釋,它並不復雜:


// this will be the borderpane for every scene it recives a backgund 
//images that will be present in every menu
public BackgroundImangeDisplayPane() {
        try {
            stream = new FileInputStream(imagePath.toString());
            Image image = new Image(stream);
            ImageView imageView = new ImageView();
            imageView.setImage(image);
            imageView.setFitWidth(1920);
            imageView.setPreserveRatio(true);
            this.getChildren().add(imageView);

            BackgroundSize backgoundSize = new BackgroundSize(AUTO, AUTO, true, true, true, true);
            BackgroundImage backgroundImage = new BackgroundImage(image, NO_REPEAT, NO_REPEAT, CENTER, backgoundSize);
            Background background = new Background(backgroundImage);
            this.setBackground(background);

        } catch (Exception e) {

        }
    }


//This extends `BackgroundImangeDisplayPane` and places on top of it a A Vbox with two lables: the title and "press any key to continue..."
// it then adds styles to the labels
public class TitleCard extends BackgroundImangeDisplayPane {
    Label title = new Label("Boats & Docks"); // lable 1
    Label subtitle = new Label("Press any key to continue ..."); label2
    
    public TitleCard(){
        super();
        VBox vbox = new VBox();
        vbox.getChildren().add(title);
        vbox.getChildren().add(subtitle);
        
        this.setCenter(vbox);
        this.setAlignment(vbox, Pos.CENTER);
        vbox.setAlignment(Pos.CENTER);
        title.setFont(new Font(170)); // set to Label
        title.setTextFill(Color.SNOW);
        title.setEffect(new DropShadow());
        subtitle.setFont( new Font (30));
          
    }
}

... 
//Works as the "main" in javaFX
private Stage primaryStage;

    @Override
    public void start(Stage primaryStage) throws Exception {

        TitleCard root = new TitleCard();
        /*BasicMenu menu = new BasicMenu(5);
        menu.ButtonSetOnAction(0, e -> changeScene() );
        BackgroundImangeWithCustomMenu background = new 
        BackgroundImangeWithCustomMenu(menu,50,50);
        root.setCenter(background);*/
        Button b = new Button();
        b.setOnAction(e -> changeSceneToLoginMenu());
        System.out.println(root.getChildren().get(1).getClass());
        root.getChildren().get(1).setFocusTraversable(true);
        root.getChildren().get(1).setOnMouseClicked(e -> changeSceneToLoginMenu());
        root.getChildren().get(1).setOnKeyPressed(e -> changeSceneToLoginMenu());
        root.getChildren().get(0).setOnMouseClicked(e -> changeSceneToLoginMenu());
        root.getChildren().get(0).setOnKeyPressed(e -> changeSceneToLoginMenu());
/*
        root.setOnMouseClicked(e -> changeSceneToLoginMenu());
        root.setOnKeyReleased(e -> changeSceneToLoginMenu());
        root.setOnKeyPressed(e -> changeSceneToLoginMenu());
*/
        Scene scene = new Scene(root, 1280, 720);
        primaryStage.setScene(scene);
        primaryStage.show();

        this.primaryStage = primaryStage;

    }

正如 James 在評論中提出的那樣,當在場景上按下一個時,導航到下一個場景(或替換當前場景中的根,並刪除按鍵處理程序)。

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

我設法找到了一個非常簡單的工作解決方案,但我並沒有完全理解它為什么起作用。 我注意到,如果我在同一個類中設置處理程序,則該節點被實例化,處理程序將正常工作但是如果我嘗試通過root.getChildren().get(1)將具有方法的節點獲取到主要功能,然后進行轉換它到 VBox 元素處理程序將不起作用。

作為解決方案,我將 VBox 設為一個字段,為 TitleCard 類中的 VBox 事件處理程序編寫了一個setter 方法 這解決了問題。

我將添加的代碼標記為帶有注釋的解決方案代碼


public class TitleCard extends BackgroundImangeDisplayPane {
    
    Label title = new Label("Boats & Docks"); // lable 1
    Label subtitle = new Label("Press any key to continue ..."); label2
    VBox vbox = new VBox; // solution code
    
public TitleCard(){
        super();
        VBox vbox = new VBox();
        vbox.getChildren().add(title);
        vbox.getChildren().add(subtitle);
        
        this.setCenter(vbox);
        this.setAlignment(vbox, Pos.CENTER);
        vbox.setAlignment(Pos.CENTER);
        title.setFont(new Font(170)); // set to Label
        title.setTextFill(Color.SNOW);
        title.setEffect(new DropShadow());
        subtitle.setFont( new Font (30));
          
    }
// Solution Code
public void setVBoxHandler(EventHandler<? super MouseEvent> value){
      vbox.setOnMouseClicked(value); 
 }
}

然后我在 start 方法中設置處理程序:

public void start(Stage primaryStage) throws Exception {

        TitleCard root = new TitleCard();
        VBox vBox =(VBox) root.getChildren().get(1);
        root.setVBoxHandler(e->changeSceneToLoginMenu() ); // solution Code
        
        Scene scene = new Scene(root, 1280, 720);
        primaryStage.setScene(scene);
        primaryStage.show();

        this.primaryStage = primaryStage;

    }

    public void changeSceneToLoginMenu() {
        System.out.println("It finally worked");
        Scene currentScene = new Scene(new Group(),100,100); // just a demo
        primaryStage.setScene(currentScene);

    }

注意: setVBoxHandler(EventHandler<? super MouseEvent> value)方法上的setVBoxHandler(EventHandler<? super MouseEvent> value)將取決於所使用的setOnXXX方法。 例如我測試過,這個靈魂也適用於按鈕,只需將類型更改為EventHandler<ActionEvent> value

關於這個問題的一些評論發布了關於“如何使用處理程序”的鏈接,這個帖子使用了異常類。 我相信這種方式已經過時了。 我在代碼中使用了 lambdas 最終結果是相同但更可紅的代碼

僅供參考,如果未來的讀者使用異常類,解決方案將相同,只需更改您設置處理程序的方式:


// lambdas
setVBoxHandler( e -> System.out.println("Code run if mouse is clicked "));

// anomimous classes
setVBoxHandler(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event){
        System.out.println("Code run if mouse is clicked ");
    }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM