Swing/SortTree のバックアップ(No.8)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/SortTree へ行く。
- 1 (2009-05-07 (木) 10:47:07)
- 2 (2010-03-08 (月) 12:21:42)
- 3 (2010-03-08 (月) 13:41:04)
- 4 (2012-10-28 (日) 22:23:20)
- 5 (2013-01-09 (水) 21:08:32)
- 6 (2013-07-02 (火) 15:53:41)
- 7 (2013-07-03 (水) 13:11:51)
- 8 (2013-07-03 (水) 18:16:27)
- 9 (2013-07-04 (木) 20:49:38)
- 10 (2013-07-10 (水) 13:59:51)
- 11 (2013-09-05 (木) 00:41:57)
- 12 (2013-09-05 (木) 17:56:17)
- 13 (2014-03-18 (火) 18:57:40)
- 14 (2014-10-07 (火) 20:28:39)
- 15 (2014-10-08 (水) 00:47:28)
- 16 (2014-11-13 (木) 01:39:43)
- 17 (2014-11-18 (火) 20:14:35)
- 18 (2014-11-18 (火) 21:21:24)
- 19 (2014-11-21 (金) 18:31:49)
- 20 (2014-11-22 (土) 03:48:33)
- 21 (2014-11-25 (火) 03:03:31)
- 22 (2015-02-18 (水) 15:11:40)
- 23 (2015-03-09 (月) 14:46:02)
- 24 (2015-03-16 (月) 17:28:33)
- 25 (2016-11-04 (金) 14:55:38)
- 26 (2017-03-29 (水) 13:55:51)
- 27 (2017-04-07 (金) 13:51:51)
- 28 (2018-02-13 (火) 16:00:29)
- 29 (2018-02-24 (土) 19:51:30)
- 30 (2019-05-22 (水) 19:35:38)
- 31 (2020-01-30 (木) 18:49:11)
- 32 (2021-07-29 (木) 02:58:44)
- 33 (2025-01-03 (金) 08:57:02)
- 34 (2025-01-03 (金) 09:01:23)
- 35 (2025-01-03 (金) 09:02:38)
- 36 (2025-01-03 (金) 09:03:21)
- 37 (2025-01-03 (金) 09:04:02)
- 38 (2025-06-19 (木) 12:41:37)
- 39 (2025-06-19 (木) 12:43:47)
TITLE:JTreeのソート
Posted by aterai at 2009-05-04
JTreeのソート
`JTree
`をソートします。OTN Discussion Forums : How to sort jTree Nodesからの引用です。
- &jnlp;
- &jar;
- &zip;
サンプルコード
//Swing - How to sort jTree Nodes
//https://forums.oracle.com/forums/thread.jspa?threadID=1353435
public static DefaultMutableTreeNode sortTree(DefaultMutableTreeNode root) {
for(int i=0;i<root.getChildCount();i++) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) root.getChildAt(i);
String nt = node.getUserObject().toString();
for(int j=0; j<i; j++) {
DefaultMutableTreeNode prevNode = (DefaultMutableTreeNode) root.getChildAt(j);
String np = prevNode.getUserObject().toString();
if(nt.compareToIgnoreCase(np)<0) {
root.insert(node, j);
root.insert(prevNode, i);
}
}
if(node.getChildCount() > 0) node = sortTree(node);
}
return root;
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、チェックボックスをクリックすると`JTree
`を降順 昇順でソートするようになっています。
元のソート無しの状態に戻す場合は、`DefaultTreeModel
`を作成し直しています。
参考リンク
- OTN Discussion Forums : How to sort jTree Nodes
- `
#6
`のHamedさんの投稿
- `
コメント
- ソースにバグあります。 -- a?
- root.insert(prevNode, i);の後にi--; を入れる必要あり -- a?
- ご指摘ありがとうございます。たしかに`
i--;break
`などがないと、入れ替えられてソートされないノードが出来てしまいますね。効率も悪いので、深さ優先で深いところにある親ノードから別の方法でソートするのもいいかもしれません。しばらくテストしてこのサンプルは修正したいと思います。 -- aterai
- ご指摘ありがとうございます。たしかに`
//package example;
//-*- mode:java; encoding:utf-8 -*-
// vim:set fileencoding=utf-8:
//@homepage@
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.tree.*;
public class MainPanel extends JPanel {
private final DefaultMutableTreeNode root = makeTreeRoot();
private final JTree tree = new JTree(new DefaultTreeModel(makeTreeRoot()));
public MainPanel() {
super(new BorderLayout());
Box box = Box.createHorizontalBox();
box.add(new JCheckBox(new AbstractAction("0") {
@Override public void actionPerformed(ActionEvent e) {
JCheckBox check = (JCheckBox)e.getSource();
DefaultMutableTreeNode r = deepCopyTree(root, (DefaultMutableTreeNode)root.clone());
compare_count = 0;
swap_count = 0;
sortTree0(r);
System.out.format("compare: %d, swap: %d%n", compare_count, swap_count);
tree.setModel(new DefaultTreeModel(check.isSelected()?r:root));
expandAll(tree);
}
}));
box.add(new JCheckBox(new AbstractAction("1") {
@Override public void actionPerformed(ActionEvent e) {
JCheckBox check = (JCheckBox)e.getSource();
DefaultMutableTreeNode r = deepCopyTree(root, (DefaultMutableTreeNode)root.clone());
compare_count = 0;
swap_count = 0;
sortTree1(r);
System.out.format("compare: %d, swap: %d%n", compare_count, swap_count);
tree.setModel(new DefaultTreeModel(check.isSelected()?r:root));
expandAll(tree);
}
}));
box.add(new JCheckBox(new AbstractAction("2") {
@Override public void actionPerformed(ActionEvent e) {
JCheckBox check = (JCheckBox)e.getSource();
DefaultMutableTreeNode r = deepCopyTree(root, (DefaultMutableTreeNode)root.clone());
compare_count = 0;
swap_count = 0;
sortTree2(r);
System.out.format("compare: %d, swap: %d%n", compare_count, swap_count);
tree.setModel(new DefaultTreeModel(check.isSelected()?r:root));
expandAll(tree);
}
}));
box.add(new JCheckBox(new AbstractAction("3") {
@Override public void actionPerformed(ActionEvent e) {
JCheckBox check = (JCheckBox)e.getSource();
DefaultMutableTreeNode r = deepCopyTree(root, (DefaultMutableTreeNode)root.clone());
compare_count = 0;
swap_count = 0;
sortTree3(r);
System.out.format("compare: %d, swap: --%n", compare_count);
tree.setModel(new DefaultTreeModel(check.isSelected()?r:root));
expandAll(tree);
}
}));
box.add(new JCheckBox(new AbstractAction("4") {
@Override public void actionPerformed(ActionEvent e) {
JCheckBox check = (JCheckBox)e.getSource();
DefaultMutableTreeNode r = deepCopyTree(root, (DefaultMutableTreeNode)root.clone());
compare_count = 0;
swap_count = 0;
sortTree4(r);
System.out.format("compare: %d, swap: %d%n", compare_count, swap_count);
tree.setModel(new DefaultTreeModel(check.isSelected()?r:root));
expandAll(tree);
}
}));
add(box, BorderLayout.SOUTH);
add(makeTitledPanel("Sort JTree", tree));
expandAll(tree);
setPreferredSize(new Dimension(320, 200));
}
private static DefaultMutableTreeNode deepCopyTree(DefaultMutableTreeNode src, DefaultMutableTreeNode tgt) {
for(int i=0; i<src.getChildCount(); i++) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)src.getChildAt(i);
DefaultMutableTreeNode clone = new DefaultMutableTreeNode(node.getUserObject());
//DefaultMutableTreeNode clone = (DefaultMutableTreeNode)node.clone();
tgt.add(clone);
if(!node.isLeaf()) {
deepCopyTree(node, clone);
}
}
return tgt;
}
private JComponent makeTitledPanel(String title, JTree tree) {
JPanel p = new JPanel(new BorderLayout());
p.setBorder(BorderFactory.createTitledBorder(title));
p.add(new JScrollPane(tree));
return p;
}
public static int compare_count = 0;
public static int swap_count = 0;
public static TreeNodeComparator tnc = new TreeNodeComparator();
//Swing - How to sort jTree Nodes
//https://forums.oracle.com/forums/thread.jspa?threadID=1353435
public static boolean DEBUG = true;
public static void sortTree0(DefaultMutableTreeNode root) {
for(int i=0;i<root.getChildCount();i++) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) root.getChildAt(i);
for(int j=0; j<i; j++) {
DefaultMutableTreeNode prevNode = (DefaultMutableTreeNode) root.getChildAt(j);
compare_count++;
if(tnc.compare(node, prevNode)<0) {
root.insert(node, j);
root.insert(prevNode, i);
swap_count++;
if(DEBUG) {
i--;
break;
}
}
}
if(node.getChildCount() > 0) sortTree0(node);
}
}
public static void sortTree1(DefaultMutableTreeNode root) {
int n = root.getChildCount();
for(int i=0;i<n-1;i++) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) root.getChildAt(i);
for(int j=i+1; j<n; j++) {
DefaultMutableTreeNode prevNode = (DefaultMutableTreeNode) root.getChildAt(j);
if(tnc.compare(node, prevNode)>0) {
swap_count++;
root.insert(node, j);
root.insert(prevNode, i);
i--;
break;
}
}
if(node.getChildCount() > 0) sortTree1(node);
}
}
public static void sort2(DefaultMutableTreeNode parent) {
int n = parent.getChildCount();
for(int i=0; i<n-1; i++) {
int min = i;
for(int j=i+1; j<n; j++) {
if(tnc.compare(
(DefaultMutableTreeNode)parent.getChildAt(min),
(DefaultMutableTreeNode)parent.getChildAt(j))>0) {
min = j;
}
}
if(i!=min) {
swap_count++;
MutableTreeNode a = (MutableTreeNode)parent.getChildAt(i);
MutableTreeNode b = (MutableTreeNode)parent.getChildAt(min);
parent.insert(b, i);
parent.insert(a, min);
//MutableTreeNode node = (MutableTreeNode)parent.getChildAt(min);
//parent.insert(node, i);
//compare_count++;
}
}
}
public static void sortTree2(DefaultMutableTreeNode root) {
Enumeration e = root.depthFirstEnumeration();
while(e.hasMoreElements()) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)e.nextElement();
if(!node.isLeaf()) {
sort2(node);
}
}
}
public static void sort3(DefaultMutableTreeNode parent) {
int n = parent.getChildCount();
@SuppressWarnings("unchecked")
Enumeration<DefaultMutableTreeNode> e = parent.children();
ArrayList<DefaultMutableTreeNode> children = Collections.list(e);
//java.util.List<DefaultMutableTreeNode> children = new ArrayList<DefaultMutableTreeNode>(n);
//for(int i=0; i<n; i++) {
// children.add((DefaultMutableTreeNode)parent.getChildAt(i));
//}
Collections.sort(children, tnc);
parent.removeAllChildren();
for(MutableTreeNode node: children) {
parent.add(node);
}
}
public static void sortTree3(DefaultMutableTreeNode root) {
Enumeration e = root.depthFirstEnumeration();
while(e.hasMoreElements()) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)e.nextElement();
if(!node.isLeaf()) {
sort3(node);
}
}
}
public static void sortTree4(DefaultMutableTreeNode root) {
Enumeration e = root.children();
while(e.hasMoreElements()) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)e.nextElement();
if(!node.isLeaf()) {
sortTree4(node);
}
}
sort2(root);
}
static class TreeNodeComparator implements Comparator<DefaultMutableTreeNode>{
@Override public int compare(DefaultMutableTreeNode a, DefaultMutableTreeNode b) {
compare_count++;
if(a.isLeaf() && !b.isLeaf()) {
return 1;
}else if(!a.isLeaf() && b.isLeaf()) {
return -1;
}else{
String sa = a.getUserObject().toString();
String sb = b.getUserObject().toString();
return sa.compareToIgnoreCase(sb);
}
}
}
private static DefaultMutableTreeNode makeTreeRoot() {
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
DefaultMutableTreeNode set1 = new DefaultMutableTreeNode("Set 001");
DefaultMutableTreeNode set2 = new DefaultMutableTreeNode("Set 002");
DefaultMutableTreeNode set3 = new DefaultMutableTreeNode("Set 003");
DefaultMutableTreeNode set4 = new DefaultMutableTreeNode("Set 004");
set1.add(new DefaultMutableTreeNode("3333333333333333"));
set1.add(new DefaultMutableTreeNode("111111111"));
set1.add(new DefaultMutableTreeNode("22222222222"));
set1.add(set4);
set1.add(new DefaultMutableTreeNode("22222222222"));
set1.add(new DefaultMutableTreeNode("22222222222"));
set2.add(new DefaultMutableTreeNode("eeeeeeeeeeeee"));
set2.add(new DefaultMutableTreeNode("bbbbbbbbbbbb"));
set3.add(new DefaultMutableTreeNode("zzzzzzz"));
set3.add(new DefaultMutableTreeNode("aaaaaaaaaaaa"));
set3.add(new DefaultMutableTreeNode("ccccccccc"));
set4.add(new DefaultMutableTreeNode("22222222222"));
set4.add(new DefaultMutableTreeNode("eeeeeeeeeeeee"));
set4.add(new DefaultMutableTreeNode("bbbbbbbbbbbb"));
set4.add(new DefaultMutableTreeNode("zzzzzzz"));
root.add(new DefaultMutableTreeNode("xxxxxxxxxxxxx"));
root.add(set3);
root.add(new DefaultMutableTreeNode("eeeeeeeeeeeee"));
root.add(set1);
root.add(set2);
root.add(new DefaultMutableTreeNode("22222222222"));
root.add(new DefaultMutableTreeNode("bbbbbbbbbbbb"));
return root;
}
private void expandAll(JTree tree) {
int row = 0;
while(row<tree.getRowCount()) {
tree.expandRow(row);
row++;
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
try{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(Exception e) {
e.printStackTrace();
}
JFrame frame = new JFrame("@title@");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().add(new MainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}