JavaFX - 阻止用户在不使用MODAL的情况下更改阶段

时间:2016-06-15 00:31:03

标签: java javafx

我的应用程序如下所示:

enter image description here

当用户点击卡片组时,它会打开一个新的舞台。

此阶段可以通过以下两种方式之一关闭:

  • 右键单击舞台。

  • 点击舞台外面(当它失去焦点时它有一个偶数处理器。)

然而,有时我需要用户使用此窗口从卡座中选择一张或多张卡片。在他选择至少一张卡片之前,我不想让他关上窗户。这意味着我必须使用MODAL来阻止他访问下面的舞台(我的应用程序)。现在MODAL的问题是,即使我希望他能够在舞台外点击,他也永远不会像往常一样离开窗户。他现在只能通过右键单击离开。我可以添加一个按钮,但我真的不愿意。

我希望我能很好地解释我的问题。你们会推荐我做什么?有没有办法阻止用户在没有MODAL的情况下返回上一阶段?在演出舞台后,我也无法更改Modality,因此无效。

谢谢!

1 个答案:

答案 0 :(得分:2)

我们的想法是使用弹出窗口Stage的{​​{3}}属性。

  

当有外部请求关闭此窗口时调用。该   安装事件处理程序可以通过使用来阻止窗口关闭   收到了活动。

使用此属性,如果通过调用Stage上的onCloseRequestProperty无法满足条件(在您的情况下至少选择一张卡),则可以中断WindowEvent的结束。

注意:正如文档所述:它仅在请求为外部时有效,因此如果您调用{{1}的consume方法,附加的侦听器将不会被执行。作为解决方案而不是调用此方法,您可以手动触发close事件。

示例:

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); } } 不可用,我已添加以下行:

Stage

这将在弹出阶段显示时禁用根root.disableProperty().bind(popupStage.showingProperty()); 。弹出窗口关闭后,主窗口将再次启用。