Java 根据来自JTextField的输入在JTree中过滤结果

Java 根据来自JTextField的输入在JTree中过滤结果,java,jtree,file-search,Java,Jtree,File Search,这是我的程序的摘要 列出指定目录中具有X扩展名的所有文件夹、子文件夹和文件。您可以查看、编辑、复制等文件的内容。每个文件都有一个与之关联的.dat文件,其中包含关键字和上次使用日期等信息 现在我正在创建一个过滤器。它应该过滤的方式是接收输入的文本并返回任何文件夹和文件,其中包含过滤器的名称、包含关键字的文件以及包含内容的文件 很简单,对吧 我唯一的问题是,它将根据文件的位置执行以下操作之一 如果这很难理解,我道歉。下面是从我的真实程序中复制和清理的功能代码。使用ApacheCommons2.4

这是我的程序的摘要

列出指定目录中具有X扩展名的所有文件夹、子文件夹和文件。您可以查看、编辑、复制等文件的内容。每个文件都有一个与之关联的.dat文件,其中包含关键字和上次使用日期等信息

现在我正在创建一个过滤器。它应该过滤的方式是接收输入的文本并返回任何文件夹和文件,其中包含过滤器的名称、包含关键字的文件以及包含内容的文件

很简单,对吧

我唯一的问题是,它将根据文件的位置执行以下操作之一

如果这很难理解,我道歉。下面是从我的真实程序中复制和清理的功能代码。使用ApacheCommons2.4


问题在于滤波算法

您没有再次调用子组件上的筛选器而不是addNodesfile,您必须调用addNodesfile,filter

目录节点,其中仅在匹配时添加,而不在子组件匹配时添加

使代码正常工作的快速破解方法如下所示:替换addNodes方法:

if folder matches
-> only lists to that folder, but not contents

if file matches
-> only lists file if its in JTree root

if file matches but is in a folder which doesnt match
-> doesnt display
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.io.File;

import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeSelectionModel;

import org.apache.commons.io.FileUtils;

public class NGui {

    JFrame frame;
    private JTree tree;
    private JTextField jtf;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager
                            .getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }
                new NGui();
            }
        });
    }

    public NGui() {
        initialize();
    }

    private void initialize() {
        frame = new JFrame();
        frame.getContentPane().setLayout(null);
        frame.setSize(250, 400);

        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setBounds(10, 50, 200, 300);
        frame.getContentPane().add(scrollPane);

        tree = new JTree(addNodes(new File(getWorkPath())));
        tree.setRootVisible(true);
        tree.setShowsRootHandles(true);

        tree.setBorder(new LineBorder(new Color(0, 0, 0)));
        tree.getSelectionModel().setSelectionMode(
                TreeSelectionModel.SINGLE_TREE_SELECTION);
        scrollPane.setViewportView(tree);

        tree.getSelectionModel().addTreeSelectionListener(
                new TreeSelectionListener() {
                    @Override
                    public void valueChanged(TreeSelectionEvent e) {
                        treeValueChanged(e);
                    }
                });
        tree.setCellRenderer(new FileTreeCellRenderer());

        jtf = new JTextField();
        jtf.setBorder(new LineBorder(new Color(0, 0, 0)));
        jtf.setBounds(10, 10, 150, 25);
        Object actionKey = jtf.getInputMap(JComponent.WHEN_FOCUSED).get(
                KeyStroke.getKeyStroke("ENTER"));
        jtf.getActionMap().put(actionKey, new AbstractAction() {
            private static final long serialVersionUID = 1L;

            @Override
            public void actionPerformed(ActionEvent ae) {
                try {
                    filterResults(ae);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        frame.getContentPane().add(jtf);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private void treeValueChanged(TreeSelectionEvent e) {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
                .getLastSelectedPathComponent();
        log("Selected Node: " + node);
    }

    private void log(Object o) {
        System.out.println(o);
    }

    private String getWorkPath() {
        return ".";
    }

    public void filterResults(ActionEvent ae) throws Exception {

        final String str = jtf.getText();
        reloadTree("."); // refreshes from any previous searches

        DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel()
                .getRoot();

        reloadTree(root.toString(), str);
    }

    public DefaultMutableTreeNode addNodes(File dir, String filter)
            throws Exception {
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(dir);
        for (File file : dir.listFiles()) {

            if (file.isDirectory()) {
                if (file.getPath().contains(filter)) {
                    log("adding: " + file.toString());
                    node.add(addNodes(file));
                }
            } else {
                // apache commons 2.4
                String tmpContent = FileUtils.readFileToString(file);
                if (file.getPath().contains(filter)
                        || tmpContent.contains(filter)) {
                    log("adding: " + file.toString());
                    node.add(new DefaultMutableTreeNode(file));
                }

            }
        }
        return node;
    }

    public DefaultMutableTreeNode addNodes(File dir) {
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(dir);
        for (File file : dir.listFiles()) {
            if (file.isDirectory()) {
                node.add(addNodes(file));
            } else {
                node.add(new DefaultMutableTreeNode(file));
            }
        }
        return node;
    }

    public void reloadTree(final String path) {
        DefaultMutableTreeNode dn = addNodes(new File(path));
        tree.setModel(new DefaultTreeModel(dn));
    }

    public void reloadTree(final String path, final String filter)
            throws Exception {
        DefaultMutableTreeNode dn = addNodes(new File(path), filter);
        tree.setModel(new DefaultTreeModel(dn));
    }

    public class FileTreeCellRenderer extends DefaultTreeCellRenderer {
        private static final long serialVersionUID = 1L;
        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value,
                boolean sel, boolean expanded, boolean leaf, int row,
                boolean hasFocus) {
            if (value instanceof DefaultMutableTreeNode) {
                value = ((DefaultMutableTreeNode) value).getUserObject();
                if (value instanceof File) {
                    value = ((File) value).getName();
                }
            }
            return super.getTreeCellRendererComponent(tree, value, sel,
                    expanded, leaf, row, hasFocus);
        }
    }

}
public DefaultMutableTreeNode addNodes(File dir, String filter)
        throws Exception {
    DefaultMutableTreeNode node = new DefaultMutableTreeNode(dir);
    //true iff any subcomponent matches
    boolean matchFound = false;
    for (File file : dir.listFiles()) {

        if (file.isDirectory()) {
            if (file.getName().contains(filter)) {
                matchFound = true;
            } 
            //always call addNodes on directories, because subcomponents may match
            //null return value indicates no match (with Java 8 use Optional for this)
            DefaultMutableTreeNode maybeNode = addNodes(file, filter);
            if(maybeNode != null) {
                matchFound = true;
                node.add(maybeNode);
            }
        } else {
            // apache commons 2.4
            String tmpContent = FileUtils.readFileToString(file);
            if (file.getName().contains(filter)
                    || tmpContent.contains(filter)) {
                matchFound = true;
                log("adding file: " + file.toString());
                node.add(new DefaultMutableTreeNode(file));
            }
        }
    }
    //only return node if node itself or subcomponent matches
    if(matchFound || dir.getName().contains(filter)) {
        return node;
    }
    //return null otherwise
    return null;
}