diff --git a/modules/controls/src/main/java/javafx/scene/control/ControlUtils.java b/modules/controls/src/main/java/javafx/scene/control/ControlUtils.java --- a/modules/controls/src/main/java/javafx/scene/control/ControlUtils.java +++ b/modules/controls/src/main/java/javafx/scene/control/ControlUtils.java @@ -29,6 +29,9 @@ import javafx.beans.Observable; import javafx.collections.ObservableMap; import javafx.event.Event; +import javafx.scene.Node; +import javafx.scene.Parent; +import javafx.scene.Scene; class ControlUtils { private static final String SCROLL_TO_INDEX_KEY = "util.scroll.index"; @@ -95,4 +98,21 @@ private static void fireScrollToColumnEvent(final Control control, final TableColumnBase column) { control.fireEvent(new ScrollToEvent>(control, control, ScrollToEvent.scrollToColumn(), column)); } + + static void requestFocusOnControlOnlyIfCurrentFocusOwnerIsChild(Control c) { + Scene scene = c.getScene(); + final Node focusOwner = scene == null ? null : scene.getFocusOwner(); + if (focusOwner == null) { + c.requestFocus(); + } else if (! c.equals(focusOwner)) { + Parent p = focusOwner.getParent(); + while (p != null) { + if (c.equals(p)) { + c.requestFocus(); + break; + } + p = p.getParent(); + } + } + } } diff --git a/modules/controls/src/main/java/javafx/scene/control/ListCell.java b/modules/controls/src/main/java/javafx/scene/control/ListCell.java --- a/modules/controls/src/main/java/javafx/scene/control/ListCell.java +++ b/modules/controls/src/main/java/javafx/scene/control/ListCell.java @@ -38,6 +38,10 @@ import javafx.collections.ObservableList; import javafx.collections.WeakListChangeListener; +import javafx.scene.Node; +import javafx.scene.Parent; +import javafx.scene.Scene; + import java.lang.ref.WeakReference; import java.util.List; @@ -362,7 +366,7 @@ @Override public void commitEdit(T newValue) { if (! isEditing()) return; ListView list = getListView(); - + if (list != null) { // Inform the ListView of the edit being ready to be committed. list.fireEvent(new ListView.EditEvent(list, @@ -387,7 +391,12 @@ // the ListView editingIndex property (if they choose to do that // rather than just grab the int from the event). list.edit(-1); - list.requestFocus(); + + // request focus back onto the list, only if the current focus + // owner has the list as a parent (otherwise the user might have + // clicked out of the list entirely and given focus to something else. + // It would be rude of us to request it back again. + ControlUtils.requestFocusOnControlOnlyIfCurrentFocusOwnerIsChild(list); } } @@ -405,7 +414,12 @@ // reset the editing index on the ListView if (updateEditingIndex) list.edit(-1); - list.requestFocus(); + + // request focus back onto the list, only if the current focus + // owner has the list as a parent (otherwise the user might have + // clicked out of the list entirely and given focus to something else. + // It would be rude of us to request it back again. + ControlUtils.requestFocusOnControlOnlyIfCurrentFocusOwnerIsChild(list); list.fireEvent(new ListView.EditEvent(list, ListView.editCancelEvent(), diff --git a/modules/controls/src/main/java/javafx/scene/control/TableCell.java b/modules/controls/src/main/java/javafx/scene/control/TableCell.java --- a/modules/controls/src/main/java/javafx/scene/control/TableCell.java +++ b/modules/controls/src/main/java/javafx/scene/control/TableCell.java @@ -337,7 +337,12 @@ if (table != null) { // reset the editing cell on the TableView table.edit(-1, null); - table.requestFocus(); + + // request focus back onto the table, only if the current focus + // owner has the table as a parent (otherwise the user might have + // clicked out of the table entirely and given focus to something else. + // It would be rude of us to request it back again. + ControlUtils.requestFocusOnControlOnlyIfCurrentFocusOwnerIsChild(table); } } @@ -354,7 +359,11 @@ TablePosition editingCell = table.getEditingCell(); if (updateEditingIndex) table.edit(-1, null); - table.requestFocus(); + // request focus back onto the table, only if the current focus + // owner has the table as a parent (otherwise the user might have + // clicked out of the table entirely and given focus to something else. + // It would be rude of us to request it back again. + ControlUtils.requestFocusOnControlOnlyIfCurrentFocusOwnerIsChild(table); CellEditEvent editEvent = new CellEditEvent( table, diff --git a/modules/controls/src/main/java/javafx/scene/control/TreeCell.java b/modules/controls/src/main/java/javafx/scene/control/TreeCell.java --- a/modules/controls/src/main/java/javafx/scene/control/TreeCell.java +++ b/modules/controls/src/main/java/javafx/scene/control/TreeCell.java @@ -407,7 +407,12 @@ if (tree != null) { // reset the editing item in the TreetView tree.edit(null); - tree.requestFocus(); + + // request focus back onto the tree, only if the current focus + // owner has the tree as a parent (otherwise the user might have + // clicked out of the tree entirely and given focus to something else. + // It would be rude of us to request it back again. + ControlUtils.requestFocusOnControlOnlyIfCurrentFocusOwnerIsChild(tree); } } @@ -422,7 +427,12 @@ if (tree != null) { // reset the editing index on the TreeView if (updateEditingIndex) tree.edit(null); - tree.requestFocus(); + + // request focus back onto the tree, only if the current focus + // owner has the tree as a parent (otherwise the user might have + // clicked out of the tree entirely and given focus to something else. + // It would be rude of us to request it back again. + ControlUtils.requestFocusOnControlOnlyIfCurrentFocusOwnerIsChild(tree); tree.fireEvent(new TreeView.EditEvent(tree, TreeView.editCancelEvent(), diff --git a/modules/controls/src/main/java/javafx/scene/control/TreeTableCell.java b/modules/controls/src/main/java/javafx/scene/control/TreeTableCell.java --- a/modules/controls/src/main/java/javafx/scene/control/TreeTableCell.java +++ b/modules/controls/src/main/java/javafx/scene/control/TreeTableCell.java @@ -335,7 +335,12 @@ if (table != null) { // reset the editing cell on the TableView table.edit(-1, null); - table.requestFocus(); + + // request focus back onto the table, only if the current focus + // owner has the table as a parent (otherwise the user might have + // clicked out of the table entirely and given focus to something else. + // It would be rude of us to request it back again. + ControlUtils.requestFocusOnControlOnlyIfCurrentFocusOwnerIsChild(table); } } @@ -354,7 +359,11 @@ if (updateEditingIndex) table.edit(-1, null); - table.requestFocus(); + // request focus back onto the table, only if the current focus + // owner has the table as a parent (otherwise the user might have + // clicked out of the table entirely and given focus to something else. + // It would be rude of us to request it back again. + ControlUtils.requestFocusOnControlOnlyIfCurrentFocusOwnerIsChild(table); CellEditEvent editEvent = new CellEditEvent( table,