2015-06-23 2 views
0

Я написал рекурсивный метод поиска в приложении GUI GUI, чтобы найти файл на диске.
UI отзывчивый,
поиск успешно произошло, но JList не заполняет, а консоль печатает имена файлов успешно, после 3-х кликов поиска файлов кнопки добавляются в JList, но с повторяющимися именами каждого файлаJList не заполняется после нажатия кнопки поиска

 //nullpointerexception 
     java.util.concurrent.ExecutionException: 
    java.lang.NullPointerException 
at java.util.concurrent.FutureTask.report(FutureTask.java:122) 
at java.util.concurrent.FutureTask.get(FutureTask.java:188) 
at javax.swing.SwingWorker.get(SwingWorker.java:602) 
at searchapp.searchScreen$4.propertyChange(searchScreen.java:90) 
at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335) 
atjava.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:327) 
at javax.swing.SwingWorker$SwingWorkerPropertyChangeSupport.firePropertyChange(SwingWorker.java:854) 
at javax.swing.SwingWorker$SwingWorkerPropertyChangeSupport$1.run(SwingWorker.java:859) 
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(SwingWorker.java:832) 
at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112) 
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:842) 
at javax.swing.Timer.fireActionPerformed(Timer.java:312) 
at javax.swing.Timer$DoPostEvent.run(Timer.java:244) 
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:312) 
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:738) 
at java.awt.EventQueue.access$300(EventQueue.java:103) 
at java.awt.EventQueue$3.run(EventQueue.java:699) 
at java.awt.EventQueue$3.run(EventQueue.java:697) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:708) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242) 
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138) 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91) 
Caused by: java.lang.NullPointerException 
at searchapp.searchWorker.search(searchWorker.java:65) 
at searchapp.searchWorker.search(searchWorker.java:66) 
at searchapp.searchWorker.search(searchWorker.java:66) 
at searchapp.searchWorker.doInBackground(searchWorker.java:51) 
at searchapp.searchWorker.doInBackground(searchWorker.java:21) 
at javax.swing.SwingWorker$1.call(SwingWorker.java:296) 
at java.util.concurrent.FutureTask.run(FutureTask.java:262) 
at javax.swing.SwingWorker.run(SwingWorker.java:335) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
at   java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
at java.lang.Thread.run(Thread.java:745) 
java.util.concurrent.ExecutionException: java.lang.NullPointerException 
at java.util.concurrent.FutureTask.report(FutureTask.java:122) 
at java.util.concurrent.FutureTask.get(FutureTask.java:188) 
at javax.swing.SwingWorker.get(SwingWorker.java:602) 
at searchapp.searchScreen$4.propertyChange(searchScreen.java:90) 
at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335) 
at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:327) 
at javax.swing.SwingWorker$SwingWorkerPropertyChangeSupport.firePropertyChange(SwingWorker.java:854) 
at javax.swing.SwingWorker$SwingWorkerPropertyChangeSupport$1.run(SwingWorker.java:859) 
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(SwingWorker.java:832) 
at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112) 
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:842) 
at javax.swing.Timer.fireActionPerformed(Timer.java:312) 
at javax.swing.Timer$DoPostEvent.run(Timer.java:244) 
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:312) 
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:738) 
at java.awt.EventQueue.access$300(EventQueue.java:103) 
at java.awt.EventQueue$3.run(EventQueue.java:699) 
at java.awt.EventQueue$3.run(EventQueue.java:697) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:708) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242) 
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138) 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91) 
Caused by: java.lang.NullPointerException 
at searchapp.searchWorker.search(searchWorker.java:65) 
at searchapp.searchWorker.search(searchWorker.java:66) 
at searchapp.searchWorker.search(searchWorker.java:66) 
at searchapp.searchWorker.doInBackground(searchWorker.java:51) 
at searchapp.searchWorker.doInBackground(searchWorker.java:21) 
at javax.swing.SwingWorker$1.call(SwingWorker.java:296) 
at java.util.concurrent.FutureTask.run(FutureTask.java:262) 
at javax.swing.SwingWorker.run(SwingWorker.java:335) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
at java.lang.Thread.run(Thread.java:745) 


    //New Code 

public class searchWorker extends SwingWorker<List<File>, File> { 

    protected static final FileFilter DIRRECTORY_FILE_FILTER = new FileFilter() { 

     @Override 
     public boolean accept(File pathname) { 
      return pathname.isDirectory(); 
     } 
    }; 
    private DefaultListModel model; 
    private File path; 
    private FileFilter filefilter; 

    public searchWorker(File path, FileFilter filter, DefaultListModel model) { 
     this.model = model; 
     this.path = path; 
     this.filefilter = filter; 
    } 

    @Override 
    protected void process(List<File> chunks) { 
     for (File file : chunks) { 
      model.addElement(file); 
     } 
    } 

    @Override 
    protected List<File> doInBackground() throws Exception { 
     return new ArrayList<>(search(path)); 
    } 

    public List<File> search(File path) { 
     List<File> files = new ArrayList<>(25); 
     if (path.exists()) { 
      File[] list = path.listFiles(filefilter); 
      if (list != null && list.length > 0) { 
       files.addAll(Arrays.asList(list)); 
       publish(list); 

      } 
      File[] dirs = path.listFiles(DIRRECTORY_FILE_FILTER); 
      for (File dir : dirs) { 
       files.addAll(search(dir)); 

      } 
     } 
     return files; 
    } 

} 

private void searchBtnActionPerformed(java.awt.event.ActionEvent evt) { 
    searchWorker worker = new searchWorker(new File("c:\\"), new FileFilter() { 

     @Override 
     public boolean accept(File pathname) { 
      return pathname.getName().endsWith(".txt") && pathname.getName().startsWith("abc"); 
     } 
    }, lm); 
    worker.execute(); 
} 

//old code 
DefaultListModel lm = new DefaultListModel(); 

public void search(String path) { 

    File root = new File(path); 
    File[] list = root.listFiles(); 
    if (list == null) { 
     return; 
    } 
    for (File f : list) { 
     if (f.isDirectory()) { 
      if (list == null) { 
       return; 
      } 
      search(f.getAbsolutePath()); 

     } else { 
      if (f.getName().endsWith(".txt") && f.getName().startsWith("abc")) { 
       lm.addElement(f.getName()); 

       System.out.println(f.getName()); 

       found = true; 
      } 
     } 

    } 


private void formWindowOpened(java.awt.event.WindowEvent evt) { 

    jList1.setModel(lm); 
} 

private void searchBtnActionPerformed(java.awt.event.ActionEvent evt) { 
    //just added this code in my program to resolve unresponsive UI 
    Thread t = new Thread(new Runnable() { 

     @Override 
     public void run() { 
      search("c:\\"); 
     } 
    }); 
    t.start(); 

} 
+0

Кроме того, где вы обновить ListModel? – MadProgrammer

ответ

0

Check следующие изменения.

public void search(String path) { 
     //DefaultListModel lm = new DefaultListModel(); 
     //If you are not using the model for other purposes you can declare it here itself 

     //to clear the previous values if any [this is why repetitive values] 
     lm.clear(); 
     File root = new File(path); 
     File[] list = root.listFiles(); 
     if (list == null) { 
      return; 
     } 
     for (File f : list) { 
      if (f.isDirectory()) { 
//    Unnecessary test for null 
//    if (list == null) { 
//     return; 
//    } 
       search(f.getAbsolutePath()); 

      } else { 
       if (f.getName().endsWith(".txt") && f.getName().startsWith("abc")) { 
        lm.addElement(f.getName()); 

        System.out.println(f.getName()); 

        found = true; 
       } 
      } 
     } 
     jList1.setModel(lm); 
    } 
+1

Вы нарушаете правила единственного потока Swing – MadProgrammer

+0

не сработали .... все же такая же проблема возникает –

2

Основная проблема в том, что вы на самом деле не изменяя ListModel в любом случае.

Swing - это однопоточная среда, вы использовали Thread, чтобы убедиться, что пользовательский интерфейс не заблокирован во время выполнения поиска, что хорошо, но Swing также не является потокобезопасным, что означает, что вы не должны обновите пользовательский интерфейс вне контекста Event Dispatching Thread, поэтому Thread плох.

В то время как вы «могли бы» использовать Thread, SwingWorker представит лучший (и вообще проще) решение задачи (не говоря уже о более многоразовый один)

public static class SearchWorker extends SwingWorker<List<File>, File> { 

    protected static final FileFilter DIRECTORY_FILE_FILTER = new FileFilter() { 
     @Override 
     public boolean accept(File pathname) { 
      return pathname.isDirectory(); 
     } 
    }; 

    private DefaultListModel model; 
    private File path; 
    private FileFilter fileFilter; 

    public SearchWorker(File path, FileFilter filter, DefaultListModel model) { 
     this.model = model; 
     this.path = path; 
     this.fileFilter = filter; 
    } 

    @Override 
    protected void process(List<File> chunks) { 
     for (File file : chunks) { 
      model.addElement(file); 
     } 
    } 

    @Override 
    protected List<File> doInBackground() throws Exception { 
     return new ArrayList<>(search(path)); 
    } 

    public List<File> search(File path) { 

     List<File> files = new ArrayList<>(25); 
     if (path.exists() && path.isDirectory()) { 
      File[] list = path.listFiles(fileFilter); 
      if (list != null && list.length > 0) { 
       files.addAll(Arrays.asList(list)); 
       publish(list); 
      } 

      File[] dirs = path.listFiles(DIRECTORY_FILE_FILTER); 
      if (dirs != null) { 
       for (File dir : dirs) { 
        files.addAll(search(dir)); 
       } 
      } 
     } 

     return files; 
    } 

} 

Тогда вы бы просто запустить его используя что-то вроде ...

SearchWorker worker = new SearchWorker(new File("c:\\"), new FileFilter() { 

    @Override 
    public boolean accept(File pathname) { 
     return pathname.getName().endsWith(".txt") && pathname.getName().startsWith("abc"); 
    } 
}, lm); 
worker.execute(); 

См Worker Threads and SwingWorker для более подробной информации

Runnable exampl е ...

Scanning

import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.io.File; 
import java.io.FileFilter; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 
import javax.swing.DefaultListModel; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.SwingWorker; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      DefaultListModel model = new DefaultListModel(); 
      JList list = new JList(model); 
      setLayout(new BorderLayout()); 
      add(new JScrollPane(list)); 

      JLabel label = new JLabel("..."); 
      add(label, BorderLayout.SOUTH); 

      SearchWorker worker = new SearchWorker(new File("c:\\"), new FileFilter() { 
       @Override 
       public boolean accept(File pathname) { 
        return pathname.getName().endsWith(".png"); 
       } 
      }, model); 
      worker.addPropertyChangeListener(new PropertyChangeListener() { 
       @Override 
       public void propertyChange(PropertyChangeEvent evt) { 
        SearchWorker worker = (SearchWorker) evt.getSource(); 
        if ("state".equals(evt.getPropertyName())) { 
         if (worker.isDone()) { 
          label.setText("Finished"); 
          try { 
           List<File> files = worker.get(); 
          } catch (Exception e) { 
           e.printStackTrace(); 
          } 
         } 
        } else if ("path".equals(evt.getPropertyName())) { 
         File path = (File) evt.getNewValue(); 
         label.setText(path.toString()); 
        } 
       } 
      }); 
      worker.execute(); 
     } 

    } 

    public static class SearchWorker extends SwingWorker<List<File>, File> { 

     protected static final FileFilter DIRECTORY_FILE_FILTER = new FileFilter() { 
      @Override 
      public boolean accept(File pathname) { 
       return pathname.isDirectory(); 
      } 
     }; 

     private DefaultListModel model; 
     private File path; 
     private FileFilter fileFilter; 

     public SearchWorker(File path, FileFilter filter, DefaultListModel model) { 
      this.model = model; 
      this.path = path; 
      this.fileFilter = filter; 
     } 

     @Override 
     protected void process(List<File> chunks) { 
      for (File file : chunks) { 
       model.addElement(file); 
      } 
     } 

     @Override 
     protected List<File> doInBackground() throws Exception { 
      return new ArrayList<>(search(path)); 
     } 

     public List<File> search(File path) { 
      firePropertyChange("path", null, path); 
      List<File> files = new ArrayList<>(25); 
      if (path.exists() && path.isDirectory()) { 
       File[] list = path.listFiles(fileFilter); 
       if (list != null && list.length > 0) { 
        files.addAll(Arrays.asList(list)); 
        publish(list); 
       } 

       File[] dirs = path.listFiles(DIRECTORY_FILE_FILTER); 
       if (dirs != null) { 
        for (File dir : dirs) { 
         files.addAll(search(dir)); 
        } 
       } 
      } 

      return files; 
     } 

    } 

} 
+0

Может кто-нибудь указать причину downvote? – MadProgrammer

+0

попробовал ваш код, но этот поиск не поступает в каждую подпапку –

+0

хочу найти целую 'c' или любой другой диск –

Смежные вопросы