Вопрос по shortcut, javafx, button, javafx-2 – Использование JavaFX 2.2 Mnemonic (и ускорителей)

9

Я пытаюсь заставить работать JavaFX Mnemonic. У меня есть какая-то кнопка на сцене, и я хочу запустить событие этой кнопки, нажав Ctrl + S. Вот кодовый скелет:

@FXML
public Button btnFirst;

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

Мнемонический анализ кнопки имеет значение false. (Ну, когда я пытался сделать эту работу, я пытался установить ее на true, но безрезультатно). Документация JavaFX гласит, что, когда мнемоника регистрируется на сцене, а комбинация клавиш достигает сцены без использования, тогда целевому узлу будет отправлено событие ActionEvent. Но это не работает, возможно, я делаю неправильно ...

Я могу использовать мнемонику стандартной кнопки (установив для mnemonicParsing значение true и префикс «F» буквой подчеркивания). Но таким образом пользователь должен использовать клавишу Alt, которая вызывает странное поведение в браузерах со строкой меню (если приложение встроено в веб-страницу, чем меню браузера активируется после нажатия кнопки «Alt + S»). Кроме того, стандартный способ не позволяет создавать ярлыки, такие как Ctrl + Shift + F3 и так далее.

Итак, есть ли способ заставить эту работу?

Ваш Ответ

1   ответ
23

Для вашего случая использования, я думаю, вы на самом деле хотите использовать ускоритель, а не мнемонику.

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

В большинстве случаев рекомендуется использовать KeyCombination.SHORTCUT_DOWN в качестве спецификатора модификатора, как в коде выше. Хорошее объяснение этого вKeyCombination документация:

The shortcut modifier is used to represent the modifier key which is used commonly in keyboard shortcuts on the host platform. This is for example control on Windows and meta (command key) on Mac. By using shortcut key modifier developers can create platform independent shortcuts. So the "Shortcut+C" key combination is handled internally as "Ctrl+C" on Windows and "Meta+C" on Mac.

Если вы хотите специально написать код для обработки только комбинации клавиш 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

спасибо dmolony, я отредактировал ответ, чтобы включить обновленную ссылку на значок.
Примечание. Предпочитайте & quot; ярлык & quot; над & quot; контролем & quot; (Windows) или «мета» (Mac), чтобы ваше приложение не зависело от платформы.
Jewelsea, спасибо. Вы абсолютно правы, ускорители - мой пример использования. Я ошибочно подумал, что ускорители должны быть подключены к пунктам меню. Спасибо за ваш урок. bes67
URL-адрес изменился, но я нашел его здесь: & quot;icons.iconarchive.com/icons/gianni-polito/colobrush/128/…& Quot;
Спасибо, Пьюс, это хорошо для использованияSHORTCUT_DOWN скорее, чемCONTROL_DOWN, Я обновил ответ, чтобы включить эту рекомендацию.

Похожие вопросы