Jobless Programmer
Jobless Programmer

Reputation: 186

java swingworker doesnt work properly it publish but wont process

I tried a simple code to scan all files from a directory with recursive with SwingWorker but it seems the output wasn't so good here is the code:

public class BackupBackgroundProcess extends SwingWorker<Object, String> {
    public BackupBackgroundProcess() {
    }
    @Override
    protected void process(List<String> list) {
        System.out.println("PROCESSING FILE = "+list.get(0));
    }
    @Override
    protected void done() {
    }
    @Override
    protected FileStatus doInBackground() throws Exception {
        System.out.println("OK");
        File[] root;
        root = new File("/home/hilman/Pictures/err").listFiles();
        for (File file : root) {
            seekFiles(file, this);
        }
        return null;
    }

    private void seekFiles(File f, SwingWorker thread) {
        if(f.isDirectory()){
            File[] listedFiles = f.listFiles();
            for (int i = 0; i < listedFiles.length; i++) {
                File file = listedFiles[i];
                seekFiles(file,  thread);
            }
        } else {
            System.out.println(" PUBLISHING FILE "+f.getAbsolutePath());
            publish(f.getAbsolutePath());

        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new BackupBackgroundProcess().execute();
            }
        });

    }
}

Output expectation is

OK
 PUBLISHING FILE /home/hilman/Pictures/err/_1427612060421_1.userfile
 PUBLISHING FILE /home/hilman/Pictures/err/pic2.png
 PUBLISHING FILE /home/hilman/Pictures/err/pic1.png
 PUBLISHING FILE /home/hilman/Pictures/err/1.png
PROCESSING FILE = /home/hilman/Pictures/err/_1427612060421_1.userfile
PROCESSING FILE = /home/hilman/Pictures/err/pic2.png
PROCESSING FILE = /home/hilman/Pictures/err/pic1.png
PROCESSING FILE = /home/hilman/Pictures/err/1.ong

but it seems it only appear

OK
 PUBLISHING FILE /home/hilman/Pictures/err/_1427612060421_1.userfile
 PUBLISHING FILE /home/hilman/Pictures/err/pic2.png
 PUBLISHING FILE /home/hilman/Pictures/err/pic1.png
 PUBLISHING FILE /home/hilman/Pictures/err/1.png
PROCESSING FILE = /home/hilman/Pictures/err/_1427612060421_1.userfile

Does SwingWorker doInBackground method finish regardless if the process is not done? Why doesn't it work properly?

Upvotes: 0

Views: 742

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347314

Basically, from my observations, when this occurs, it's because what's going on in the doBackground method is preventing what ever is processing the "publish queue" from being able to run.

Try adding a call to Thread.yield or Thread.sleep somewhere in the processing loop to allow the "publishing" thread time to process the "publish queue"

import java.io.File;
import java.util.List;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class BackupBackgroundProcess extends SwingWorker<Object, String> {

    public BackupBackgroundProcess() {
    }

    @Override
    protected void process(List<String> list) {
        System.out.println("PROCESSING " + list.size() + " files");
    }

    @Override
    protected void done() {
    }

    @Override
    protected Object doInBackground() throws Exception {
        System.out.println("OK");
        File[] root;
        root = new File("/home/hilman/Pictures/err").listFiles();
        for (File file : root) {
            seekFiles(file, this);
        }
        return null;
    }

    private void seekFiles(File f, SwingWorker thread) {
        if (f.isDirectory()) {
            File[] listedFiles = f.listFiles();
            for (int i = 0; i < listedFiles.length; i++) {
                File file = listedFiles[i];
                seekFiles(file, thread);
            }
        } else {
            //          System.out.println(" PUBLISHING FILE " + f.getAbsolutePath());
            publish(f.getAbsolutePath());
            Thread.yield();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new BackupBackgroundProcess().execute();
            }
        });

    }
}

Since you're doing a recursive call, I placed a call to Thread.yield after calling publish, but you could just as easily place it at the end of the seek method.

Remember, the process/publish process buffers results, so when publish is called, you might get a number of files, for example...

OK
PROCESSING 122 files
PROCESSING 127 files
PROCESSING 184 files
PROCESSING 144 files
PROCESSING 131 files
PROCESSING 147 files
PROCESSING 335 files
...

I tend to use Thread.sleep(1), but I'd recommending testing with both a see what results you get...

Upvotes: 3

Related Questions