JavaFX线程问题

JavaFX线程问题,java,multithreading,javafx,nullpointerexception,scenebuilder,Java,Multithreading,Javafx,Nullpointerexception,Scenebuilder,我正在使用线程来解决GUI冻结的问题。但对于线程,我面临一个问题,即我无法在run方法中将报表格式作为参数传递,甚至在构造函数的帮助下,我也无法这样做 public class BirtReportExportCon implements Runnable { @FXML Button exportButton; @FXML CheckBox pdfCheckBox; @FXML CheckBox xlsCheckBox; @FXM

我正在使用线程来解决GUI冻结的问题。但对于线程,我面临一个问题,即我无法在run方法中将报表格式作为参数传递,甚至在构造函数的帮助下,我也无法这样做

public class BirtReportExportCon implements Runnable {

    @FXML
    Button exportButton;

    @FXML
    CheckBox pdfCheckBox;

    @FXML
    CheckBox xlsCheckBox;

    @FXML
    CheckBox docCheckBox;

    @FXML
    CheckBox mailCheckBox;

    public String fileFormat;
允许在Gui上选中单个复选框

    public void eventCheckBoxPdf() {
        if (pdfCheckBox.isSelected() == true) {
            xlsCheckBox.setSelected(false);
            docCheckBox.setSelected(false);
        }
    }

    public void eventCheckBoxXls() {
        if (xlsCheckBox.isSelected() == true) {
            pdfCheckBox.setSelected(false);
            docCheckBox.setSelected(false);
        }
    }

    public void eventCheckBoxDoc() {
        if (docCheckBox.isSelected() == true) {
            pdfCheckBox.setSelected(false);
            xlsCheckBox.setSelected(false);
        }
    }
提供所选的文件格式

    public void onButtonClick() throws EngineException {

        if (docCheckBox.isSelected() == true) {
            fileFormat = "docx"; // I WANT THIS FILE FORMAT IN MY RUN METHOD
            Runnable r = new BirtReportExportCon();
            new Thread(r).start();

        }

        else if (pdfCheckBox.isSelected() == true) {
            fileFormat = "pdf";
            Runnable r = new BirtReportExportCon();
            new Thread(r).start();
        }

        else if (xlsCheckBox.isSelected() == true) {
            fileFormat = "xls";
            Runnable r = new BirtReportExportCon();
            new Thread(r).start();
        }
    }
运行方法

    public void run()
    {
        try
        {
            exportFile(fileFormat); // HERE I WANT THAT SO I CAN ABLE TO CREATE REPORT OF REQUIRED FORMAT
        }
        catch (EngineException e) {
            e.printStackTrace();
        }
    }
保存报告并打开报告

    public void exportFile(String fileFormat) throws EngineException {

        String output = "output path";
        String reportDesignFilePath = "report path";


        try {
            EngineConfig configure = new EngineConfig();
            Platform.startup(configure);
            IReportEngineFactory reportEngineFactory = (IReportEngineFactory) Platform
                    .createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
            IReportEngine engine = reportEngineFactory.createReportEngine(configure);
            engine.changeLogLevel(Level.WARNING);
            IReportRunnable runnable = engine.openReportDesign(reportDesignFilePath);
            IRunAndRenderTask task = engine.createRunAndRenderTask(runnable);
            IRenderOption option = new PDFRenderOption();
            option.setOutputFormat(fileFormat);
            option.setOutputFileName(output + fileFormat);
            task.setRenderOption(option);
            task.run();
            task.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // Open Created File
        File fileOpen = new File(output + fileFormat);
        if (fileOpen.exists()) {
            if (Desktop.isDesktopSupported()) {
                try {
                    Desktop desktop = Desktop.getDesktop();
                    desktop.open(fileOpen);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

试着这样做:

if ( docCheckBox.isSelected() == true ) {
    BirtReportExportCon r = new BirtReportExportCon();
    r.fileFormat = "docx"; // I WANT THIS FILE FORMAT IN MY RUN METHOD
    new Thread(r).start();
}

我也有类似的问题。我认为问题在于文件开放阶段。您正在使用的Desktop类来自java.awt包。当您使用Desktop类时,JAVAFX线程会被阻塞,正如用户在回答底部给出的链接中所评论的那样。但是该用户的声誉很低(只有11),因此我们不能依赖他

要使应用程序解冻,必须创建一个新线程。 这是我的代码的一部分,我在我的应用程序中使用过,这段代码工作得非常好。我还添加了一个链接,指向我的应用程序中的一个github问题,在那里我说明了冻结问题,类似于您的问题。该问题是2天前创建的

@FXML
    void openWithAction(ActionEvent event) {
        boolean flag = false;
        Task task = new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                try {
                    Desktop.getDesktop().open(new File(fileModel.getFileLocation()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }
        };
        new Thread(task).start();
    }
@FXML
作废openWithAction(ActionEvent事件){
布尔标志=假;
任务=新任务(){
@凌驾
受保护的Void调用()引发异常{
试一试{
打开(新文件(fileModel.getFileLocation());
}捕获(IOE异常){
e、 printStackTrace();
}
返回null;
}
};
新线程(任务).start();
}
Github问题链接:

我还建议您使用JavaFX提供的并发性。 这里是另一个SO post链接。希望这有帮助。


编辑:如果我不理解你的问题,我很抱歉。是关于应用程序冻结、无法传递参数或由于应用程序冻结而无法传递参数的问题。

您应该在Swing线程上运行此代码,而不是从Java FX线程调用它。例如:

@FXML
    void openWithAction(ActionEvent event) {
        SwingUtilities.invokeLater( () -> Desktop.getDesktop().
                                          open(new File(fileModel.
                                                  getFileLocation())));
    }

错误:无法解析文件格式,或者文件格式不是一个响应,因为我陷入了这个问题。非常感谢您的帮助。编辑了答案。有帮助吗?如果是,实际问题是我无法在线程的run方法中传递参数。但是现在问题已经解决了,我期待着优化代码如果答案帮助或解决了问题,那么请投票或接受我的答案。还有一个问题……我正在使用任务填充我的进度条,该进度条会引发此代码的异常……所以,我想在不使用task的情况下填充进度栏……并想在此程序中运行进度栏……您能帮我解决此问题吗?如果您的项目在github中是公开的,那么您可以与我共享,或者尝试在SO中询问其他问题。我们不能在这里讨论另一个问题。我会尽力帮忙的。