我的应用程序如下所示:
当用户点击卡片组时,它会打开一个新的舞台。
此阶段可以通过以下两种方式之一关闭:
右键单击舞台。
点击舞台外面(当它失去焦点时它有一个偶数处理器。)
然而,有时我需要用户使用此窗口从卡座中选择一张或多张卡片。在他选择至少一张卡片之前,我不想让他关上窗户。这意味着我必须使用MODAL
来阻止他访问下面的舞台(我的应用程序)。现在MODAL
的问题是,即使我希望他能够在舞台外点击,他也永远不会像往常一样离开窗户。他现在只能通过右键单击离开。我可以添加一个按钮,但我真的不愿意。
我希望我能很好地解释我的问题。你们会推荐我做什么?有没有办法阻止用户在没有MODAL
的情况下返回上一阶段?在演出舞台后,我也无法更改Modality
,因此无效。
谢谢!
答案 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());
。弹出窗口关闭后,主窗口将再次启用。