[英]Can't change initModality of an Alert window in JavaFX
在JavaFX(11)中,我试图在主窗口上方显示一个警告窗口,但我不希望主窗口可以被点击。 为此,我认为我必须更改该警报窗口的initModality( https://docs.oracle.com/javafx/2/api/javafx/stage/Stage.html请参阅'模态')。 它不起作用,因为警报窗口的所有者为空?
这是我的控制器类。 主类只是IntelliJ IDEA生成的默认JavaFX Main类,而.fxml文件只是一个带有按钮的锚定板,用于测试目的。
package sample;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.stage.Modality;
public class Controller {
public Button button;
public void initialize(){
Alert alert = new Alert(Alert.AlertType.ERROR);
System.out.println(alert.getOwner()); //output: null
alert.initModality(Modality.APPLICATION_MODAL);
alert.setHeight(200);
alert.setWidth(300);
alert.show();
button.setOnAction(push -> System.out.println("button pressed")); //button is still pressable
}
}
主窗口中的按钮仍然可以按下,因此initModality不起作用。 我也尝试使用Modality.WINDOW_MODAL
和Modality.NONE
,没有变化。
如果重要的话,我在Linux上使用bspwm。
我认为问题在于窗口的显示顺序。 使用以下内容对此进行测试再现了Windows 10上的问题(使用JavaFX 12.0.1):
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
var alert = new Alert(AlertType.INFORMATION);
alert.initModality(Modality.APPLICATION_MODAL);
alert.setHeaderText(null);
alert.setContentText("This is a test of application modality.");
alert.show();
primaryStage.setScene(new Scene(new StackPane(new Label("Hello, World!")), 500, 300));
primaryStage.show();
}
}
上面的结果是一个不正确模态的对话窗口。 但是,如果移动alert.show()
后 primaryStage.show()
一切正常。
由于您在FXML控制器的initialize()
方法中显示Alert
,因此在显示主窗口之前可能正在执行代码。 如果要在应用程序开头显示Alert
,则至少有两个选项:
在您的回答中调用Platform.runLater
调用中的show()
。
向Controller
类添加一个方法,并在显示另一个窗口后调用它。
@Override public void start(Stage primaryStage) throws IOException { FXMLLoader loader = new FXMLLoader(/*location*/); primaryStage.setScene(new Scene(loader.load())); primaryStage.show(); loader.<Controller>getController().showMyAwesomeAlert(); }
我通过将警报代码放在Platform.runLater()
方法中来修复它,如下所示:
public void initialize(){
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.initModality(Modality.APPLICATION_MODAL);
alert.setHeight(200);
alert.setWidth(300);
Platform.runLater(alert::show());
button.setOnAction(push -> {
System.out.println("button pressed");
});
}
主窗口现在不是交互式的,就像我想要的那样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.