Java AWT Threads
===

I'm having an issue with Threads using netbeans AWT GUI. This is my first time really trying to develope a GUI for a backup program using Java's File System Notifier. I have two files SyncUI.java and Sync.java.

Pretty much what I want to happen is you enter a directory path in the jTextField1 textfield which creates a sync thread that creates a new sync object and then calls processEvents on that object. When a file in that directory is changed I want to add text about the change to the list.

In its current state the UI is no longer not responding, however the processEvents isn't adding anything into my list. Any idea what the problem is? Also since I'm just starting to use java any constructive criticism is welcomed. 

SyncUI.java:

    package sync;
    import java.io.IOException;
    import java.nio.file.Path;
    import java.nio.file.Paths;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.DefaultListModel;
    import javax.swing.JList;
    import javax.swing.SwingUtilities;
  
    public class SyncUI extends javax.swing.JFrame {
        
        public SyncUI() {
            initComponents();
        }

        @SuppressWarnings("unchecked")
        // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
        private void initComponents() {
            jButton1 = new javax.swing.JButton();
            jTextField1 = new javax.swing.JTextField();
            list1 = new java.awt.List();

            setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

            jButton1.setText("Start");
            jButton1.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jButton1ActionPerformed(evt);
                }
            });

            jTextField1.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    jTextField1ActionPerformed(evt);
                }
            });

            list1.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    list1ActionPerformed(evt);
                }
            });

            org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
            .addContainerGap()
            .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(list1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(layout.createSequentialGroup()
            .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 329, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
            .add(jButton1)
            .add(0, 0, Short.MAX_VALUE)))
            .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
            .addContainerGap()
            .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
            .add(jButton1)
            .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
            .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
            .add(list1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 229, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(25, Short.MAX_VALUE))
        );

            pack();
        }// </editor-fold>                        

    private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {                                            
        jButton1.doClick();
    }                                           

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {  
            //I tried to use invokeLater, this solved the problem of the UI nonresponse issue                                       
            SwingUtilities.invokeLater(new Runnable() {
                public void run()
                {
                    //Creates a path dir that my Sync constructor needs to start file   notification watcher on that directory
                    Path dir = Paths.get(jTextField1.getText());
                    try
                    {
                        //Creates a new sync object passing it the directory and the list in my GUI
                        Sync sync = new Sync(dir, list1);
                        try
                        {
                            sync.processEvents();
                        }
                        catch (InterruptedException ex)
                        {
                            Logger.getLogger(SyncUI.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    catch (IOException ex)
                    {
                        Logger.getLogger(SyncUI.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                
            });
    }                                        

    private void list1ActionPerformed(java.awt.event.ActionEvent evt) {                                      
        // TODO add your handling code here:
    }                                     
    
    public static void main(String args[]) throws IOException
    {
        java.awt.EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                SyncUI s = new SyncUI();
                s.setVisible(true);               
            }
        });		
    }
    
    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JTextField jTextField1;
    private java.awt.List list1;
    // End of variables declaration                   
    }


Sync.java:


    package sync;

    import static java.nio.file.StandardWatchEventKinds.*;
    import java.nio.file.attribute.*;
    import java.io.*;
    import java.nio.file.*;
    import java.util.*;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javax.swing.SwingUtilities;

    public class Sync
    {
        private final WatchService ws;
        private final Map<WatchKey,Path> keys;
        public java.awt.List list;
	
        public Sync(Path dir, java.awt.List list) throws IOException, InterruptedException
        {
            this.ws = FileSystems.getDefault().newWatchService();
            this.keys = new HashMap<WatchKey,Path>();
            this.list = list;
            recSet(dir);
            //this.processEvents();
        }
 	
        private void register(Path dir) throws IOException
        {
            WatchKey key = dir.register(ws, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
            keys.put(key, dir);
        }
	
        private void recSet(Path start) throws IOException
        {
            Files.walkFileTree(start, new SimpleFileVisitor<Path>()
            {     
                public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException
                {
                    if(!Files.isHidden(dir))
                    {
                        register(dir);
                        System.out.println(dir);
                    }
                return FileVisitResult.CONTINUE;
                }
            });
        }
	
        void processEvents() throws IOException, InterruptedException
        {
            System.out.println("Entered processEvents");
            SwingUtilities.invokeLater(new Runnable() {
                public void run()
                {
                    System.out.println("Entered run");
                    list.add("test2");
                    list.repaint();
                    while(true)
                    { 
                        WatchKey key;			
                        try
                        {
                            key = ws.take();
                        }
                        catch (InterruptedException x)
                        {
                            return;
                        }
	 		
                        Path dir = keys.get(key);
                        if (dir == null)
                        {
                            System.err.println("WatchKey not recognized");
                            continue;
                        }

                        for (WatchEvent<?> event: key.pollEvents())
                        {
                            WatchEvent.Kind<?> kind = event.kind();
                            WatchEvent<Path> ev = (WatchEvent<Path>)event;
                            Path filename = ev.context();
                            String name = dir.resolve(filename).toString();		        

                            if (kind == OVERFLOW)
                                continue;		        
		        
                            if(kind == ENTRY_CREATE)
                            {
                                System.out.print("Entry Created: ");
                                File f = new File(name);
            
                                if(f.isDirectory())
                                    try {
                                        register(dir.resolve(filename));
                                    } catch (IOException ex) {
                                        Logger.getLogger(Sync.class.getName()).log(Level.SEVERE, null, ex);
                                    }

                                System.out.println(name);
                                list.add(name);     
                            }
                            else if(kind == ENTRY_DELETE)
                            {
                                System.out.print("Entry Deleted: ");
                                System.out.println(name);                          
                            }
                            else if(kind == ENTRY_MODIFY)
                            {
                                File f = new File(name);
                                if(!f.isDirectory())
                            {
                                System.out.print("Entry Modify: ");
                                System.out.println(name);
                            }
                        }
		        
                        boolean valid = key.reset();
  		        
                        if (!valid)
                            break;
                        }
                    }
                }
            });       
        }
    }