【问题标题】:JavaFX thread issueJavaFX 线程问题
【发布时间】:2017-07-17 09:48:41
【问题描述】:

我正在使用线程来解决 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();
                }
            }
        }
    }

【问题讨论】:

    标签: java multithreading javafx nullpointerexception scenebuilder


    【解决方案1】:

    我遇到了类似的问题。我认为问题出在 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)

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

    【讨论】:

    • 有帮助吗?如果
    • 是的,实际问题是我无法在线程的运行方法中传递参数。但是这个问题现在已经解决了,我期待着优化代码
    • 如果答案帮助或解决了问题,请投票或接受我的答案。
    • 还有另一个问题............我正在使用任务来填充我的进度条,用这段代码引发异常......所以,我想填充我的进度条没有使用任务.......并且想用这个程序运行进度条......你能帮我解决这个问题吗
    • 如果您的项目在 github 上是公开的,那么您可以与我分享或尝试在 SO 中提出另一个问题。我们不能在这里讨论另一个问题。我会尽力提供帮助。
    【解决方案2】:

    试试这样的:

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

    【讨论】:

    • 错误:fileFormat 无法解析或不是字段
    • 请回复,因为我陷入了困境。任何帮助将不胜感激。
    • 编辑了答案。
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2017-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-28
      • 2011-02-15
      相关资源
      最近更新 更多