這個想法是使用彈出的Stage
的onCloseRequestProperty屬性。
當有外部請求關閉此窗口時調用。安裝的事件處理程序可以通過使用收到的事件來阻止窗口關閉。
有了這個屬性,你可以中斷Stage
閉幕如果(被選中的一個,以免卡在你的情況下)的條件不被在WindowEvent
調用consume滿足。
注:由於文檔狀態:它是唯一有效的,如果請求外部,所以如果你調用Stage
的close方法,附加的監聽器將不執行。作爲一種解決方案而不是調用此方法,您可以手動激發WindowEvent.WINDOW_CLOSE_REQUEST事件。
例子:
public class PopUpApp extends Application {
Stage popupStage;
Stage primaryStage;
@Override
public void start(Stage stage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 400, 400);
primaryStage = stage;
initPopUpStage();
// When the Pop-Up stage is showing, do not handle any action on the
// main GUI
root.disableProperty().bind(popupStage.showingProperty());
Button b = new Button("Open deck");
b.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
// Add some ToggleButtons to simulate the cards
VBox vbox = new VBox();
vbox.setAlignment(Pos.CENTER);
List<ToggleButton> toggles = new ArrayList<ToggleButton>();
for (int i = 0; i < 4; i++) {
ToggleButton tb = new ToggleButton("Card " + i + 1);
toggles.add(tb);
}
vbox.getChildren().addAll(toggles);
Scene sc = new Scene(vbox, 300, 300);
popupStage.setScene(sc);
// On close request check for the condition
popupStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent event) {
Boolean readytoClose = false;
for (ToggleButton toggle : toggles) {
if (toggle.isSelected()) {
readytoClose = true;
break;
}
}
// Consume the event a show a dialog
if (!readytoClose) {
event.consume();
Alert alert = new Alert(AlertType.INFORMATION,
"At least one card has be to be selected!");
alert.showAndWait();
}
}
});
popupStage.show();
}
});
root.setCenter(b);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
private void initPopUpStage() {
popupStage = new Stage();
popupStage.initOwner(primaryStage);
popupStage.initStyle(StageStyle.UNDECORATED);
// On focus loss, close the window
popupStage.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
// Rather than popupStage.close(); fire the event manually
if (!newValue)
popupStage.fireEvent(new WindowEvent(popupStage, WindowEvent.WINDOW_CLOSE_REQUEST));
}
});
}
public static void main(String[] args) {
launch(args);
}
}
更新:
將主Stage
不可用我已經加入這一行:
root.disableProperty().bind(popupStage.showingProperty());
這將禁用根BorderPane
而彈出式舞臺正在顯示。只要彈出窗口關閉,主窗口就會再次啓用。
非常感謝。我不知道我可以使用onCloseRequest來實現這種功能。儘管如此,這是一個巨大的問題。如果沒有'Modality',儘管存在彈出階段,用戶仍然可以與應用程序的其餘部分進行通信。他們可以點擊甲板50次,並製作50個窗戶。我目前的想法是在我的主要GUI類中有一個靜態布爾變量,它說「是當前顯示的窗口?」。如果該變量爲真,則不允許在主要階段激活任何事件處理程序。然而,這是一種痛苦。任何其他想法? – Hatefiend
請在答案中查看我的更新。 – DVarga
太棒了。最後一件事。我有六個獨特的窗口將顯示和隱藏像這樣,我需要所有六個這樣的綁定。現在,如果我調用'.bind()',它會覆蓋前面的'bind',並且只有正確綁定的最後一個屬性會影響禁用的屬性。我怎樣才能綁定多個? – Hatefiend