web-dev-qa-db-ja.com

アラートダイアログのJavaFXデフォルトフォーカスボタン

Jdk 8u40以降、新しいjavafx.scene.control.AlertAPIを使用して確認ダイアログを表示しています。以下の例では、「いいえ」ボタンではなく「はい」ボタンがデフォルトでフォーカスされています。

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;
}

そして、私はそれを変更する方法がわかりません。

編集:

これは、「はい」ボタンがデフォルトでフォーカスされている結果のスクリーンショットです。

enter image description here

13
thibault

以下が通常これを行う方法であるかどうかはわかりませんが、ボタンを検索してデフォルトの動作を自分で設定することで、デフォルトのボタンを変更できます。

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;
}
16
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
}
6
Sheepy

(private)ButtonBarSkinクラスを見ると、デフォルトのOSの動作に基づいて、ボタンのレイアウトを実行するdoButtonOrderLayout()というメソッドがあります。

その中で、あなたはこれを読むことができます:

/ *すべてのボタンが配置されたので、正しいボタンにフォーカスが設定されていることを確認する必要があります。 [...]もしそうなら、このデフォルトのボタンにフォーカスを要求します。 * /

_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を選択でき、Enterキーを押すとYESが選択されます(デフォルトボタン)。

Alert dialog

または、@ crusamの回答に続いてデフォルトの動作を変更することもできます。

4
José Pereda