Как окно получает фокус, зависит от платформы (OS + JRE).
Платформа обрабатывает сфокусированное окно, поэтому после вызова фокуса окно может работать по-разному в разных ОС.
Невозможно добиться требуемого поведения с помощью чистого JFX из-за установленного вами ограничения:
Примечание: я не могу удалить initOwner (), так как я всегда хочу держать свое подокно поверх главного окна.
com.sun.javafx.tk.quantum.WindowStage
if (!isPopupStage && owner != null && owner instanceof WindowStage) {
WindowStage ownerStage = (WindowStage)owner;
ownerStage.requestToFront();
}
То, что вы можете сделать, это подражать owner window <- child window
отношениям без инициализации реального владельца.
* Источник: 1017 *
public class PlainZStage extends Stage {
public PlainZStage(final Window owner) {
init(owner, this::focusedChanged);
}
private void init(final Window owner, final ChangeListener<Boolean> listener) {
showingProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(final ObservableValue<? extends Boolean> observable, final Boolean oldValue,
final Boolean newValue) {
owner.getScene().getRoot().setDisable(newValue);
if (newValue) {
owner.focusedProperty().addListener(listener);
} else {
owner.focusedProperty().removeListener(listener);
showingProperty().removeListener(this);
}
}
});
}
private void focusedChanged(final ObservableValue<? extends Boolean> source, final Boolean oldValue,
final Boolean newValue) {
if (newValue && isShowing()) {
toFront();
}
}
}
Использование:
button.setOnAction(e -> {
final Stage stg = new PlainZStage(stage);
stg.setScene(new Scene(new StackPane(), 300, 300));
stg.show();
// Window will close automatically after 10secs.
final Timeline timeline = new Timeline(new KeyFrame(Duration.millis(10000), x -> {
stg.close();
}));
Кроме того, вы можете комбинировать JFX и SWING для фильтрации событий фокуса, но вы столкнетесь с чистым архитектурным злом:)