0

This continues this thread of August 16, 2015

I'm modifying my Search program to use SwingWorker. The original code (main shown below) has one Thread that is invoked in main and "walks the file tree" from a given node:

  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;
  }
}

Here's the original class header for TASK:

public class TASK extends SimpleFileVisitor<Path> implements Runnable{

But in order to use SwingWorker, (I assume) I need TASK extends SwingWorker, making the original run command illegal (error: run is final in SwingWorker).

Here's original run:

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

Since I can't use run, I made the code above the initialization for class TASK like so:

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);
  }

But now the line in main below causes error (no suitable constructor since now TASK doesn't implement runnable....):

 t = new Thread(new TASK());

And if I just say new TASK(); the GUI shows, but when I click the Search button, nothing happens. No file walk. No errors. The output from TASK doesn't even show. So no chance to invoke SwingWorker. (In fact, just to see what might happen [nothing] I removed it from the class header for TASK: public class TASK /*extends SwingWorker*/ implements FileVisitor<Path>.)

If anything obvious is wrong, I'd love to see it. If not, I will spend a good long while making a SSCCE.

Community
  • 1
  • 1
DSlomer64
  • 4,234
  • 4
  • 53
  • 88
  • 1
    I would create a SwingWorker class that doesn't implement FileVisitor but rather that uses a FileVisitor by composition, i.e., that contains a FileVisitor instance. And don't create `new Thread(...)`. Instead you create your SwingWorker instance and call `execute()` on it. – Hovercraft Full Of Eels Aug 17 '15 at 17:08
  • Did so, and, after not so long, I got output! But since I haven't implemented the `doInBackground` and `process` (etc.) methods, it's clunky. **BUT** thanks to your single sentence, I got the job to the next phase. THANKS, as always! (This comment was a lot older; I forgot to Add Comment for many minutes!) – DSlomer64 Aug 17 '15 at 17:52
  • 1
    Yes, activate your visitor from within the doInBackground method. – Hovercraft Full Of Eels Aug 17 '15 at 18:27

1 Answers1

0

Thanks to @Hover, I have a reasonably-smooth-working Search program. Highlights (i.e., no details about variables or logic):

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));
    }
  }


}

Only thing troubling me is that I haven't implemented the publish and process and other SwingWorker methods.

EDIT

So I included the two in the code above.

EDIT 2

I changed types on several statements, based on the class definition for TASK:

public class TASK extends SwingWorker<Void,String>

The first generic type parameter for SwingWorker, which is Void above, must be the type returned by doInBackground (and get, if used).

The second, String above, must be the type used in publish and process.

DSlomer64
  • 4,234
  • 4
  • 53
  • 88
  • 1
    No need for the invokeLater and Runnable in your `btnSearchActionPerformed` method as it should already be called on the EDT. – Hovercraft Full Of Eels Aug 17 '15 at 18:41
  • Thanks. It was there out of earlier desperation. I've added `publish` and `process`. Not sure of any differences in operation. – DSlomer64 Aug 17 '15 at 18:57
  • Actually, `invokeLater`, etc. were there more out of ignorance than desperation. Desperation because something else was preventing proper execution; ignorance because ... they were there unnecessarily and I didn't know it. – DSlomer64 Aug 18 '15 at 19:42