2010-04-25 7 views
1

Quelle est la meilleure façon de garantir la livraison lors de l'utilisation d'un SwingWorker? J'essaye de diriger des données d'un InputStream vers un JTextArea, et j'exécute mon SwingWorker avec la méthode execute. Je pense que je suis l'exemple here, mais je reçois des résultats hors d'usage, des doublons, et un non-sens général.Swingworker produisant des sorties/sorties en double dans le désordre?

Voici mon SwingWorker non-travail:

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"); 
     } 
    } 
} 
+1

Exécutez-vous plusieurs travailleurs à la fois? – TofuBeer

+0

Avez-vous essayé de l'utiliser dans le fil Swing Dispatcher? A moins que votre flux d'entrée ne soit trop lent (> 1 seconde) alors je le mettrais dans le DispatchThread. Il n'y a pas assez de code ou de contexte pour identifier les problèmes. –

+0

Un seul opérateur est exécuté à la fois et le flux d'entrée prend des données pendant plusieurs heures. –

Répondre

-1

Effacer votre tableau de données après avoir lu à partir du flux d'entrée.

while ((len = is.read(data)) > 0) { 
       String line = new String(data).trim(); 
       publish(line); 
       Arrays.fill(data,(byte)0); 
} 
+0

-1 - lisez l'API ou la réponse de Fred; vous créez une chaîne avec beaucoup de caractères NUL dedans – kdgregory

+0

Pas vraiment, le trim s'occupe de ça. C'est peut-être un peu inefficace, mais ce n'est pas du tout mon goulot d'étranglement dans cette application. is.read() prend environ 1 seconde pour répondre, donc tout ce que je fais dans la boucle est fondamentalement libre. J'aurais -1 votre commentaire pour la pré-optimisation si je pouvais. –

1

Vous devez utiliser le « len » valeur lors de la création de votre chaîne: méthode

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

Aussi, je vous recommande Enveloppez votre InputStream dans un BufferedReader et utilisez le 'readLine():

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