0

is a couple of days that I'm facing with the problem mentioned on the subject and I was not able to find a solution. I have wrote a JavaFX application in which I open an ACCESS DB and I elaborate the infomrations stored on it to generate word document. Using the SceneBuilder program I have created a UI with several controls and in particular I have added a ProgressBar and a Button. What I would like to do is to have the ProgressBar that oscillating in the undefinite state untill that the open and check the DB procedure is done. In particular I would like to have that the bar start oscillating when a specific button is pressed and stop when the instructions on the associated ActionEvent implemented on the Controller class that handle the UI are executed. But I was not able to got this. Once my program execute the "getConnection" instruction my UI is stuck. Here you have the instructions present on the ActionEvent associated to the button:

@FXML
private void handleButtonDB(ActionEvent event) 
{
    generalProgressBar.setProgress(-1);
    FileChooser fileChooser = new FileChooser();
    fileChooser.setTitle("Open DB File");
    File initDir = new File("C:\\Users\\Public\\Documents\\National Instruments\\TestStand 2016 (32-bit)\\Components\\Models");
    fileChooser.setInitialDirectory(initDir);
    fileChooser.getExtensionFilters().addAll(
            new FileChooser.ExtensionFilter("DataBase file", "*.mdb")
        );
    selectedDBFile = fileChooser.showOpenDialog(null);

    Runnable task = new Runnable() {
        public void run() {
            connectToDB();
        }
    };
     // Run the task in a background thread
    Thread backgroundThread = new Thread(task);
    // Terminate the running thread if the application exits
    backgroundThread.setDaemon(true);
    // Start the thread
    backgroundThread.start();
    while(backgroundThread.isAlive()) {

    }
    if(!isUUTAdditionalInfoAvailable)
        AlertMessage.infoBox("In the selected DB the TABLE 'UUT_PROP_RESULT_ADDITIONAL_DATA' is not present.", "NO UUT ADDITIONAL INFO");
    AlertMessage.infoBox("The selected DB has been loaded.", "DB LOAD INFO");
    generalProgressBar.setProgress(0);
}

where the ProgressBar is defined as follow:

@FXML private ProgressBar generalProgressBar;

The following methods are the ones that I have wrote to create a separate thread for the call to openDBConnection method

    public static Connection dbConnection = null;
    public static boolean isDbOpen = false;
    public static boolean isAdditionalInfoPresent = false;

    public static void openDBConnection(String dbFile)
    {
        isDbOpen=false;
        try
        {
            Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
            String database = "jdbc:ucanaccess://"+dbFile+";";
            dbConnection = DriverManager.getConnection(database, "", "");

            isDbOpen=true;
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
        return;
        //return false;
    }

these are the Runnable methods:

  public static class OpenerDBRunnable implements Runnable {
        private final String dbFile;
        private final ProgressBar finalProgBar;
        OpenerDBRunnable(String file,ProgressBar myBar) {
            this.dbFile = file;
            this.finalProgBar = myBar;
        }

        @Override
        public void run() {
            try
            {           
                boolean run = false;
                while(!run) {
                    DBAccess.openDBConnection(dbFile);
                    run=DBAccess.isDbOpen;
                    Platform.runLater(new Runnable()
                    {@Override
                        public void run()
                        {
                        finalProgBar.setProgress(-1);
                        }
                    });
                }
            }
            catch (Exception ex) 
            {
                ex.printStackTrace();
            }
        }
    }

    public void connectToDB() {

        if(selectedDBFile != null) 
        {
            if(isDBSelected) {
                DBAccess.closeDBConnection();
                sequenceChoice.getItems().clear();
                uut_sn.getItems().clear();
                isSeqSelected = false;
                isDBSelected = false;   
            }
            isDBSelected = true;
            try
            {   
                ExecutorService executor = Executors.newSingleThreadExecutor();
                Runnable worker = new OpenerDBRunnable(selectedDBFile.getAbsolutePath(),generalProgressBar);
                executor.execute(worker);
                executor.shutdown();
                while(!executor.isTerminated()) {   

                }
                //DBAccess.openDBConnection(selectedDBFile.getAbsolutePath());
                isUUTAdditionalInfoAvailable = DBAccess.checkAdditionalInfoPresence();
                ResultSet resultSeq = DBAccess.getSequences();
                sequenceChoice.getItems().clear();
                List<String> myList =  new ArrayList<String>();
                while((resultSeq!=null) && (resultSeq.next()))
                {
                    myList.add(resultSeq.getString("SEQUENCE_FILE_PATH"));
                }   
                resultSeq.close();
                Collections.sort(myList); 
                List<String> myList_wo_Duplicate = myList.stream().distinct().collect(Collectors.toList());
                sequenceChoice.getItems().addAll(myList_wo_Duplicate);
            }
            catch (Exception ex) 
            {
                ex.printStackTrace();
            }
        }

    }
  • 4
    `while(backgroundThread.isAlive()) { }` What's the point of creating a new thread, if you'll block the original thread until the other thread is done? – fabian Apr 11 '20 at 13:40
  • 3
    You've just created a thread, and then immediately shot it in the foot. Not good. I think that you will want to read up on call-backs, and interthread communication with JavaFX. – Hovercraft Full Of Eels Apr 11 '20 at 13:43
  • 2
    See https://stackoverflow.com/questions/30249493/using-threads-to-make-database-requests/30250308#30250308 In your case you would show the progress indicator, start the `Task` to connect to the database, and in the `Task`'s `onSucceeded` handler, remove the progress indicator (and process the results). – James_D Apr 11 '20 at 14:14

0 Answers0