如何为按钮添加javafx快捷键组合

时间:2018-02-05 05:43:21

标签: javafx keyboard-shortcuts

我的用户界面有一个添加按钮,我想为其分配键盘快捷键组合。我没有为此目的使用setAcceleartor。 在javafx应用程序中设置键盘快捷键的最简单方法是什么?

UI中的

按钮声明:

 <Button fx:id="addButton" alignment="CENTER" minWidth="-Infinity" mnemonicParsing="false" onAction="#addAction" prefHeight="31.0" prefWidth="130.0"  text="Add"  HBox.hgrow="ALWAYS" />

控制器按钮绑定:

@FXML
private Button addButton;

想要为按钮的快捷方式设置setOnAction的方法:

    public void addAction(ActionEvent event) throws SQLException, ClassNotFoundException {
    if (validateInput()) {
        String productName = productField.getText();
        double unitPrice = Double.parseDouble(priceField.getText());
        int quantity = Integer.parseInt(quantityField.getText());
        double total = unitPrice * quantity;
        ITEMLIST.add(new Item(productName, unitPrice, quantity, total));
        calculation();
        resetAdd();
        productTableView.getSelectionModel().clearSelection();
        ObservableList<Product> productsData = ProductDAO.searchProducts();
        populateProducts(productsData);
        searchField.setText("");
    }
}

initialize()方法:

@FXML
private void initialize() throws SQLException, ClassNotFoundException, IOException {
  setSaveAccelerator(addButton);
}

我尝试使用setAccelerator的代码:

    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() {
                @FXML public void run() {
                    button.fire();
                }
            }
    );
}

1 个答案:

答案 0 :(得分:1)

setSaveAccelerator方法中,只需指示按钮将其事件触发到其侦听器,例如:addAction(ActionEvent event),而不是直接调用button.fire()。例如:

    private void setSaveAccelerator(Button button) {
        if(button==null) {
            System.out.println("Button is null! "); // check that the button was injected properly through your fxml
        }
        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() {
                @FXML public void run() {

                    button.fire();
                }
            }
       );
   }

修改

要避免IllegalArgumentException,必须在按钮附加到场景后附加加速器。我设法通过在控制器中创建一个公共方法来实现这一点,以便在设置场景后附加加速器。然后,在加载场景的类中,可以调用控制器的方法来设置该功能。请参阅以下示例:

在控制器类中(在我的情况下为MainController):

public void setup() {
    setSaveAccelerator(button);
}

加载fxml文件时在主类中:

    FXMLLoader loader = new FXMLLoader(MainController.class.getResource("mainFXML.fxml"));
    AnchorPane page = (AnchorPane) loader.load();

    MainController controller = loader.getController();

    Scene scene = new Scene(page);

    controller.setup(); // calls the setup method attaching the accelerators

完整示例

主要课程:

public class Main extends Application{

    public static Stage primaryStage;

    @Override
    public void start(Stage primaryStage) throws Exception {
        Main.primaryStage=primaryStage;

        FXMLLoader loader = new FXMLLoader(MainController.class.getResource("mainFXML.fxml"));
        AnchorPane page = (AnchorPane) loader.load();

        MainController controller = loader.getController();

        Scene scene = new Scene(page);

        primaryStage.setTitle("Shortcut example");
        primaryStage.setScene(scene);

        controller.setup();

        primaryStage.show();

    }

    public static void main(String[] args) {

        launch(args);
    }
}

Maincontroller:

public class MainController {

    @FXML
    private ResourceBundle resources;

    @FXML
    private URL location;

    @FXML
    private Button button;

    @FXML
    private AnchorPane rootPane;

    @FXML
    private TextArea textarea;

    @FXML
    void action(ActionEvent event) {

        textarea.setText("Action fired!!");
    }

    @FXML
    void initialize() {
        assert button != null : "fx:id=\"button\" was not injected: check your FXML file 'MainFXML.fxml'.";
        assert rootPane != null : "fx:id=\"rootPane\" was not injected: check your FXML file 'MainFXML.fxml'.";
        assert textarea != null : "fx:id=\"textarea\" was not injected: check your FXML file 'MainFXML.fxml'.";

    }

    public void setup() {
        setSaveAccelerator(button);
    }


    private void setSaveAccelerator(Button button) {
        if(button==null) {
            System.out.println("Button null!!");
        }
        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() {
                    @FXML public void run() {

                        button.fire();
                    }
                }
                );
    }
}

MainFXML.fxml

<AnchorPane fx:id="rootPane" prefHeight="408.0" prefWidth="330.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
   <children>
      <Button fx:id="button" layoutX="139.0" layoutY="350.0" mnemonicParsing="false" onAction="#action" text="Button" />
      <TextArea fx:id="textarea" layoutX="73.0" layoutY="38.0" prefHeight="200.0" prefWidth="200.0" />
   </children>
</AnchorPane>