简体   繁体   中英

JavaFX thread should wait for background thread but without freezing the UI (JavaFX)

I want my main thread to wait until the background thread completes. But, this makes my UI freeze. I want to achieve this without freezing my UI. Please help me out. I am new to JavaFX.

My Code is ---

waitNotifyClass wait1 = new waitNotifyClass();
private void download(ActionEvent event) throws SQLException, IOException, InterruptedException {
        try (Connection conn = ......getConnection()) {

            /// opening filechooser
            FileChooser fc = new FileChooser();
            FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("Compressed(zipped) Folder (*.zip)", "*.zip");//Compressed(zipped) Folder (*.gz)", "*.gz"
            fc.getExtensionFilters().add(extFilter);
            String downloadsLocation = System.getProperty("user.home") + "/Downloads/";
            /// get a File file with name as you save in file chooser

  
            file = fc.showSaveDialog(downloadMultiTraceFileButton.getScene().getWindow());
       
            file.mkdirs();

            File sourceFile = file;
            String s = file.getAbsolutePath().substring(0, file.getAbsolutePath().length() - 4);
            destFile = new File(s);
            if (sourceFile.renameTo(destFile)) {
                System.out.println("File renamed successfully");
            } else {
                System.out.println("Failed to rename file");
            }

            /// object of the folder made after renaming
            File theDir = new File(destFile.getAbsolutePath());

            /// Iterating through the slected item of trace files one by one for create a file and then fill it
            Task task = new Task() {
                @Override
                protected Void call() throws Exception {
                    for (String str : traceFileListView.getSelectionModel().getSelectedItems()) {
                     
                        File myFile = new File(theDir.getAbsolutePath() + "\\" + str);
                        /// make new file if myFile doesnt exist
                        if (!myFile.exists()) {
                            myFile.createNewFile();
                        }
                        /// get writer object of FileWriter for writing finally on file from 
                      

                        FileWriter writer = new FileWriter(myFile);
                 
                        /// query for getting content of trace file
                        String querySubPart = "select * from table_name='" + str + "'";
                     
                        PreparedStatement preparedStatement = conn.prepareStatement(querySubPart);
                        
                        ResultSet resultSet = preparedStatement.executeQuery();
                        resultSet.setFetchSize(200);
                        ///  writing into file from resultSet
                        System.out.println("writing before while loop " + Thread.currentThread());
                        while (resultSet.next()) {
                            try {
                                writer.write(resultSet.getString(1));
                                System.out.println(resultSet.getString(1));
                            } catch (IOException ex) {
                                System.out.println("inside try of write");
                            }
                        }
                        writer.close();
                    }
                    wait1.notifyFunction();
                    updateProgress(1, 1);
                    return null;

                }

            };

            System.err.println("Thread created" + Thread.currentThread());
            new Thread(task).start();
            wait1.waitFunction();

            //// closing the window open where download button was there
            ((Stage) generateTraceFileButton.getScene().getWindow()).close();
            /// getting sourcepath folder which is to be zipped
            String sourcePath = theDir.getAbsolutePath();
            // name of zip folder
            String destinationpath = theDir + ".zip";
            System.out.println(destinationpath);

       
            packInZipCode(sourcePath, destinationpath);
          
  

        } catch (SQLException e) {

            System.out.println("Exception caught \n" + e.toString());
            if (e.toString().trim().toUpperCase().contains("----")) {
                ....
            }
        }
    }

I am sure that my UI is freezing because of wait1.waitFunction() because this is making my UI thread wait and freeze the UI. I want to wait for it but without freezing the app. Edited--

why do I want to achieve this?

because If I will not stop my UI thread, it will go ahead and zip my file. but that same file is being used by the background thread also. So I won't get the desired output. Also, my main task is to do the downloading part(here it is heavy, so take time) in the background thread. At the same time, I don't want my main thread to freeze.

I tried this---> Implemented task.setOnSucceded just after thread creation so that my JavaFx thread will execute this part only after task is completed. But in this case , background thread(task is executing here) is losing connection . Got this error--> java.sql.SQLException: Connection is closed at this line--> preparedStatement = conn.prepareStatement(querySubPart);

My new Code looks like this -->

private void downloadMultiTraceFiles(ActionEvent event) throws SQLException, IOException, InterruptedException {
        try (Connection conn = mainApp.getHikariDataSource().getConnection()) {

            /// opening filechooser
            FileChooser fc = new FileChooser();
            FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("Compressed(zipped) Folder (*.zip)", "*.zip");//Compressed(zipped) Folder (*.gz)", "*.gz"
            fc.getExtensionFilters().add(extFilter);
            String downloadsLocation = System.getProperty("user.home") + "/Downloads/";
            /// get a File file with name as you save in file chooser

            System.out.println("Inside runlator" + Thread.currentThread());
            file = fc.showSaveDialog(downloadMultiTraceFileButton.getScene().getWindow());
            System.out.println("Path of file->" + file.getAbsolutePath());
            file.mkdirs();

            File sourceFile = file;
            String s = file.getAbsolutePath().substring(0, file.getAbsolutePath().length() - 4);
            destFile = new File(s);
            if (sourceFile.renameTo(destFile)) {
                System.out.println("File renamed successfully" + Thread.currentThread());
            } else {
                System.out.println("Failed to rename file");
            }

            /// object of the folder made after renaming
            File theDir = new File(destFile.getAbsolutePath());

            /// Iterating through the slected item of trace files one by one for create a file and then fill it
            Task task = new Task() {
                @Override
                protected Void call() throws Exception {
                    for (String str : traceFileListView.getSelectionModel().getSelectedItems()) {
                        System.out.println("inside of the for loop " + Thread.currentThread());
                        File myFile = new File(theDir.getAbsolutePath() + "\\" + str);
                        /// make new file if myFile doesnt exist
                        if (!myFile.exists()) {
                            myFile.createNewFile();
                        }
                        /// get writer object of FileWriter for writing finally on file from 
                        System.out.println("t1--------- " + Thread.currentThread());

                        FileWriter writer = new FileWriter(myFile);
                        System.out.println("t2----------- " + Thread.currentThread());
                        /// query for getting content of trace file
                        String querySubPart = "select payload from gv$diag_trace_file_contents where trace_filename='" + str + "'";
                        System.out.println("t3----------- " + Thread.currentThread());
                        PreparedStatement preparedStatement = conn.prepareStatement(querySubPart);
                        System.out.println("t4----------- " + Thread.currentThread());
                        ResultSet resultSet = preparedStatement.executeQuery();
                        resultSet.setFetchSize(200);
                        ///  writing into file from resultSet
                        System.out.println("writing before while loop " + Thread.currentThread());
                        while (resultSet.next()) {
                            try {
                                writer.write(resultSet.getString(1));
                                System.out.println(resultSet.getString(1));
                            } catch (IOException ex) {
                                System.out.println("inside try of write");
                            }
                        }
                        writer.close();
                    }
                    wait1.notifyFunction();
                    updateProgress(1, 1);
                    return null;

                }

            };

            System.err.println("Thread created" + Thread.currentThread());
            new Thread(task).start();
            wait1.waitFunction();

            task.setOnSucceeded((e) -> {
                System.out.println("Inside set on succeeded"+Thread.currentThread());
                //// closing the window open where download button was there
                ((Stage) generateTraceFileButton.getScene().getWindow()).close();
                /// getting sourcepath folder which is to be zipped
                System.out.println("before zip");
                String sourcePath = theDir.getAbsolutePath();
                // name of zip folder
                String destinationpath = theDir + ".zip";
                System.out.println(destinationpath);

                try {
                    packInZipCode(sourcePath, destinationpath);
                } catch (IOException ex) {
                    Logger.getLogger(GenerateTraceFilesController.class.getName()).log(Level.SEVERE, null, ex);
                }

          
            });
  

        } catch (SQLException e) {

            System.out.println("Exception caught \n" + e.toString());
            if (e.toString().trim().toUpperCase().contains("ORA-48127")) {
                ....
            }
        }
    }

If you want your main thread to wait, and at the same time you don't want your UI to be frozen, then you can use:

task.setOnSucceeded(e->{'your code'})

For example:

Thread t1 = new Thread(task);
t1.start();
Thread.interrupted();

task.setOnSucceeded(e -> {
    System.out.println("inside succeeded");
    String sourcePath = theDir.getAbsolutePath();
    // name of zip folder
    String destinationpath = theDir + ".zip";
    System.out.println(destinationpath);

    try {
        //// calling the function where zipping code is written
        packInZipCode(sourcePath, destinationpath);
    } catch (IOException ex) {
        Logger.getLogger(GenerateTraceFilesController.class.getName()).log(Level.SEVERE, null, ex);
    }
    System.out.println("zip sucessfully ---" + Thread.currentThread());
    // for deleting the folder from which our zip folder made, bcs it is duplicate now, so dlete it
    deleteDirectoryLegacyIO(theDir);
    System.out.println("end succeeded");
});
            

This part of the code will be run by the JavaFX thread. and your UI will also not freeze. This solved my problem.

Why do you want to run those codes by the Javafx thread?

because some works /operations can be done only by the JavaFX thread. These works include Filechooser, file operations, label setting, etc. So you can't run these in your background thread, so we want to run them by the Main thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM