Manage GUI and EDT in a multi-task application

前端 未结 3 1435
终归单人心
终归单人心 2021-01-20 21:44

I developed a Java application for creating and extracting an archive - like WinRAR. You can create several archives at the same time with multithreading. And recently, I wa

3条回答
  •  情歌与酒
    2021-01-20 22:31

    As suggested by others, the best way is to use SwingWorker.

    SwingWorker properties are listenable and listeners are always called in the EDT, thus, you could do something like:

    public class ArchivingWorker extends SwingWorker {
        JProgressBar progressBar = null;
        // Other members here...
        ...
    
        public ArchivingWorker(...) {
            // Any specific initialization here (in EDT)
            addPropertyChangeListener(new PropertyChangeListener() {
                @Override void propertyChange(PropertyChangeEvent e) {
                    if (    "state".equals(e.getPropertyName())
                        &&  e.getNewValue() == StateValue.STARTED) {
                        // Background thread has just started, show a progress dialog here
                        progressBar = new JProgressBar();
                        ...
                    }
                    else if ("progress".equals(e.getPropertyName())) {
                        // Update progress bar here with e.getNewValue()
                        ...
                    }
                }
            });
        }
    
        @Override protected Void doInBackground() {
            // Archiving process here and update progress from time to time
            setProgress(progress);
    
            return null;
        }
    
        @Override protected void done() {
            // Ensure that archiving process worked correctly (no exception)
            try {
                get();
            } catch (Exception e) {
                // Handle exception (user feedback or whatever)
            } finally {
                // Close progress dialog
                ...
            }
        }
    }
    

    Then you can use ArchivingWorker as you need it:

    ArchivngWorker worker = new ArchivingWorker(...);
    worker.execute();
    

提交回复
热议问题