本文介绍了单击搜索按钮后,JList不会填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在Java GUI应用程序中编写了一个递归搜索方法,以在驱动器中查找文件.
用户界面具有响应性,
搜索成功完成,但JList没有填充,而控制台成功打印了文件名,在JList中添加了3次单击搜索按钮的文件后,每个文件都重复了名称

I've written a recursive search method in java GUI application to find a file in a drive.
UI is responsive,
Search happened successfully but JList does not populate,whereas console prints file names successfully, after 3 clicks on search button files are added in JList but with repeated names of each file

     //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();

}

推荐答案

基本问题是,您实际上并没有修改ListModel.

The basic problem is, you're not actually modifying the ListModel in anyway.

Swing是一个单线程环境,您已经使用Thread来确保执行搜索时不会阻塞UI,这很好,但是Swing也不是线程安全的,这意味着您不应该t从事件调度线程的上下文外部更新UI,因此Thread是错误的.

Swing is a single threaded environment, you've used a Thread to ensure that the UI is not blocked while the search is carried out, which is good, but Swing is also not thread safe, meaning that you shouldn't update the UI from outside of the context of the Event Dispatching Thread, so the Thread is bad.

尽管您可以"使用ThreadSwingWorker可以为该问题提供更好(通常更简单)的解决方案(更不用说可重用的问题了)

While you "could" use a Thread, a SwingWorker would present a better (and generally simpler) solution to the problem (not to mention a more reusable one)

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

}

然后,您只需使用...来启动它即可.

Then you would simply start it using something like...

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和SwingWorker

See Worker Threads and SwingWorker for more details

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

    }

}

这篇关于单击搜索按钮后,JList不会填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 02:22