Struktur für TreeTable rekursiv aufbauen

Diskutiere Struktur für TreeTable rekursiv aufbauen im Java Basics - Anfänger-Themen Bereich.
K

KlaRo

Hallo,

ich bin wohl noch blutiger Anfänger, habe erst vor ein paar Wochen begonnen Java zu lernen.
Nun habe ich mein eigenes "kleines" Projekt gestartet, welches bisher auch gut geklappt hat. Nun habe ich ein Problem beim Erstellen einer TreeTable mit mehreren Spalten, woran ich bereits mehrere Tage hänge und nicht weiter komme. Tabellen und TreeViews jeweils einzeln automatisiert zu füllen klappt wunderbar, allerdings leider nicht die Kombination aus beiden.

Ich würde gerne Ordner und Dateien aus einem bestimmten Verzeichnis (rekursiv) als TreeTable anzeigen und einige Infos der Dateien, wie z.B. Dateigröße, in den Spalten ausgeben. Die Infos auslesen funktioniert einwandfrei. Irgendwie scheitert es leider an der (rekursiven) Umsetzung.

Nachfolgend mein Code-Ansatz zur "manuellen" Strukturerstellung:
Java:
[/B]
    private static MyDataNode createDataStructure() {
        List<MyDataNode> children1 = new ArrayList<MyDataNode>();
        children1.add(new MyDataNode("1.mp3", "12", "123", "234", "1", "X:", null));
        children1.add(new MyDataNode("2.mp3", "13", "123", "234", "1", "X:", null));
        children1.add(new MyDataNode("3.mp3", "14", "123", "234", "1", "X:", null));
        children1.add(new MyDataNode("4.mp3", "15", "123", "234", "1", "X:", null));

        List<MyDataNode> pix = new ArrayList<MyDataNode>();
        pix.add(new MyDataNode("1.png", "12", "123", "234", "1", "X:", null));
        pix.add(new MyDataNode("2.png", "13", "123", "234", "1", "X:", null));
        pix.add(new MyDataNode("3.png", "14", "123", "234", "1", "X:", null));

        List<MyDataNode> children2 = new ArrayList<MyDataNode>();
        children2.add(new MyDataNode("pix", null, null, null, null, null, pix));
        children2.add(new MyDataNode("10.mp3", "1", "123", "234", "1", "X:", null));
        children2.add(new MyDataNode("11.mp3", "2", "123", "234", "1", "X:", null));
        children2.add(new MyDataNode("12.mp3", "3", "123", "234", "1", "X:", null));

        List<MyDataNode> rootNodes = new ArrayList<MyDataNode>();
        rootNodes.add(new MyDataNode("Band1", null, null, null, null, null, children2));
        rootNodes.add(new MyDataNode("Band2", null, null, null, null, null, children1));
        rootNodes.add(new MyDataNode("Band3", null, null, null, null, null, children2));
        rootNodes.add(new MyDataNode("Band4", null, null, null, null, null, children1));
        rootNodes.add(new MyDataNode("Band5", null, null, null, null, null, children1));
        rootNodes.add(new MyDataNode("Band6", null, null, null, null, null, children1));
        rootNodes.add(new MyDataNode("Band7", null, null, null, null, null, children1));
        MyDataNode root = new MyDataNode("D:\\___ED\\Eigene Musik\\___Mucke", null, null, null, null, null, rootNodes);

        return root;
    }
[B][B]
[/B]

Wie kann man nun diesen Code rekursiv aufbauen?
Anbei auch die Ausgabe, wie es aussehen sollte.

Ich hoffe auf auf schnelle Hilfe.

Viele Grüße und Danke schon mal im Voraus!
 

Anhänge

mihe7

mihe7

Ist das Swing oder JavaFX?

Prinzipiell kannst Du https://docs.oracle.com/javase/8/do...java.nio.file.Path-java.nio.file.FileVisitor- verwenden. Natürlich geht das auch mit selbstgestricktem, rekursiv beispielsweise etwa so in der Art
Java:
public void visit(File directory, Consumer<File> consumer) {
    List<File> directories = new ArrayList<>();
    for (File file : directory.listFiles()) {
        if (file.isDirectory()) {
            directories.add(file);
        } else {
            consumer.accept(file);
        }
    }
    for (File dir : directories) {
        visit(dir);
    }
}
Wobei Consumer https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html ist.
 
K

KlaRo

Das ist Swing.

Wie Rekursion prinzipiell funktioniert, habe ich, denke ich zumindest, verstanden. Ich bekomme es nur leider nicht hin obigen Code so umzubauen, dass er automatisch (also erst Root-Verzeichnis, dann Unterordner, Dateien, usw. ohne »children1«, »children2«, »pix«, usw.) variabel (d.h. sollte später nach Eingabe eines Start-Ordners komplett durchlaufen) die Struktur mit den Infos in den Spalten auflistet.
 
K

KlaRo

Danke. Bei dieser Version habe ich das Problem, dass alles (zum Aufbau des Trees und zum ermitteln der Zusatzinfos) neu durchgelaufen wird, sobald die Größe des Fensters verändert oder der Scrollbalken verschoben wird. Zudem wird scheinbar alles für jede Spalte je ein Mal durchlaufen → extremer Performanceverlust und eigentlich absolut unnötig, da die Daten ja bereits vorhanden. Ist das bei allen TreeTable-Versionen von Swing so oder mache ich etwas falsch? Konnte das Durchlaufen während den beiden Situationen bisher nicht unterbinden.
 
Zuletzt bearbeitet:
mihe7

mihe7

Bei dieser Version habe ich das Problem, dass alles (zum Aufbau des Trees und zum ermitteln der Zusatzinfos) neu durchgelaufen wird, sobald die Größe des Fensters verändert oder der Scrollbalken verschoben wird.
Oh, das sollte keine Fertiglösung sein. Ich hab es jetzt nicht ausprobiert, aber dem Code nach zu urteilen, sollte das nicht sein. Relevant für Deine Frage ist eigentlich auch nur das FileSystemModel.
 
K

KlaRo

Ich habe das Ganze nun in beiden Versionen zusammengebaut.
Leider wird folgendes immer zeilenweise pro Spalte (also hier bei 7 Spalten wird der Code 7× / Zeile) durchlaufen:

Java:
[/B]
    public Object getValueAt(Object node, int column) {
..........................................................................................
            try {
                switch (column) {
//             case 0:
//                 return file.getAbsolutePath();// .getName();
                case 1:
                    return laufzeit;
                case 2:
                    return bitrate;
                case 3:
                    return bitrateMode;
                case 4:
                    return HumanReadableByteCount.humanReadableByteCountSI(file.length());
                case 5:
                    return file.getAbsolutePath();
                case 6:
//                    return stufe;
                }
            } catch (SecurityException se) {
            }
        } else {
..........................................................................................
        }
        return null;
    }
[B]
Da ich dabei bei Musikdateien z.B. die Bitrate auslesen will, dauert das bereits bei nur 100 Dateien ziemlich lange.
Da dieser Code allerdings auch bei jeder Änderung der Größe des Fensters und beim Scrollen durchlaufen wird, steigert sich diese Zeit ins Unermessliche...

Gibt es eine Möglichkeit, dieses Auslesen nur ein Mal, z.B. beim ersten Auslesen, durchzulaufen, danach jedoch nicht mehr? Ev. eleganter als mit einer Boolean-Variablen.
 
mihe7

mihe7

Leider wird folgendes immer zeilenweise pro Spalte (also hier bei 7 Spalten wird der Code 7× / Zeile) durchlaufen:
Ja, das ist auch völlig richtig. Die Tabelle muss für jede Zelle, die sie anzeigt, den Wert bekommen, den sie anzeigen soll.

Gibt es eine Möglichkeit, dieses Auslesen nur ein Mal, z.B. beim ersten Auslesen, durchzulaufen, danach jedoch nicht mehr? Ev. eleganter als mit einer Boolean-Variablen.
Selbstverständlich. Du brauchst ja nur entsprechende Objekte zu verwenden.
 
K

KlaRo

Hmm OK. Dann schau ich mal, ob ich das hinbekomme.
Danke für deine Hilfe.
 
Thema: 

Struktur für TreeTable rekursiv aufbauen

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben