窗口如何获得焦点取决于平台(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
关系而不初始化真正的所有者。
Source:
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();
}
}
}
Usage:
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 来过滤焦点事件,但您将面临纯粹的架构邪恶:)