ich möchte einen JTree erstellen der mir von einem Ordner ausgehend z.B. c:\\ nun alle ordner auflistet die dateien mit der endung .dat enthalten. Also so richtig Pfadmäsig usw. Der Baum soll sich so durch die Pfadstruktur ziehen, jedoch nur die Pfäde mit einer .dat Datei.
Gibt es da etwas anderes als den JTree, oder muss ich hier nun etwas aufwendigeres programmieren um dies zu erreichen?
ok ich habe mal bisschen gegoogelt und folgendes gefunden
Code:
import java.io.File;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
/**
* The methods in this class allow the JTree component to traverse
* the file system tree, and display the files and directories.
**/
public class FileTreeModel implements TreeModel
{
// We specify the root directory when we create the model.
protected File root;
public FileTreeModel(File root)
{
this.root = root;
}
// The model knows how to return the root object of the tree
public Object getRoot()
{
return root;
}
// Tell JTree whether an object in the tree is a leaf or not
public boolean isLeaf(Object node)
{
if(node.toString().contains(".properties"))
{
return ((File)node).isFile();
}
else
{
return false;
}
}
// Tell JTree how many children a node has
public int getChildCount(Object parent) {
String[] children = ((File)parent).list();
if (children == null)
return 0;
return children.length;
}
// Fetch any numbered child of a node for the JTree.
// Our model returns File objects for all nodes in the tree. The
// JTree displays these by calling the File.toString() method.
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]);
}
// Figure out a child's position in its parent node.
public int getIndexOfChild(Object parent, Object child)
{
String[] children = ((File)parent).list();
if (children == null)
return -1;
String childname = ((File)child).getName();
for(int i = 0; i < children.length; i++)
{
if (childname.equals(children[i]))
return i;
}
return -1;
}
// This method is only invoked by the JTree for editable trees.
// This TreeModel does not allow editing, so we do not implement
// this method. The JTree editable property is false by default.
public void valueForPathChanged(TreePath path, Object newvalue) {}
// Since this is not an editable tree model, we never fire any events,
// so we don't actually have to keep track of interested listeners.
public void addTreeModelListener(TreeModelListener l) {}
public void removeTreeModelListener(TreeModelListener l) {}
}
Code:
private void tree()
{
File root = new File("E:\\");
//if (args.length > 0) root = new File(args[0]);
//else root = new File(System.getProperty("user.home"));
// Create a TreeModel object to represent our tree of files
FileTreeModel model = new FileTreeModel(root);
// Create a JTree and tell it to display our model
JTree tree = new JTree();
tree.setModel(model);
left.add(tree);
// The JTree can get big, so allow it to scroll.
JScrollPane scrollpane = new JScrollPane(left);
scrollpane.setBorder(BorderFactory.createLineBorder(Color.blue , 4));
scrollpane.setViewportView(left);
scrollpane.getViewport().setView(left);
f.add(scrollpane, BorderLayout.LINE_START);
left.setBackground(Color.white);
}
damit bekomme ich das grundsätzlich hin, jedoch habe ich nun die probleme
1.) Das als node immer der komplette pfad angezeigt wird.. das ist etwas nervig bei großer strucktur, wie bekomme ich hin, dass er nur den momentan namen des ordners/datei anzeigt im baum.
2.) Werden immernoch alle pfade angezeigt, jedoch will ich nur die pfade angezeigt beommen bei denen ich auch eine .dat datei finden kann.
Kann mir pls jmd helfen hierbei.. bin echt am verzweifeln.
2.) hm, das musst du wahrscheinlich peer hand in jede Funktion eintragen. (du kannst ja mit substring die endung der Datei abschneiden und dann schauen, ob das .dat entspricht)
Problematisch ist das nur bei Ordnern, da du ja die kinder des Ordners erst kennst, wenn er aufgeklappt wird, daher kann man da noch nicht bestimmen ob der Ordner eine datei mit der Endung .dat enthält. die einzigste möglichkeit ist den Baum komplet selber zu bauen (rekursiv) und erst wenn alles eingelesen ist zu entscheiden welcher Knoten nun wirklich an den Baum kommt.
#edit wobei die bei der recursiven-selbst-zusammen-bau-variante mit 90% wahrscheinlichkeit der HeapSpace von Java um die Ohren fliegen wird :wink:
- kompletten Baum einlesen
- Baum vom Root-Node aus traversieren
- durchlaufene Nodes der Reihe nach auf einen Stack schieben
- wenn keine Kinder im Baum mehr vorhanden sind Nodes vom Stack holen und daraus löschen, wenn sie keine .dat Dateien sind
- wenn aktuelles Element auf dem Stack .dat ist den Stack in ein Array umwandeln und daraus einen TreePath machen (dafür gibts nen eigenen Konstruktor); evtl. muss das Array umgekehrt werden (habs nicht mehr genau im Kopf)
- TreePath in einer Collection ablegen
- wenn der Baum fertig durchlaufen ist eine Schleife durchlaufen, in der bei jedem Durchlauf alle gesicherten TreePaths angefasst werden und der Reihe nach Element 0, 1, .., n (soweit im jeweiligen TreePath vorhanden) durchlaufen und in ein neues TreeModel überführt wird, bis alle Elemente aller TreePaths durchlaufen sind
Am Ende hat man dann ein TreeModel, das nur noch Pfade enthält letzte Nodes eine Datei vom Typ .dat enthalten.
Wenn man den Check schon beim Einlesen des Baums macht, kann man natürlich noch etwas "abkürzen".
private void tree(File currentFile,DefaultMutableTreeNode currentNode )
{
File[] files = currentFile.listFiles();
if (files != null)
{ //Have the rights to list Files in this folder
for (int i = 0; i < files.length; i++)
{
if (files[i].isDirectory())
{// File is a Folder
Icon leafIcon = new ImageIcon("C:\\middle.gif");
DefaultMutableTreeNode folder = new DefaultMutableTreeNode( files[i].getName() );
currentNode.add(folder);
tree(files[i], folder);
}
else
{
if(files[i].getName().contains(".dat"))
{
DefaultMutableTreeNode file = new DefaultMutableTreeNode( files[i].getName() );
currentNode.add(file);
hits.add(files[i]);
}
else
{
// do nothing atm
}
}
}
if(currentFile != rootFile)
{
currentFile = currentFile.getParentFile();
}
else
{
left.add(tree);
JScrollPane scroll = new JScrollPane( left );
scroll.setBorder(BorderFactory.createLineBorder(Color.blue , 4));
scroll.setViewportView(left);
scroll.getViewport().setView(left);
f.add(scroll, BorderLayout.LINE_START);
left.setBackground(Color.white);
}
}
Ich habe es nun soweit, dass es mir ein Baum Darstellt.
Jedoch zeigt er mir im Jtree alle Ordner die Keinen inhalt haben als dateien an(also das Icon der Dateien...)
Wie kann ich nun ändern, dass er Ordner die leer sind auch als ordner anzeigt und nicht als Dateien... das Mit dem renderer verstehe ich leider nicht so ganz, kann das mal einer erklären bzw. nen bsp code posten wie ich das hinbekommen könnt??