Java swing doInBackground, stopping program, and update GUI

78 views Asked by At

I'm new to java Swing, and I need to make some simple Java desktop app. I have MainPanel in which I have SwingWorker with doInBackgroung in which I call service which calls a DAO that make a quering data from database. I also have a stop button which on click set worker.cancel(true), but the program is not stopping and I can not even close the window with X button. I suppose that the proccessing is not stoped imidietly because the querying to database is not ended yet, but why cant I close the window?

This is the code:

worker = new SwingWorker() {

            @Override
            protected Object doInBackground() throws Exception {

                long startTime = System.nanoTime();
                textArea.append("Starting...\n");

                generatingFilesService.genereteFiles(connectionDBFirst, connectionDBSecond, connectionDBThird,
                        date1, date2);
    
                long endTime = System.nanoTime();
                double time = (double) ((endTime - startTime) / 1_000_000_000);
                if (ConnectionDBFirst.flag != false) {
                    if (time < 60d) {
                        textArea.append("Genereting ended for " + time + " seconds\n");
                        textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
                    } else {
                        textArea.append("Genereting ended for " + (time / 60) + " minutes\n");
                        textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
                    }
                }
                return null;
            }       
            
            @Override
            protected void done() {
                if (isCancelled()) {
                    textArea.append("Stopping generating files...\n");
                    closeConnections();
                    logger.info(Messages.PROCCESS_INTERUPTED);
                } else 
                    closeConnections();
            }
        };worker.execute();

Stopping code:

if (e.getSource() == stop) {

        worker.cancel(true);

        stop.setEnabled(false);}

UPDATE:

Based on the answer and comments, here is the rest of the code:

public void genereteFiles(connectionDBFirst, connectionDBSecond, connectionDBThird,
                        date1, date2) {

    List<Person> persons1 = daoFirst.getPersons(connectionDBFirst, date1, date2);
        
    //here i want to update the textArea() that the daoFirst.getPersons() is done
    //but how to that without MainPanel.textArea.append(...);
    
    List<Person> persons2 = daoSecond.getPersons(connectionDBSecond, date1, date2);
    
    //here i want to update the textArea() that the daoSecond.getPersons() is done
    //but how to that without MainPanel.textArea.append(...);
    
    //same with daoThird

    genereteFilesService.createFiles(persons1, persons2, persons3);

    //update textArea() again

}

DAO code:

public List<Person> getPersons(connectionDBFirst, date1, date2) {

    //executeing sql query and geting the Persons
    //this takes long time, and from here I calculate 
    //percentage of persons fetched and I want to show the prcentage in textArea()
    //but how to do that without MainPanel.textArea.append(...);
}

Now, beside initial question, how can I use publish() and proccess() methods to update the textArea() from generateFiles() and DAO methods?

1

There are 1 answers

7
Hovercraft Full Of Eels On

You're making Swing mutational calls from within the doInBackground method:

textArea.append(...);

And this breaks the threading rules and your program.

The solution is to not do this, and instead to publish the data that needs to be displayed and then process the information that was published via the publish/process method pair of the SwingWorker.

e.g., (code not tested):

worker = new SwingWorker<Void, String>() {

    @Override
    protected Object doInBackground() throws Exception {
        long startTime = System.nanoTime();
        
        // textArea.append("Starting...\n");
        publish("Starting...\n");
        
        generatingFilesService.genereteFiles(connectionDBFirst, connectionDBSecond, connectionDBThird, date1, date2);
        long endTime = System.nanoTime();
        double time = (double) ((endTime - startTime) / 1_000_000_000);
        if (ConnectionDBFirst.flag != false) {
            if (time < 60d) {
                // textArea.append("Genereting ended for " + time + " seconds\n");
                // textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
                publish("Genereting ended for " + time + " seconds\n");
            } else {
                // textArea.append("Genereting ended for " + (time / 60) + " minutes\n");
                // textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
                publish("Genereting ended for " + (time / 60) + " minutes\n");
            }
        }
        return null;
    }       

    @Override
    protected void process(List<String> chunks) {
        for (String chunk : chunks) {
            textArea.append(chunk);
            textArea.setCaretPosition(MainPanel.textArea.getDocument().getLength());
        }
    }

// ....
}
worker.execute();