import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

import javax.swing.*;

public class LazyListModelExample {

  static class LazyListModel extends AbstractListModel {

    public int getSize() {
      return list.size();
    }

    public Object getElementAt(int index) {
      return list.get(index);
    }

    public void safeAdd(final File file) {
      try {
        SwingUtilities.invokeAndWait(new Runnable() {
          public void run() {
            int index= list.size();
            list.add(file);
            fireIntervalAdded(LazyListModel.this, index, index);
          }
        });
      } catch (InterruptedException e) {
        e.printStackTrace();
      } catch (InvocationTargetException e) {
        Throwable cause= e.getCause();
        if (cause instanceof RuntimeException)
          throw (RuntimeException)cause;
        else
          if (cause instanceof Error)
            throw (Error)cause;
          else
            throw new Error(cause);
      }
    }

    public void traverse(File file) {
      File[] files= file.listFiles(filter);
      for (int i= 0; i < files.length; i++) {
        safeAdd(files[i]);
        traverse(files[i]);
      }
    }

    final ArrayList list= new ArrayList();
    private final FileFilter filter=new FileFilter() {
      public boolean accept(File file) {
        return file.isDirectory();
      }
    };
  }

  public static void main(String[] args) {

    LazyListModel model= new LazyListModel();
    JList list= new JList(model);
    JScrollPane pane= new JScrollPane(list);

    final JFrame frame= new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setContentPane(pane);
    frame.setSize(400, 300);
    frame.show();

    File dir;
    if (args.length > 0)
      dir= new File(args[0]);
    else
      dir= new File(".");

    model.traverse(dir);
  }
}