警告对话框中的 JavaFX 默认聚焦按钮
JavaFX default focused button in Alert Dialog
自 jdk 8u40 以来,我正在使用新的 javafx.scene.control.Alert
API 来显示确认对话框。在下面的示例中,"Yes" 按钮默认聚焦而不是 "No" 按钮:
public boolean showConfirmDialog(String title, String header, String content, AlertType alertType) {
final Alert alert = new Alert(alertType);
alert.setTitle(title);
alert.setHeaderText(header);
alert.setContentText(content);
alert.getButtonTypes().clear();
alert.getButtonTypes().addAll(ButtonType.YES, ButtonType.NO);
final Optional<ButtonType> result = alert.showAndWait();
return result.get() == ButtonType.YES;
}
而且我不知道如何更改它。
编辑:
这里是 "Yes" 按钮默认聚焦的结果截图:
我不确定以下是否是通常执行此操作的方法,但您可以通过查找按钮并自行设置默认行为来更改默认按钮:
public boolean showConfirmDialog(String title, String header, String content, AlertType alertType) {
final Alert alert = new Alert(alertType);
alert.setTitle(title);
alert.setHeaderText(header);
alert.setContentText(content);
alert.getButtonTypes().clear();
alert.getButtonTypes().addAll(ButtonType.YES, ButtonType.NO);
//Deactivate Defaultbehavior for yes-Button:
Button yesButton = (Button) alert.getDialogPane().lookupButton( ButtonType.YES );
yesButton.setDefaultButton( false );
//Activate Defaultbehavior for no-Button:
Button noButton = (Button) alert.getDialogPane().lookupButton( ButtonType.NO );
noButton.setDefaultButton( true );
final Optional<ButtonType> result = alert.showAndWait();
return result.get() == ButtonType.YES;
}
如果你看一下 (private) ButtonBarSkin
class,有一个名为 doButtonOrderLayout()
的方法执行按钮的布局,基于一些默认值 OS 行为。
在里面,你可以读到:
/* now that all buttons have been placed, we need to ensure focus is
set on the correct button. [...] If so, we request focus onto this default
button. */
由于 ButtonType.YES
是默认按钮,它将成为焦点。
所以@ymene 的回答是正确的:您可以更改默认行为,然后焦点将是 NO
。
或者您可以通过在 buttonOrderProperty()
中设置 BUTTON_ORDER_NONE
来避免使用该方法。现在第一个按钮将获得焦点,因此您需要先放置 NO
按钮。
alert.getButtonTypes().setAll(ButtonType.NO, ButtonType.YES);
ButtonBar buttonBar=(ButtonBar)alert.getDialogPane().lookup(".button-bar");
buttonBar.setButtonOrder(ButtonBar.BUTTON_ORDER_NONE);
请注意 YES
仍将具有默认行为:这意味着 NO
可以使用 space 栏(聚焦按钮)进行选择,而 YES
将是如果按回车键(默认按钮),则选中。
或者您也可以更改@crusam 回答后的默认行为。
感谢 crusam 的简单功能:
private static Alert setDefaultButton ( Alert alert, ButtonType defBtn ) {
DialogPane pane = alert.getDialogPane();
for ( ButtonType t : alert.getButtonTypes() )
( (Button) pane.lookupButton(t) ).setDefaultButton( t == defBtn );
return alert;
}
用法:
final Alert alert = new Alert(
AlertType.CONFIRMATION, "You sure?", ButtonType.YES, ButtonType.NO );
if ( setDefaultButton( alert, ButtonType.NO ).showAndWait()
.orElse( ButtonType.NO ) == ButtonType.YES ) {
// User selected the non-default yes button
}
自 jdk 8u40 以来,我正在使用新的 javafx.scene.control.Alert
API 来显示确认对话框。在下面的示例中,"Yes" 按钮默认聚焦而不是 "No" 按钮:
public boolean showConfirmDialog(String title, String header, String content, AlertType alertType) {
final Alert alert = new Alert(alertType);
alert.setTitle(title);
alert.setHeaderText(header);
alert.setContentText(content);
alert.getButtonTypes().clear();
alert.getButtonTypes().addAll(ButtonType.YES, ButtonType.NO);
final Optional<ButtonType> result = alert.showAndWait();
return result.get() == ButtonType.YES;
}
而且我不知道如何更改它。
编辑:
这里是 "Yes" 按钮默认聚焦的结果截图:
我不确定以下是否是通常执行此操作的方法,但您可以通过查找按钮并自行设置默认行为来更改默认按钮:
public boolean showConfirmDialog(String title, String header, String content, AlertType alertType) {
final Alert alert = new Alert(alertType);
alert.setTitle(title);
alert.setHeaderText(header);
alert.setContentText(content);
alert.getButtonTypes().clear();
alert.getButtonTypes().addAll(ButtonType.YES, ButtonType.NO);
//Deactivate Defaultbehavior for yes-Button:
Button yesButton = (Button) alert.getDialogPane().lookupButton( ButtonType.YES );
yesButton.setDefaultButton( false );
//Activate Defaultbehavior for no-Button:
Button noButton = (Button) alert.getDialogPane().lookupButton( ButtonType.NO );
noButton.setDefaultButton( true );
final Optional<ButtonType> result = alert.showAndWait();
return result.get() == ButtonType.YES;
}
如果你看一下 (private) ButtonBarSkin
class,有一个名为 doButtonOrderLayout()
的方法执行按钮的布局,基于一些默认值 OS 行为。
在里面,你可以读到:
/* now that all buttons have been placed, we need to ensure focus is set on the correct button. [...] If so, we request focus onto this default button. */
由于 ButtonType.YES
是默认按钮,它将成为焦点。
所以@ymene 的回答是正确的:您可以更改默认行为,然后焦点将是 NO
。
或者您可以通过在 buttonOrderProperty()
中设置 BUTTON_ORDER_NONE
来避免使用该方法。现在第一个按钮将获得焦点,因此您需要先放置 NO
按钮。
alert.getButtonTypes().setAll(ButtonType.NO, ButtonType.YES);
ButtonBar buttonBar=(ButtonBar)alert.getDialogPane().lookup(".button-bar");
buttonBar.setButtonOrder(ButtonBar.BUTTON_ORDER_NONE);
请注意 YES
仍将具有默认行为:这意味着 NO
可以使用 space 栏(聚焦按钮)进行选择,而 YES
将是如果按回车键(默认按钮),则选中。
或者您也可以更改@crusam 回答后的默认行为。
感谢 crusam 的简单功能:
private static Alert setDefaultButton ( Alert alert, ButtonType defBtn ) {
DialogPane pane = alert.getDialogPane();
for ( ButtonType t : alert.getButtonTypes() )
( (Button) pane.lookupButton(t) ).setDefaultButton( t == defBtn );
return alert;
}
用法:
final Alert alert = new Alert(
AlertType.CONFIRMATION, "You sure?", ButtonType.YES, ButtonType.NO );
if ( setDefaultButton( alert, ButtonType.NO ).showAndWait()
.orElse( ButtonType.NO ) == ButtonType.YES ) {
// User selected the non-default yes button
}