2015-08-17 1 views
0

Cela continue this thread of August 16, 2015Essayer d'utiliser SwingWorker dans le programme de recherche qui utilise FileVisitor dans un thread

Je modifier mon programme Search utiliser SwingWorker. Le code d'origine (main ci-dessous) a une Thread qui est invoquée dans main et « marche l'arborescence des fichiers » à partir d'un nœud donné:

public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      gui = new GUI(); 
      Utilities.disable(GUI.btnStop); 
     }}); 
    t = new Thread(new TASK()); 
    taskStarted = false; 
    } 
} 

Voici l'en-tête de classe d'origine pour TASK:

public class TASK extends SimpleFileVisitor<Path> implements Runnable{ 

Mais pour utiliser SwingWorker, (je suppose) j'ai besoin de TASK extends SwingWorker, ce qui rend la commande originale run illégale (erreur: run est final en SwingWorker).

est ici originale run:

public void run() 
    { 
     SearchyGUI.disposition = FileVisitResult.CONTINUE; 
     Files.walkFileTree(path , this); 
    } 

Puisque je ne peux pas utiliser run, je fait le code ci-dessus l'initialisation pour la classe TASK comme ceci:

public class TASK implements SwingWorker implements FileVisitor<Path> { 
    public void TASK() 
    { 
     System.out.println("Here we are starting TASK..."); 
     SearchyGUI.disposition = FileVisitResult.CONTINUE; 
     Files.walkFileTree(path , this); 
    } 

Mais maintenant la ligne main ci-dessous provoque une erreur (aucun constructeur approprié car maintenant TASK ne met pas en œuvre runnable ....):

t = new Thread(new TASK()); 

Et si je dis simplement new TASK(); l'interface graphique montre, mais quand je clique sur le bouton de recherche, rien ne se passe. Pas de file de marche. Pas d'erreurs La sortie de TASK ne s'affiche même pas. Donc, aucune chance d'invoquer SwingWorker. (En fait, juste pour voir ce qui pourrait arriver [rien] je l'ai retiré de l'en-tête de la classe pour TASK: public class TASK /*extends SwingWorker*/ implements FileVisitor<Path>.)

Si quelque chose d'évident est faux, j'aimerais le voir. Sinon, je vais passer un bon moment en faisant un SSCCE.

+1

Je voudrais créer une classe SwingWorker qui n'implémente pas FileVisitor mais qui utilise un FileVisitor par composition, c'est-à-dire qui contient une instance FileVisitor. Et ne créez pas 'nouveau Thread (...)'. A la place, vous créez votre instance SwingWorker et appelez 'execute()'. –

+0

l'a fait, et, après pas si longtemps, j'ai eu la sortie! Mais comme je n'ai pas implémenté les méthodes 'doInBackground' et' process' (etc.), c'est un peu maladroit. ** MAIS ** grâce à votre seule phrase, j'ai eu le travail à la phase suivante. MERCI, comme toujours! (Ce commentaire était beaucoup plus ancien, j'ai oublié d'ajouter un commentaire pendant plusieurs minutes!) – DSlomer64

+1

Oui, activez votre visiteur depuis la méthode doInBackground. –

Répondre

0

Grâce à @Hover, j'ai un programme de recherche raisonnablement efficace. Faits saillants (à savoir, pas de détails sur les variables ou logique):

public class Main 
{ 
    public static void main(String args[]) 
    { 
    EventQueue.invokeLater 
    (
     new Runnable() 
     { 
     @Override 
     public void run() 
     { 
      gui = new GUI(); 
     } 
     } 
    ); 
    } 
} 

//============================================================== 

public class GUI extends JFrame 
{ 
    private static void btnSearchActionPerformed(ActionEvent evt) 
    { 
     TASK task = new TASK(); 
     task.execute();  
    } 
} 

//============================================================== 

public class TASK extends SwingWorker<Void,String> 
{ 
    FV fv; 

    TASK() 
    { 
    fv = new FV(); 
    } 

    //-------------- inner class 

    class FV implements FileVisitor<Path> 
    { 
     public FileVisitResult visitFile(Path f, BasicFileAttributes a) throws IOException 
     { 
     if(f.getFileName().toString().toLowerCase().matches(fPatt.toLowerCase().trim())) 
     { 
      publish(s); // old --> report(f); -- see process method below 
     } 
     return Main.disposition; 
     } 
    } 

    //---------------- 

    protected Void doInBackground() throws Exception 
    { 
    Files.walkFileTree(path, fv); 
    return null; 
    } 

// **EDIT** added new method 

    @Override 
    protected void process(List<String> chunks){ 
    for (int i = 0; i < chunks.size(); i++) { 
     report(chunks.get(i)); 
    } 
    } 


} 

La seule chose qui me trouble est que je ne l'ai pas mis en œuvre les publish et process et d'autres méthodes SwingWorker.

EDIT

J'inclus les deux dans le code ci-dessus.

EDIT 2

j'ai changé les types de plusieurs déclarations, selon la définition de classe pour TASK:

public class TASK extends SwingWorker<Void,String>

Le premier paramètre de type générique pour SwingWorker, qui est Void ci-dessus, doit être le type renvoyé par doInBackground (et get, si utilisé).

La seconde, String ci-dessus, doit être du type utilisé dans publish et process.

+1

Inutile d'utiliser invokeLater et Runnable dans votre méthode 'btnSearchActionPerformed' car elle devrait déjà être appelée sur l'EDT. –

+0

Merci. Il était là de désespoir plus tôt. J'ai ajouté 'publish' et' process'. Pas sûr de toute différence dans le fonctionnement. – DSlomer64

+0

En fait, 'invokeLater', etc. étaient là plus par ignorance que par désespoir. Désespoir parce que quelque chose d'autre empêchait une bonne exécution; l'ignorance parce que ... ils étaient là inutilement et je ne le savais pas. – DSlomer64