我还没有找到在JavaFx 8对话框中为按钮类型指定键盘快捷键的直接方法。
例如:
dialog.dialogPane().getButtonTypes.addAll(ButtonType.OK, ButtonType.Cancel)
如何将ESC键分配给ButtonType.Cancel?
感谢。
答案 0 :(得分:1)
您可以使用加速器,如下所示:
JavaFX对话框在定义和使用按钮的方式上有点奇怪(并且复杂),因此添加加速器会有点复杂,但仍然有可能。下面的代码设置一个加速器,当按下一个组合键时触发按钮动作,快捷键+ f,快捷键将根据你的操作系统改变(在OS X上它是标记为#34的键;命令" )。
// Create a custom button type:
ButtonType fishingButtonType = new ButtonType( "Go fishing", ButtonBar.ButtonData.OTHER);
dialog.getDialogPane().getButtonTypes().add(fishingButtonType);
// Set an accelerator and an action for the fishing button.
Button fishingButton = (Button) dialog.getDialogPane().lookupButton(fishingButtonType);
fishingButton.addEventFilter(ActionEvent.ACTION, ae -> {
// linkware image: http://www.iconka.com
dialog.setGraphic(new ImageView("http://icons.iconarchive.com/icons/iconka/meow/64/cat-fish-icon.png"));
ae.consume(); // consume the action so that the dialog does not close when the button is pressed.
});
fishingButton.sceneProperty().addListener((observable, oldValue, newScene) -> {
if (newScene != null) {
newScene.getAccelerators().put(
new KeyCodeCombination(KeyCode.F, KeyCombination.SHORTCUT_DOWN),
fishingButton::fire
);
}
});
可执行示例代码
大部分代码都是从优秀的Makery JavaFX dialog tutorial中解脱出来的。附加代码已添加到教程代码中,以添加钓鱼按钮和加速器以触发它。
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.input.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.Pair;
import java.util.Optional;
public class LoginDialog extends Application {
@Override
public void start(Stage stage) throws Exception {
Button showDialogButton = new Button("Show Dialog");
showDialogButton.setOnAction(event -> {
showDialog();
});
StackPane layout = new StackPane(showDialogButton);
layout.setPadding(new Insets(10));
stage.setScene(new Scene(layout));
stage.show();
}
private void showDialog() {
// Create the custom dialog.
Dialog<Pair<String, String>> dialog = new Dialog<>();
dialog.setTitle("Login Dialog");
dialog.setHeaderText("Look, a Custom Login Dialog");
// Set the icon.
// icon source: http://www.iconarchive.com/show/soft-scraps-icons-by-hopstarter/Lock-Lock-icon.html
dialog.setGraphic(new ImageView("http://icons.iconarchive.com/icons/hopstarter/soft-scraps/64/Lock-Lock-icon.png"));
// Set the button types.
ButtonType loginButtonType = new ButtonType("Login", ButtonBar.ButtonData.OK_DONE);
ButtonType fishingButtonType = new ButtonType( "Go fishing", ButtonBar.ButtonData.OTHER);
dialog.getDialogPane().getButtonTypes().addAll(loginButtonType, fishingButtonType, ButtonType.CANCEL);
// Create the username and password labels and fields.
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(20, 150, 10, 10));
TextField username = new TextField();
username.setPromptText("Username");
PasswordField password = new PasswordField();
password.setPromptText("Password");
grid.add(new Label("Username:"), 0, 0);
grid.add(username, 1, 0);
grid.add(new Label("Password:"), 0, 1);
grid.add(password, 1, 1);
// Enable/Disable login button depending on whether a username was entered.
Node loginButton = dialog.getDialogPane().lookupButton(loginButtonType);
loginButton.setDisable(true);
// Set an accelerator and an action for the fishing button.
Button fishingButton = (Button) dialog.getDialogPane().lookupButton(fishingButtonType);
fishingButton.addEventFilter(ActionEvent.ACTION, ae -> {
// linkware image: http://www.iconka.com
dialog.setGraphic(new ImageView("http://icons.iconarchive.com/icons/iconka/meow/64/cat-fish-icon.png"));
ae.consume();
});
fishingButton.sceneProperty().addListener((observable, oldValue, newScene) -> {
if (newScene != null) {
newScene.getAccelerators().put(
new KeyCodeCombination(KeyCode.F, KeyCombination.SHORTCUT_DOWN),
fishingButton::fire
);
}
});
// Do some validation (using the Java 8 lambda syntax).
username.textProperty().addListener((observable, oldValue, newValue) -> {
loginButton.setDisable(newValue.trim().isEmpty());
});
dialog.getDialogPane().setContent(grid);
// Request focus on the username field by default.
Platform.runLater(username::requestFocus);
// Convert the result to a username-password-pair when the login button is clicked.
dialog.setResultConverter(dialogButton -> {
if (dialogButton == loginButtonType) {
return new Pair<>(username.getText(), password.getText());
}
return null;
});
Optional<Pair<String, String>> result = dialog.showAndWait();
result.ifPresent(usernamePassword -> {
System.out.println("Username=" + usernamePassword.getKey() + ", Password=" + usernamePassword.getValue());
});
}
public static void main(String[] args) {
launch(args);
}
}