JavaFX线程问题

时间:2017-07-17 09:48:41

标签: java multithreading javafx nullpointerexception scenebuilder

我正在使用线程来解决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上检查单个CheckBox

    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);
        }
    }

提供选择的fileFormat

    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();
                }
            }
        }
    }

3 个答案:

答案 0 :(得分:0)

尝试这样的事情:

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

答案 1 :(得分:0)

我有类似的问题。我认为问题出在fileOpening阶段。您正在使用的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();
    }

Github问题链接: 的 https://github.com/karanpant/SearchEverything/issues/3

我还建议您使用JavaFX提供的并发性。 这是另一个SO帖子链接。希望这可以帮助。 JavaFX Freeze on Desktop.open(file), Desktop.browse(uri)

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

答案 2 :(得分:0)

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

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