繁体   English   中英

Java FX:无法从其他FX线程打开弹出窗口

[英]Java FX : Unable to open popup from different FX thread

嗨,我有同时在GUI(Java FX)和命令行上运行的应用程序。 当以GUI运行时,我在文本区域上显示状态。 这很好。

但是问题是,当我尝试通过某些不同的类(非javafx)显示错误(通过弹出窗口)时,它向我显示Java Fx-线程异常不在FX线程上。

下面是我的代码

这是我希望显示弹出窗口的Java FX类。

public class DeploymentProcesController implements Initializable {


@FXML
private TextArea statusTextArea;

@Override
public void initialize(URL location, ResourceBundle resources) {

}

public void updateGUIMessage(String message) {
    if (Platform.isFxApplicationThread()) {
        statusTextArea.appendText(message);
    } else {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                statusTextArea.appendText(message);
            }
        });
    }
}

public void displayAlertMessages(final String message) {
    Platform.setImplicitExit(false);
    Task<Void> task = new Task<Void>() {
        @Override public Void call() {
            Platform.runLater(new Runnable() {
                public void run() {
                    Alert alert = new Alert(AlertType.INFORMATION, message, ButtonType.OK);
                    alert.showAndWait();
                }
            });

            return null;
        }
    };
    new Thread(task).start();
}

}

我有一个非FX类,这是切入点。 因此,根据运行类型(命令行/ GUI),我更新了状态。

这是我打电话来更新状态的方式。

public void promptUser(String message,boolean isCommandLineRun){
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    if(isCommandLineRun) {
        System.out.println(simpleDateFormat.format(new Date()) + " - " + message);
    } else {
        controller.displayAlertMessages(message);
    }
}

从非fx类调用updateGUIMessage方法时,我没有任何问题。 这是因为statusArea元素位于FX线程上(此fx类的成员)。

我也没有在单击某些按钮时生成警报框的问题,而是要显示其他类别的警报框-我遇到问题,因为一旦尝试生成警报框,应用程序就会崩溃,并说不在fx上线。

我了解“警报”框是一个弹出窗口,因此可能未处理。 但是任何人都可以帮助我,我想向用户显示不同类别的警报框。

UI中的所有内容都必须从UI应用程序线程执行。 这正是错误消息的含义。

幸运的是,您可以简单地包装您的调用,以便在UI线程中执行该调用:

if(isCommandLineRun) {
    System.out.println(simpleDateFormat.format(new Date()) + " - " + message);
} else {
    Platform.runLater(() -> controller.displayAlertMessages(message));
}

终于找到了解决方案,

由于Java fx在单线程上运行,因此所有内容都必须在同一线程上。 对于需要背景暂停的每个任务(例如弹出窗口),我们需要使用FutureTask。

我在这里找到了这篇文章:

JavaFX2:我可以暂停后台任务/服务吗?

假设您要在调用弹出窗口之前运行一些长时间运行的代码,处理Fx按钮时需要完成两个步骤。 当按下按钮时,第一个线程使代码作为线程运行。 第二个是Platform.runlater(),它告诉Fx Platform从Platform执行该线程中的代码。 请注意,直到在外部线程中达到runlater后,才会执行弹出窗口。 否则,您可以直接调用弹出窗口。

public void MyExampleBtn() {
  Thread t = new Thread() {
    // long running work to be done, threaded so as not to hang the main controls.
    // .... 
    // work is done do the success popup
    @Override
      public void run() {
      Platform.runLater(new Runnable() {
       @Override
         public void run() {
           Alert alert = new Alert(AlertType.INFORMATION);
           alert.setTitle("Success!");
           alert.setHeaderText(null);
           alert.setContentText("This is my popup");
           alert.showAndWait();
         }
       });
     }
   };
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM