ポップアップStage
のonCloseRequestPropertyプロパティを使用することです。
このウィンドウを閉じる外部要求があるときに呼び出されます。 イベントハンドラがインストールされていると、 受信イベントを消費してウィンドウが閉じることを防ぐことができます。条件(LEST一枚のカードで、あなたのケースでは、選択されている)場合は、Stage
の閉鎖を中断することができます。このプロパティを使用して
はWindowEvent
にconsumeを呼び出すことによって満たされていません。
注:ドキュメントの状態として:あなたはStage
のcloseメソッドを呼び出した場合、添付のリスナーが実行されないことになるので、要求は、外部にある場合にのみ有効です。このメソッドを呼び出すのではなく、解決策としてWindowEvent.WINDOW_CLOSE_REQUESTイベントを手動で起動することができます。一方、これはルートBorderPane
が無効になります
root.disableProperty().bind(popupStage.showingProperty());
:私は、この行を追加した主なStage
が使用できないようにするに
:
例:
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);
}
}
更新ポップアップステージが表示されます。ポップアップウィンドウが閉じられるとすぐに、メインウィンドウが再度有効になります。
ありがとうございます。私はこの種の機能のためにonCloseRequestを使うことはできないと思っていました。しかし、ここには大きな問題がある。 「モダリティ」なしでは、ユーザは、ポップアップ段階があるにもかかわらず、依然としてアプリケーションの残りの部分と通信することが許可される。彼らはデッキを50回クリックして50の窓を作った。私の現在のアイデアは、メインのGUIクラスに静的なブール変数を持たせることです。これは "現在表示されているウィンドウですか?"その変数がtrueの場合、プライマリステージでイベントハンドラを有効にしないでください。しかし、それは一種の痛みです。他のアイデア? – Hatefiend
答えの私の更新を見てください。 – DVarga
最後に一つだけ。私は6つのユニークなウィンドウが表示され、このように非表示になり、私はそれらのすべての6つのようにバインドする必要があります。今すぐ '.bind()'を呼び出すと、前の 'bind'を上書きし、正しくバインドされた最後のプロパティだけが、無効なプロパティに影響を与えます。どのように私は複数をバインドできますか? – Hatefiend