2012-10-03 16 views
8

私はJavaFXニーモニックの仕事をしようとしています。シーンにいくつかのボタンがあり、私が達成したいのはCtrl + Sを押してこのボタンイベントを発生させることです。ここ は、コードsceletonです:JavaFX 2.2ニーモニック(アクセラレータ)

@FXML 
public Button btnFirst; 

btnFirst.getScene().addMnemonic(new Mnemonic(btnFirst, 
      new KeyCodeCombination(KeyCode.S, KeyCombination.CONTROL_DOWN))); 

ボタンのmnemonicParsingはfalseです。 (まあ、この仕事をしようとしている間、私はそれを真に設定しようとしましたが、結果はありません)。 JavaFXのマニュアルには、ニーモニックがシーンに登録され、KeyCombinationが使用されていないシーンに到達すると、ターゲットノードにActionEventが送信されることが記載されています。しかし、これはうまくいきません。

標準ボタンのニーモニックを使用できます(mnemonicParsingをtrueに、プレフィックス 'F'をアンダースコアで設定)。しかし、この方法では、Altキーを使用する必要があります。これは、メニューバーを使ってブラウザに異常な動作を引き起こします(Alt + Sを押してボタンイベントを発生させた後にブラウザのメニューがWebページに埋め込まれている場合)。 さらに、標準的な方法では、Ctrl + Shift + F3などのショートカットを作成することができません。

これを行うにはいくつかの方法がありますか?

答えて

20

実際には、ニーモニックではなくアクセラレータを使用したいと考えています。

button.getScene().getAccelerators().put(
    new KeyCodeCombination(KeyCode.S, KeyCombination.SHORTCUT_DOWN), 
    new Runnable() { 
    @Override public void run() { 
     button.fire(); 
    } 
    } 
); 

は、ほとんどの場合、あなたが上記のコードのように、修飾指定子としてKeyCombination.SHORTCUT_DOWNを使用することをお勧めします。この良い説明は KeyCombinationドキュメントである:ショートカット修飾子は、ホストプラットフォーム上でキーボードショートカットで一般的に使用される で修飾キーを表すために使用される

。これはWindows上の のサンプルコントロールとMacのmeta(コマンドキー)です。 ショートカットキー修飾子を使用することで、プラットフォームに依存しないショートカットを作成することができます。したがって、 "Shortcut + C"キーの組み合わせは、Windowsでは "Ctrl + C"、Macでは "Meta + C"として内部で として処理されます。

あなたは、具体的のみのCtrl + Sキーの組み合わせを処理するコードしたい場合、彼らはあなたが使用できます。

new KeyCodeCombination(KeyCode.S, KeyCombination.CONTROL_DOWN) 

ここで実行可能な例である:

import javafx.animation.*; 
import javafx.application.Application; 
import javafx.event.*; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.scene.image.*; 
import javafx.scene.input.*; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 
import javafx.util.Duration; 

public class SaveMe extends Application { 
    @Override public void start(final Stage stage) throws Exception { 
    final Label response = new Label(); 
    final ImageView imageView = new ImageView(
     new Image("http://icons.iconarchive.com/icons/gianni-polito/colobrush/128/software-emule-icon.png") 
    ); 
    final Button button = new Button("Save Me", imageView); 
    button.setStyle("-fx-base: burlywood;"); 
    button.setContentDisplay(ContentDisplay.TOP); 
    displayFlashMessageOnAction(button, response, "You have been saved!"); 

    layoutScene(button, response, stage); 
    stage.show(); 

    setSaveAccelerator(button); 
    } 

    // sets the save accelerator for a button to the Ctrl+S key combination. 
    private void setSaveAccelerator(final Button button) { 
    Scene scene = button.getScene(); 
    if (scene == null) { 
     throw new IllegalArgumentException("setSaveAccelerator must be called when a button is attached to a scene"); 
    } 

    scene.getAccelerators().put(
     new KeyCodeCombination(KeyCode.S, KeyCombination.SHORTCUT_DOWN), 
     new Runnable() { 
     @Override public void run() { 
      fireButton(button); 
     } 
     } 
    ); 
    } 

    // fires a button from code, providing visual feedback that the button is firing. 
    private void fireButton(final Button button) { 
    button.arm(); 
    PauseTransition pt = new PauseTransition(Duration.millis(300)); 
    pt.setOnFinished(new EventHandler<ActionEvent>() { 
     @Override public void handle(ActionEvent event) { 
     button.fire(); 
     button.disarm(); 
     } 
    }); 
    pt.play(); 
    } 

    // displays a temporary message in a label when a button is pressed, 
    // and gradually fades the label away after the message has been displayed. 
    private void displayFlashMessageOnAction(final Button button, final Label label, final String message) { 
    final FadeTransition ft = new FadeTransition(Duration.seconds(3), label); 
    ft.setInterpolator(Interpolator.EASE_BOTH); 
    ft.setFromValue(1); 
    ft.setToValue(0); 
    button.setOnAction(new EventHandler<ActionEvent>() { 
     @Override public void handle(ActionEvent event) { 
     label.setText(message); 
     label.setStyle("-fx-text-fill: forestgreen;"); 
     ft.playFromStart(); 
     } 
    }); 
    } 

    private void layoutScene(final Button button, final Label response, final Stage stage) { 
    final VBox layout = new VBox(10); 
    layout.setPrefWidth(300); 
    layout.setAlignment(Pos.CENTER); 
    layout.getChildren().addAll(button, response); 
    layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 20; -fx-font-size: 20;"); 
    stage.setScene(new Scene(layout)); 
    } 

    public static void main(String[] args) { launch(args); } 
} 
// icon license: (creative commons with attribution) http://creativecommons.org/licenses/by-nc-nd/3.0/ 
// icon artist attribution page: (eponas-deeway) http://eponas-deeway.deviantart.com/gallery/#/d1s7uih 

出力例:

Sample program output

+0

jewelsea、ありがとうu。あなたは絶対にそうです、アクセラレータは私のユースケースです。私は誤って、アクセラレータをメニュー項目に関連付ける必要があると考えました。あなたのレッスンをありがとう。 – bes67

+2

注:アプリケーションをプラットフォームに依存しないようにするには、「コントロール」(Windows)または「メタ」(Mac)を「ショートカット」にすることをお勧めします。 – Puce

+2

Thanks Puce、 'CONTROL_DOWN'ではなく' SHORTCUT_DOWN'を使うのは良いことです。この勧告を含めるように答えを更新しました。 – jewelsea

関連する問題