JTree mit Verzeichnissen füllen

Hab mal eine Lösung zusammengestellt, wo man zwei Sortierverfahren auswählen kann:
Code:
/**
 * 
 */
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeMap;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;

/**
 * @author Manuel Beck
 * 
 */
public class JTreeDirectoryView extends JFrame {

    File root;    
    JTree tree;
    Comparator currentComparator = comparator2;

    final static Comparator comparator = new Comparator() {


            public int compare(Object o1, Object o2) {
 
                File file1 = (File)o1;
                File file2 = (File)o2;
                             
                if (file1.isDirectory() && file2.isDirectory()){
                    return file1.getName().compareTo(file2.getName());
                } else if (file1.isDirectory()){
                    return -1;
                }
                else if (file2.isDirectory()) {
                    return +1;
                }                                

                int point1 = file1.getName().lastIndexOf(".");
                int point2 = file2.getName().lastIndexOf(".");
                
                if (point1 == -1 || point2 == -1) return -1;
                
                String fileEnd1 = file1.getName().substring(point1+1, file1.getName().length()-1).toLowerCase();
                String fileEnd2 = file2.getName().substring(point2+1, file2.getName().length()-1).toLowerCase();

                
                int result =  fileEnd1.compareTo(fileEnd2);
                
                if (result == 0) return file1.getName().compareTo(file2.getName());
                
                return result;
                        
                
            }
        };
       final static Comparator comparator2 = new Comparator() {

            public int compare(Object o1, Object o2) {
 
                File file1 = (File)o1;
                File file2 = (File)o2;
                             
               
                    return file1.getName().compareTo(file2.getName());
            
                
            }
        };
       

    public JTreeDirectoryView() {
        super("JTreeDirectoryView");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

       tree = new JTree();
        buildTreeModelAccordingToDirectoryStructure(root = new File("C:/"),
                tree);

        getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
        
        getContentPane().add(new JButton(new AbstractAction("Nach DateiTyp sortieren") {

            public void actionPerformed(ActionEvent e) {
                currentComparator = comparator;
                tree.updateUI();
            }
            
        }),BorderLayout.SOUTH);
        getContentPane().add(new JButton(new AbstractAction("Nach Name sortieren") {

            public void actionPerformed(ActionEvent e) {
                currentComparator = comparator2;
                tree.updateUI();
            }
            
        }),BorderLayout.NORTH);
        tree.addTreeSelectionListener(new TreeSelectionListener() {
            public void valueChanged(TreeSelectionEvent e) {
                FileSystemTreeNode treeNode = (FileSystemTreeNode)e.getNewLeadSelectionPath().getLastPathComponent();
                File f = (File)treeNode.getUserObject();
                
                System.out.println("Gewählte Datei: " + f.getName());
                System.out.println("Ist ein Ordner: " + f.isDirectory());
            } 
        });
        
        pack();
        setVisible(true);
    }

    void buildTreeModelAccordingToDirectoryStructure(File file, JTree tree) {
        tree.setModel(new DefaultTreeModel(new FileSystemTreeNode(file)));
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        new JTreeDirectoryView();
    }

    class FileSystemTreeNode extends DefaultMutableTreeNode {
 
        ArrayList<File> currentFiles;

        public FileSystemTreeNode(File file) {
            setUserObject(file);
        }

        public int getChildCount() {
            filterDirectories((File) getUserObject());

            if (currentFiles == null) {
                return 0;
            }
            
            return currentFiles.size();
        }

        public TreeNode getChildAt(int index) {
            filterDirectories((File) getUserObject());

            return new FileSystemTreeNode(currentFiles.get(index));
        }

        public boolean isLeaf() {
            
            if (((File)getUserObject()).isFile()) return true;
            return false;
        }

        public String toString() {
            String string = ((File) getUserObject()).getName();
            if (getUserObject() == root) {
                string = ((File) getUserObject()).getAbsolutePath();
            }
            return string;
        }

        private void filterDirectories(File file) {

            TreeMap directoryList = new TreeMap(currentComparator);

            if (file.isDirectory()) {

                File[] files = file.listFiles();

                for (int i = 0; i < files.length; i++) {

                    directoryList.put(files[i], files[i]);
                                
                }

                currentFiles = new ArrayList<File>();
                for(Object o: directoryList.values()) {
                    File f = (File)o;
                    
                    currentFiles.add(f);
                }
            } else {
                currentFiles = new ArrayList<File>();
                currentFiles.add(file);
            }
        }

    }
}

Gruß, Manuel
 
Zuletzt bearbeitet:
Danke fuer die schnelle antwort! Soweit erstmal keine weitere probleme. Danke fuer einen weiteren hilfreichen einblick in die java-welt ;)

MfG,
eXti
 
Habe gerade nochmal einen kleinen Fehler entdeckt und behoben. Mein Comparator hat teilweise Dateien rausgeschmissen, die die selbe Dateitypendung haben. Jetzt prüf ich bei Gleichheit der Endungen, noch auf den Dateinamen und alle Dateien bleiben erhalten.

Gruß, Manuel
 
Joa, Comparator ist wohl zur zeit meine groesste schwaeche, warum ich auch erst mich in diesem thread gemeldet hab. Koenntest den code deines ueberarbeiteten comparators verraten? Hab da keinen blassen schimmer :) Bei interesse kann ich auch mal zeigen, woran ich arbeite :)
 
also ich habe jetzt einfach das was du geschrieben hast in code umgesetzt, und tatsaechlich schmeisst er die dateien nicht mehr raus und sortiert nach dateiendungen.

Code:
if (fileEnd1.compareTo(fileEnd2) == 0) {
  return file1.getName().compareTo(file2.getName());
}
return fileEnd1.compareTo(fileEnd2);

statt return fileEnd1.compareTo(fileEnd2); was du ja hattest.

Aber ehrlich gesagt, verstehe ich nicht warum das zum erfolg fuehrt... bzw den bug behebt.. Eine kleine erklaerung waere sehr wissensdurst-loeschend.

Danke im vorraus,
eXti
 
Das Problem war zuvor, dass nur auf das Dateiende geprüft wurde. Wurde jetzt zweimal die selbe Dateiendung verglichen kam bei der Rückgabe von compareTo() = 0 raus, was heißt, dass keine Bewegung in der Liste stattfindet und die zweite zuvergleichende Datei rausfliegt.
So wurde dann maximal nur ein Dateityp angezeigt und viele Dateien gingen unter.

Jetzt prüfen wir bei Gleichheit des Dateityps noch auf den Dateinamen, was dazuführt, dass unsere doppelten Dateitypen nicht rausfliegen und die Dateien selber Alphabetisch sortiert werden.

Ich hoffe ich konnte helfen:)

Gruß, Manu
 
JTree mit Werten aus DB befüllen

Hallo Forum,

habe durch Google eure tollen Tips gefunden um ein Verzeichnis in ein JTree zu packen.

Mein Problem ist allerding das ich ein Shop-Menü (CAO-Faktura) aus einer Datenbank in ein JTree laden muss.

So siehts in der DB aus:

SHOP_ID | ID | TOP_ID | SORT_NUM | NAME
1 1 0 1 Node_Kat1
1 2 1 0 Entry_1
1 3 0 0 Node_Kat2
1 4 3 0 Node_SubKat1
1 5 3 0 Entry_2
1 6 4 0 Node_SubKat2
1 7 6 0 Entry_3
1 8 0 0 Entry_4


Das Menü sollte so aussehen:

ROOT
|
+ Node_Kat2
| |
| --- Entry_2
| + Node_SubKat_1
| |
| + Node_SubKat_2
| |
| --- Entry_3
--- Entry_4
+ Node_Kat_1
|
---- Entry_1


Was ich bisher gemacht habe....

Code:
private JTree getJTree(){
   ......
   ResultSet rsK = sql.select("SELECT * FROM ARTIKEL_KAT WHERE SHOP_ID=1 AND TOP_ID=0 ORDER BY SORT_NUM");
	while(rsK.next()){
	   	 id = rsK.getInt("ID");
	    	 top_id = rsK.getInt("TOP_ID");
	    	 child = new DefaultMutableTreeNode();
	    	 child = this.goDeeper(1,id,0);
	    	 root.add(child);
			    	 
			    	 
	}

..........
}


private DefaultMutableTreeNode goDeeper(int shop_id,int id,int top_id){
		DefaultMutableTreeNode retVal = new DefaultMutableTreeNode();
		
		try{
			ResultSet rsTmp = sql.select("SELECT * FROM ARTIKEL_KAT WHERE SHOP_ID="+shop_id+" AND TOP_ID="+id+" ORDER BY SORT_NUM");
	    	 
			while(rsTmp.next()){
	    		 ResultSet rsTmp2 = sql.select("SELECT * FROM ARTIKEL_KAT WHERE SHOP_ID="+shop_id+" AND ID="+id+" ORDER BY SORT_NUM");
	    		 while(rsTmp2.next()){	    			 
	    			 retVal = new DefaultMutableTreeNode(rsTmp2.getString("Name"));	    			 
	    		 }
	    		 
	    		 retVal.add(goDeeper(shop_id,rsTmp.getInt("ID"),rsTmp.getInt("TOP_ID"))) ;
            }
			
			rsTmp.beforeFirst();
				if(!rsTmp.next()){
	    		 ResultSet rsK = sql.select("SELECT * FROM ARTIKEL_KAT WHERE SHOP_ID="+shop_id+" AND TOP_ID="+top_id+" AND ID= "+id+" ORDER BY SORT_NUM");
	    		 while(rsK.next()){
	    			 retVal = new DefaultMutableTreeNode(rsK.getString("Name"));
	    		 }
	    		 
	    	 }
		}catch(Exception e){
			...
		}
   	 	return retVal;
	}

Ich denke ich müsste das "retVal" immer wieder an "goDeeper" übergeben und den neuen "retVal" daran anhängen...... aber ich schaffs einfach nicht :-(

kann mir jamand helfen ?

lg
slacki
 
Zurück