views:

61

answers:

2

What is the proper way to guarantee delivery when using a SwingWorker? I'm trying to route data from an InputStream to a JTextArea, and I'm running my SwingWorker with the execute method. I think I'm following the example here, but I'm getting out of order results, duplicates, and general nonsense.

Here is my non-working SwingWorker:

class InputStreamOutputWorker extends SwingWorker<List<String>,String> {

    private InputStream is;
    private JTextArea output;

    public InputStreamOutputWorker(InputStream is, JTextArea output) {
        this.is = is;
        this.output = output;
    }

    @Override
    protected List<String> doInBackground() throws Exception {
        byte[] data = new byte[4 * 1024];
        int len = 0;

        while ((len = is.read(data)) > 0) {
            String line = new String(data).trim();
            publish(line);
        }

        return null;
    }

    @Override
    protected void process( List<String> chunks )
    {
        for( String s : chunks )
        {
            output.append(s + "\n");
        }
    }
}
A: 

Clear your data array after reading from the input stream.

while ((len = is.read(data)) > 0) {
                String line = new String(data).trim();
                publish(line);
                Arrays.fill(data,(byte)0);
}
Stefan Kendall
-1 - read the API or Fred's answer; you're creating a String with a lot of NUL characters in it
kdgregory
Not really, trim takes care of it. It may be slightly inefficient, but that's not where my bottleneck is at all in this application. is.read() takes about 1 second to respond, so anything I do in the loop is basically free. I'd -1 your comment for pre-optimization if I could.
Stefan Kendall
+1  A: 

You need to use the 'len' value when creating your string:

String line = new String(data,0,len).trim();

Also, I would recommend you wrap your InputStream in a BufferedReader and use the 'readLine()' method:

BufferedReader reader = new BufferedReader(is);
...
String line = reader.readLine()
Fred Haslam