Can';t更改JavaFX中警报窗口的初始模式
在JavaFX(11)中,我试图在主窗口上方显示一个警报窗口,但我不希望主窗口可以单击。要做到这一点,我认为我必须更改该警报窗口的初始模式(请参阅“模式”)。它是否因为警报窗口的所有者为空而不起作用 这是我的控制器类。main类只是IntelliJ IDEA生成的默认JavaFX主类,.fxml文件只是一个带有按钮的锚机,用于测试Can';t更改JavaFX中警报窗口的初始模式,java,javafx,java-11,Java,Javafx,Java 11,在JavaFX(11)中,我试图在主窗口上方显示一个警报窗口,但我不希望主窗口可以单击。要做到这一点,我认为我必须更改该警报窗口的初始模式(请参阅“模式”)。它是否因为警报窗口的所有者为空而不起作用 这是我的控制器类。main类只是IntelliJ IDEA生成的默认JavaFX主类,.fxml文件只是一个带有按钮的锚机,用于测试 package sample; import javafx.scene.control.Alert; import javafx.scene.control.But
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无法工作。我还尝试了模态.WINDOW\u模态
和模态。无
,无变化
如果有必要的话,我使用bspwm在Linux上运行。我通过将警报代码放入
平台来修复它。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");
});
}
主窗口现在不是交互式的,正如我所希望的。我认为问题在于窗口的显示顺序。在Windows 10(使用JavaFX 12.0.1)上通过以下测试重现了该问题: 上面的结果是对话框窗口不是正确的模态。但是,如果将
alert.show()
移动到primaryStage.show()
之后,一切都会正常工作
由于您正在FXML控制器的initialize()
方法中显示您的警报
,因此代码很可能是在显示主窗口之前执行的。如果要在应用程序开始时显示警报
,至少有两个选项:
平台内调用show()
。稍后运行调用,就像在中一样
- 这样做的缺点是,它使您的代码高度依赖于看似无关的代码。例如,如果出于任何原因更改主窗口的显示方式和时间,则此选项可能会中断
控制器
类添加一个方法,并在显示其他窗口后调用它
@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();
}
@覆盖
公共无效开始(阶段primaryStage)引发IOException{
FXMLLoader=新的FXMLLoader(/*位置*/);
setScene(新场景(loader.load());
primaryStage.show();
loader.getController().showMyAwesomeAlert();
}
我想这是因为您的
警报最终显示在另一个窗口之前。这是因为我在initialize()方法中运行了代码吗?如何确保警报窗口在应用程序启动后立即打开?谢谢,我将使用第二个选项。
@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();
}