gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 02:53:52 30 4
gpt4 key购买 nike

我有一个如下所示的应用程序:

enter image description here

当用户单击这副牌时,它会打开一个新的舞台。

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

  • 右键单击舞台。

  • 在舞台外部单击(当失去焦点时它有一个事件处理程序)。

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

我希望我能很好地解释我的问题。你们会建议我做什么?有没有办法可以在没有 MODAL 的情况下以某种方式阻止用户返回上一阶段?在舞台显示后,我也无法更改Modality,因此这不起作用。

谢谢!

最佳答案

这个想法是使用 onCloseRequestProperty弹出 Stage 的属性。

Called when there is an external request to close this Window. The installed event handler can prevent window closing by consuming the received event.

使用此属性,如果不满足条件(在您的情况下至少选择一张卡),您可以通过调用 consume 来中断 Stage 的关闭。在 WindowEvent 上。

注意:正如文档所述:仅当请求是外部时才有效,因此如果您调用 close Stage 的方法,附加的监听器将不会被执行。作为解决方案,您可以触发 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。弹出窗口关闭后,主窗口将再次启用。

关于JavaFX - 阻止用户在不使用 MODAL 的情况下更改阶段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37824263/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com