Java swing doInBackground、停止程序和更新GUI

u59ebvdq  于 2023-04-19  发布在  Java
关注(0)|答案(1)|浏览(116)

我是Java Swing的新手,我需要制作一些简单的Java桌面应用程序。我有MainPanel,其中我有SwingWorker和doInBackgroung,其中我调用服务,它调用DAO,从数据库查询数据。我还有一个停止按钮,单击设置工人。取消(true),但是程序没有停止,我甚至不能用X按钮关闭窗口。我想是因为对数据库的查询还没有结束,所以进程没有立即停止,但是为什么我不能关闭窗口呢?
这就是代码:

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

停止代码:

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

        worker.cancel(true);

        stop.setEnabled(false);}

更新:

根据答案和注解,下面是代码的其余部分:

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代码:

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

现在,除了第一个问题,我如何使用publish()和processess()方法来更新generateFiles()和DAO方法中的textArea()?

svmlkihl

svmlkihl1#

您正在从doInBackground方法中进行Swing突变调用:

textArea.append(...);

这就破坏了线程规则和你的程序。
解决方案是不这样做,而是publish需要显示的数据,然后process通过SwingWorker的发布/处理方法对发布的信息。
例如,(代码未测试):

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

相关问题