我已经在上一篇文章中解决了这个问题。 case insensitive for jTree。 有人说我应该为另一个问题创建另一个线程,所以这里是:D。 搜索时是否可以单击该文件夹。例如,我搜索“男孩”,树会给我 JTree节点和 BOYSSS节点。
我是否可以单击BOYSSS节点以查看里面有什么? 这是我的程序:
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
public final class FilteredJTreeExample {
public static void main(final String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("I DONT KNOW IF THIS WILL WORK, BUT WHATEVER MAN!!");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
private static void addComponentsToPane(final Container pane) {
pane.setLayout(new GridBagLayout());
JTree tree = createTree(pane);
JTextField filter = createFilterField(pane);
filter.getDocument().addDocumentListener(createDocumentListener(tree, filter));
}
private static JTree createTree(final Container pane) {
DefaultMutableTreeNode root = new DefaultMutableTreeNode("JTree");
FilteredTreeModel model = new FilteredTreeModel(new DefaultTreeModel(root));
JTree tree = new JTree(model);
JScrollPane scrollPane = new JScrollPane(tree);
GridBagConstraints c = new GridBagConstraints();
c.weightx = 1;
c.weighty = 1;
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 1;
pane.add(scrollPane, c);
createTreeNodes(root);
expandTree(tree);
return tree;
}
private static JTextField createFilterField(final Container pane) {
JTextField filter = new JTextField();
GridBagConstraints c = new GridBagConstraints();
c.weightx = 0;
c.weighty = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
pane.add(filter, c);
return filter;
}
private static DocumentListener createDocumentListener(final JTree tree, final JTextField filter) {
return new DocumentListener() {
@Override
public void insertUpdate(final DocumentEvent e) {
applyFilter();
}
@Override
public void removeUpdate(final DocumentEvent e) {
applyFilter();
}
@Override
public void changedUpdate(final DocumentEvent e) {
applyFilter();
}
public void applyFilter() {
FilteredTreeModel filteredModel = (FilteredTreeModel) tree.getModel();
filteredModel.setFilter(filter.getText());
DefaultTreeModel treeModel = (DefaultTreeModel) filteredModel.getTreeModel();
treeModel.reload();
expandTree(tree);
}
};
}
private static void expandTree(final JTree tree) {
for (int i = 0; i < tree.getRowCount(); i++) {
tree.expandRow(i);
}
}
private static void createTreeNodes(final DefaultMutableTreeNode node) {
DefaultMutableTreeNode ojt1 = new DefaultMutableTreeNode("BOYSSS");
ojt1.add(new DefaultMutableTreeNode("Rey"));
ojt1.add(new DefaultMutableTreeNode("Regi"));
ojt1.add(new DefaultMutableTreeNode("Geo"));
ojt1.add(new DefaultMutableTreeNode("Jerome"));
ojt1.add(new DefaultMutableTreeNode("Ryan"));
ojt1.add(new DefaultMutableTreeNode("Leo"));
ojt1.add(new DefaultMutableTreeNode("Ricardo"));
node.add(ojt1);
DefaultMutableTreeNode ojt2 = new DefaultMutableTreeNode("GIRLSS");
ojt2.add(new DefaultMutableTreeNode("Neri"));
ojt2.add(new DefaultMutableTreeNode("Chesca"));
ojt2.add(new DefaultMutableTreeNode("Diane"));
ojt2.add(new DefaultMutableTreeNode("Faye"));
ojt2.add(new DefaultMutableTreeNode("Mimi"));
ojt2.add(new DefaultMutableTreeNode("Shea"));
ojt2.add(new DefaultMutableTreeNode("Shane"));
ojt2.add(new DefaultMutableTreeNode("Lorraine"));
node.add(ojt2);
}
}
FilteredTreeModel类:
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
public final class FilteredTreeModel implements TreeModel {
private TreeModel treeModel;
private String filter;
public FilteredTreeModel(final TreeModel treeModel) {
this.treeModel = treeModel;
this.filter = "";
}
public TreeModel getTreeModel() {
return treeModel;
}
public void setFilter(final String filter) {
this.filter = filter;
}
private boolean recursiveMatch(final Object node, final String filter) {
boolean matches = node.toString().toLowerCase().contains(filter.toLowerCase());
int childCount = treeModel.getChildCount(node);
for (int i = 0; i < childCount; i++) {
Object child = treeModel.getChild(node, i);
matches |= recursiveMatch(child, filter);
}
return matches;
}
@Override
public Object getRoot() {
return treeModel.getRoot();
}
@Override
public Object getChild(final Object parent, final int index) {
int count = 0;
int childCount = treeModel.getChildCount(parent);
for (int i = 0; i < childCount; i++) {
Object child = treeModel.getChild(parent, i);
if (recursiveMatch(child, filter)) {
if (count == index) {
return child;
}
count++;
}
}
return null;
}
@Override
public int getChildCount(final Object parent) {
int count = 0;
int childCount = treeModel.getChildCount(parent);
for (int i = 0; i < childCount; i++) {
Object child = treeModel.getChild(parent, i);
if (recursiveMatch(child, filter)) {
count++;
}
}
return count;
}
@Override
public boolean isLeaf(final Object node) {
return treeModel.isLeaf(node);
}
@Override
public void valueForPathChanged(final TreePath path, final Object newValue) {
treeModel.valueForPathChanged(path, newValue);
}
@Override
public int getIndexOfChild(final Object parent, final Object childToFind) {
int childCount = treeModel.getChildCount(parent);
for (int i = 0; i < childCount; i++) {
Object child = treeModel.getChild(parent, i);
if (recursiveMatch(child, filter)) {
if (childToFind.equals(child)) {
return i;
}
}
}
return -1;
}
@Override
public void addTreeModelListener(final TreeModelListener l) {
treeModel.addTreeModelListener(l);
}
@Override
public void removeTreeModelListener(final TreeModelListener l) {
treeModel.removeTreeModelListener(l);
}
}