Usando JavaFX 2.2 Mnemonic (y aceleradores)

Estoy tratando de hacer funcionar JavaFX Mnemonic. Tengo un botón en la escena y lo que quiero lograr es disparar este evento de botón presionando Ctrl + S. Aquí hay un código sceleton:

@FXML public Button btnFirst; btnFirst.getScene().addMnemonic(new Mnemonic(btnFirst, new KeyCodeCombination(KeyCode.S, KeyCombination.CONTROL_DOWN))); 

La función mnemotécnica de Button es falsa. (Bueno, al intentar hacer esto, intenté establecerlo en verdadero, pero sin resultado). La documentación de JavaFX establece que cuando un Mnemónico se registra en una Escena y KeyCombination no llega a la Escena, entonces el Nodo de destino recibirá un ActionEvent. Pero esto no funciona, probablemente, estoy haciendo mal …

Puedo usar el mnemónico del botón estándar (estableciendo mnemonicParsing en verdadero y prefijo la letra “F” en el carácter de guión bajo). Pero de esta manera el usuario tiene que usar la tecla Alt, que trae un comportamiento extraño en los navegadores con la barra de menú (si la aplicación está integrada en la página web que el menú del navegador activado después del evento del botón de disparo presionando Alt + S). Además, la forma estándar hace que sea imposible hacer accesos directos como Ctrl + Shift + F3 y así sucesivamente.

Entonces, si hay alguna forma de hacer que esto funcione?

Para su caso de uso, creo que realmente desea usar un acelerador en lugar de un mnemotécnico.

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

En la mayoría de los casos, se recomienda utilizar KeyCombination.SHORTCUT_DOWN como especificador de modificador, como en el código anterior. Una buena explicación de esto está en la documentación de KeyCombination :

El modificador de acceso directo se usa para representar la tecla modificadora que se usa comúnmente en los atajos de teclado en la plataforma de host. Esto es, por ejemplo, el control en Windows y meta (tecla de comando) en Mac. Mediante el uso de modificadores de teclas de método abreviado, los desarrolladores pueden crear accesos directos independientes de la plataforma. Por lo tanto, la combinación de teclas “Acceso directo + C” se maneja internamente como “Ctrl + C” en Windows y “Meta + C” en Mac.

Si desea codificar específicamente solo para manejar una combinación de teclas Ctrl + S, puede usar:

 new KeyCodeCombination(KeyCode.S, KeyCombination.CONTROL_DOWN) 

Aquí hay un ejemplo ejecutable:

 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() { @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() { @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 

Muestra de salida:

Muestra de salida del programa

    Intereting Posts