Java 按字母顺序排列 Jtree 节点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9714328/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sort Jtree Node Alphabetically
提问by Jony
I have loaded my JTree to view My directory structure as shown in my code and output image. Here, Tree nodes are by default sorted in alphabetical order, but my other requirement is that I want to sort all nodes according to second name of directory name without actually renaming the directory. I have underlined the name on which I need to sort the JTree node. Please suggest me something.
我已经加载了我的 JTree 来查看我的目录结构,如我的代码和输出图像所示。在这里,树节点默认按字母顺序排序,但我的另一个要求是我想根据目录名称的第二个名称对所有节点进行排序,而无需实际重命名目录。我在我需要对 JTree 节点进行排序的名称下划线。请给我建议。
import java.io.File;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
public class FILE_NAME {
public static void main(String[] args) {
JFrame frame = new JFrame("My Jtree");
File root = new File("C:/java");
JTree tree = new JTree(new FileTreeModel(root));
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(tree);
frame.setVisible(true);
}
}
class FileTreeModel implements TreeModel {
protected File root;
public FileTreeModel(File root) {
this.root = root;
}
@Override
public Object getRoot() {
return root;
}
@Override
public boolean isLeaf(Object node) {
return ((File) node).isFile();
}
@Override
public int getChildCount(Object parent) {
String[] children = ((File) parent).list();
if (children == null) {
return 0;
}
return children.length;
}
@Override
public Object getChild(Object parent, int index) {
String[] children = ((File) parent).list();
if ((children == null) || (index == children.length)) {
return null;
}
return new File((File) parent, children[index]);
}
@Override
public int getIndexOfChild(Object parent, Object child) {
String[] children = ((File) parent).list();
String childname = ((File) child).getName();
if (children == null) {
return -1;
}
for (int i = 0; i == children.length; i++) {
if (childname.equals(children[i])) {
return i;
}
}
return -1;
}
@Override
public void valueForPathChanged(TreePath path, Object newvalue) {
}
@Override
public void addTreeModelListener(TreeModelListener l) {
}
@Override
public void removeTreeModelListener(TreeModelListener l) {
}
}
OUTPUT
输出
采纳答案by yggdraa
you can use Arrays.sort() method that uses Comparator, and write your own comparator which compares entries by your own rules, like that:
您可以使用使用 Comparator 的 Arrays.sort() 方法,并编写自己的比较器,根据您自己的规则比较条目,如下所示:
String[] children = ((File) parent).list();
Arrays.sort(children, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
// do your comparison
}
});
In the model methods it will be overload, so you may consider to save directory listing in some model private field and check if directory was not changed in model methods invocation (comparing File.lastModified() will help). If it was - save new listing.
在模型方法中它将被重载,因此您可以考虑将目录列表保存在某些模型私有字段中并检查目录是否在模型方法调用中没有更改(比较 File.lastModified() 会有所帮助)。如果是 - 保存新列表。
回答by Adrian
It goes like this :
它是这样的:
public void sortTree() {
treeModel.reload(sort(rootNode));
}
public DefaultMutableTreeNode sort(DefaultMutableTreeNode node) {
//sort alphabetically
for(int i = 0; i < node.getChildCount() - 1; i++) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) node.getChildAt(i);
String nt = child.getUserObject().toString();
for(int j = i + 1; j <= node.getChildCount() - 1; j++) {
DefaultMutableTreeNode prevNode = (DefaultMutableTreeNode) node.getChildAt(j);
String np = prevNode.getUserObject().toString();
System.out.println(nt + " " + np);
if(nt.compareToIgnoreCase(np) > 0) {
node.insert(child, j);
node.insert(prevNode, i);
}
}
if(child.getChildCount() > 0) {
sort(child);
}
}
//put folders first - normal on Windows and some flavors of Linux but not on Mac OS X.
for(int i = 0; i < node.getChildCount() - 1; i++) {
DefaultMutableTreeNode child = (DefaultMutableTreeNode) node.getChildAt(i);
for(int j = i + 1; j <= node.getChildCount() - 1; j++) {
DefaultMutableTreeNode prevNode = (DefaultMutableTreeNode) node.getChildAt(j);
if(!prevNode.isLeaf() && child.isLeaf()) {
node.insert(child, j);
node.insert(prevNode, i);
}
}
}
return node;
}
回答by Candamir
The most flexible solution is to build a simple extension of DefaultMutableTreeNode
that sorts the node's children every time a new element is added (credit to this articlefor the general idea):
最灵活的解决方案是构建一个简单的扩展,DefaultMutableTreeNode
每次添加新元素时都会对节点的子节点进行排序(总体思路归功于本文):
public class SimpleTreeNode
extends DefaultMutableTreeNode
{
private final Comparator comparator;
public SimpleTreeNode(Object userObject, Comparator comparator)
{
super(userObject);
this.comparator = comparator;
}
public SimpleTreeNode(Object userObject)
{
this(userObject,null);
}
@Override
public void add(MutableTreeNode newChild)
{
super.add(newChild);
if (this.comparator != null)
{
Collections.sort(this.children,this.comparator);
}
}
}
This solution is very flexible because it allows you to have different sorting methods for each level of the tree or even for each folder. (Of course you can also very easily use the same or no Comparator
everywhere.)
此解决方案非常灵活,因为它允许您对树的每个级别甚至每个文件夹使用不同的排序方法。(当然,您也可以非常轻松地在任何Comparator
地方使用相同或不使用。)
In case this helps anyone, see below two sorting methods that I have used with SimpleTreeNode
:
如果这对任何人有帮助,请参阅下面我使用的两种排序方法SimpleTreeNode
:
public class Comparators
{
/** Allows alphabetical or reverse-alphabetical sorting
*
*/
public static class AlphabeticalComparator
implements Comparator
{
private final boolean order;
public AlphabeticalComparator()
{
this(true);
}
public AlphabeticalComparator(boolean order)
{
this.order = order;
}
@Override
public int compare(Object o1, Object o2)
{
if (order)
{
return o1.toString().compareTo(o2.toString());
}
else
{
return o2.toString().compareTo(o1.toString());
}
}
}
/** Allows sorting according to a pre-defined array
*
*/
public static class OrderComparator
implements Comparator
{
private final String[] strings;
public OrderComparator(String[] strings)
{
this.strings = strings;
}
@Override
public int compare(Object o1, Object o2)
{
String s1 = o1.toString();
String s2 = o2.toString();
int i1 = -1;
int i2 = -1;
for (int j = 0; j < strings.length; j++)
{
if (s1.equals(strings[j]))
{
i1 = j;
}
if (s2.equals(strings[j]))
{
i2 = j;
}
}
if (i1 == -1 || i2 == -1)
{
throw new Error("Can't use this comparator to compare "+o1+" and "+o2);
}
else
{
return Integer.compare(i1,i2);
}
}
}
}