JavaFX thread issue

2019-08-26 21:07发布

i'm using thread to resolve the problem of GUI freeze. But with thread i'm facing a problem that i'm unable to pass format of the report as argument in run method or even with the help of constructor i'm unable to do it.....

public class BirtReportExportCon implements Runnable {

    @FXML
    Button exportButton;

    @FXML
    CheckBox pdfCheckBox;

    @FXML
    CheckBox xlsCheckBox;

    @FXML
    CheckBox docCheckBox;

    @FXML
    CheckBox mailCheckBox;

    public String fileFormat;

Allow to Check Single CheckBox on 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);
        }
    }

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

Run Method

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

save report and open the report

    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条回答
Summer. ? 凉城
2楼-- · 2019-08-26 21:35

You should run this code on the Swing thread instead of calling it from the Java FX thread. Like the following:

@FXML
    void openWithAction(ActionEvent event) {
        SwingUtilities.invokeLater( () -> Desktop.getDesktop().
                                          open(new File(fileModel.
                                                  getFileLocation())));
    }
查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-08-26 21:37

I had a similar problem like this. I think the problem lies in the fileOpening stage. The Desktop class you are using comes from java.awt package.When you use the Desktop class then the JAVAFX thread gets blocked as commented by a user in the link given at the bottom of this answer. But the user has a low reputation (only 11)so we cannot rely on him.

To make your application unfreeze, you will have to create a new Thread. Here is a part of my code, i used in my application and this code worked perfectly. I have also put a link to a github issue of my application where i stated the freezing problem, similar to yours. The issue was created 2 days ago.

@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 issue link: https://github.com/karanpant/SearchEverything/issues/3

I also suggest you to use concurrency provided by JavaFX. Here is the other SO post link. Hope this helps. JavaFX Freeze on Desktop.open(file), Desktop.browse(uri)

EDIT: I am sorry if i don't understand your question . Is your question about application freezing or about not being able to pass a parameter or about not being able to pass a parameter because of application freezing.

查看更多
Rolldiameter
4楼-- · 2019-08-26 21:58

Try something like this:

if ( docCheckBox.isSelected() == true ) {
    BirtReportExportCon r = new BirtReportExportCon();
    r.fileFormat = "docx"; // I WANT THIS FILE FORMAT IN MY RUN METHOD
    new Thread(r).start();
}
查看更多
登录 后发表回答