JavaFX线程问题

JavaFX thread issue

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

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

我遇到过类似的问题。我认为问题出在 fileOpening 阶段。您使用的桌面 class 来自 java.awt package.When 您使用桌面 class 然后 JAVAFX 线程被阻止,正如用户在给定的 link 中评论的那样在这个答案的底部。但是用户的声誉很低(只有 11)所以我们不能依赖他。

要使您的应用程序解冻,您必须创建一个新线程。 这是我的代码的一部分,我在我的应用程序中使用过,这段代码运行良好。我还在我的应用程序的 github 问题中添加了 link 问题,其中我说明了冻结问题,类似于您的问题。该问题创建于 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 问题 link: https://github.com/karanpant/SearchEverything/issues/3

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

编辑: 如果我不明白您的问题,我深表歉意。您的问题是关于应用程序冻结或关于无法传递参数或由于应用程序冻结而无法传递参数。

您应该在 Swing 线程上 运行 这段代码,而不是从 Java FX 线程调用它。像下面这样:

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