Skip to content

Commit

Permalink
Fix focus handling in DialogPane
Browse files Browse the repository at this point in the history
Replaced direct focus requests with Platform.runLater to ensure correct focus behavior. Consolidated button type settings into fewer cases and addressed focus issues in input dialogs to prevent buttons from stealing focus.
  • Loading branch information
dlemmermann committed Nov 12, 2024
1 parent ca74028 commit a5c14ac
Showing 1 changed file with 21 additions and 13 deletions.
34 changes: 21 additions & 13 deletions gemsfx/src/main/java/com/dlsc/gemsfx/DialogPane.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import javafx.animation.KeyValue;
import javafx.animation.RotateTransition;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
Expand Down Expand Up @@ -416,7 +417,7 @@ public final Dialog<Void> showError(String title, String message, String details
* @param title the title for the dialog
* @param message the main error message
* @param details additional details
* @param onSend an optional action to send out / forward the error message
* @param onSend an optional action to send out / forward the error message
* @return the dialog
*/
public final Dialog<Void> showError(String title, String message, String details, Runnable onSend) {
Expand Down Expand Up @@ -456,8 +457,6 @@ public final Dialog<Void> showError(String title, String message, String details
VBox content = new VBox(messageLabel, textArea);
content.getStyleClass().add("error-container");
dialog.setContent(content);

FocusUtil.requestFocus(textArea);
}

dialog.show();
Expand Down Expand Up @@ -625,7 +624,9 @@ public final Dialog<String> showTextInput(String title, String message, String p
textInputControl = textField;
}

FocusUtil.requestFocus(textInputControl);
// FocusUtil.requestFocus(textInputControl);

Platform.runLater(textInputControl::requestFocus);

VBox box = new VBox();
box.getStyleClass().add("prompt-node-wrapper");
Expand Down Expand Up @@ -1100,12 +1101,9 @@ public Dialog(DialogPane pane, Type type) {
case WARNING:
getButtonTypes().setAll(ButtonType.OK, ButtonType.CANCEL);
break;
case INFORMATION:
case INFORMATION, ERROR:
getButtonTypes().setAll(ButtonType.OK);
break;
case ERROR:
getButtonTypes().setAll(ButtonType.CLOSE);
break;
case CONFIRMATION:
getButtonTypes().setAll(ButtonType.YES, ButtonType.NO);
break;
Expand Down Expand Up @@ -1772,7 +1770,16 @@ private class ContentPane extends StackPane {
private final ChangeListener<Node> focusListener = (o, oldOwner, newOwner) -> {
if (newOwner != null && !isInsideDialogPane(newOwner.getParent()) && getScene() != null) {
if (oldOwner != null && isInsideDialogPane(oldOwner.getParent())) {
oldOwner.requestFocus();
if (getDialog().getType().equals(Type.INPUT)) {
Node node = FocusUtil.findFirstFocusableNode(getDialog().getContent());
if (node != null) {
node.requestFocus();
} else {
oldOwner.requestFocus();
}
} else {
oldOwner.requestFocus();
}
} else {
requestFocus();
}
Expand Down Expand Up @@ -1977,10 +1984,11 @@ public static class DialogButtonBar extends ButtonBar {
public DialogButtonBar(Dialog<?> dialog) {
this.dialog = dialog;

// Setting the skin eagerly to make sure the focus does not
// switch to one of the buttons in the button bar when it
// should stay with a node shown by the dialog.
setSkin(new ButtonBarSkin(this));
if (dialog.getType().equals(Type.INPUT)) {
// initializing skin early or the skin will grab the focus later on for one of its buttons instead of
// leaving it with the control used for the input
setSkin(new ButtonBarSkin(this));
}

getStyleClass().add("footer");

Expand Down

0 comments on commit a5c14ac

Please sign in to comment.