bestimmte dateiendungen in jtree rausfiltern

  • Themenstarter Themenstarter Gelöschtes Mitglied 35125
  • Beginndatum Beginndatum
G

Gelöschtes Mitglied 35125

Gast
hey leute nachdem sich mein erstes problem von alleine 😉) gelöst hat hab ich auch gleich das nächste. und zwar geht es diesmal um die filterung von bestimmten dateiendungen so dass nur diese im jtree angezeigt werden. hier mein code bis jetzt:

Code:
package dateibaum;

import java.io.File;
import java.io.FileFilter;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;

public class DateiBaum extends JFrame implements TreeSelectionListener
{
//Konstruktor
JTree baum;
    public DateiBaum(File file)
    {
        
        DefaultMutableTreeNode wurzel = new DefaultMutableTreeNode(file);
        baumAusgeben(file, wurzel);
        //Tree-Komponente erzeugen
        baum = new JTree(wurzel);
        baum.addTreeSelectionListener(this);
        //Ebene mit Scrollbalken zur Anzeige des JTree erzeugen
        JScrollPane treePane = new JScrollPane(baum);
        //diese der Inhalts-Ebene des JFrame hinzufügen
        this.getContentPane().add(treePane);

        //Fenster initialisieren
        this.setTitle("DateiBaum");
        this.setSize(500, 500);
        this.setLocation(200, 200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }//Ende Konstruktor

    //Rekursive Methode zum Aufbau des Datenmodells für den JTree
    private void baumAusgeben(File file, DefaultMutableTreeNode ast)
    {
        DefaultMutableTreeNode blatt = new DefaultMutableTreeNode(file.getName());
        if (file.getName().endsWith(".jpg"))
        {
        
        ast.add(blatt);
        }
        if (file.isDirectory())
        {
            File verzeichnisInhalt[] = file.listFiles();
            if (verzeichnisInhalt != null)
                for (int i = 0; i < verzeichnisInhalt.length; i++)
                    baumAusgeben(verzeichnisInhalt[i], blatt);
        }
        
    }//Ende der Methode baumAusgeben

    //Methode des TreeSelectionListeners
    public void valueChanged(TreeSelectionEvent e)
    {
        Object[] geklickt = baum.getSelectionPath().getPath();
        int anzahl = geklickt.length;
        String text = "Geklickt auf: " + geklickt[anzahl - 1];
        for (int i = anzahl - 2; i >= 0; i--)
            text += "\n" + geklickt[i];
        JOptionPane.showMessageDialog(rootPane, text);
    }

    public static void main(String[] args)
    {
        DateiBaum dateiBaum = new DateiBaum(VerzeichnisAuswahl.getFile("Einlesen"));
        dateiBaum.setVisible(true);
    }
}

Code:
package dateibaum;

import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import konstanten.Konstanten;

/**
 * Die Klasse Dateiauswahl stellt ein Dialog zur Auswahl eines
 * root-Verzeichnisses zur Verfügung.
 * 
 */
public class VerzeichnisAuswahl implements Konstanten
{
    

    public static File getFile(String titel)
    {
        //Dialog zum Auswählen des Root-Verzeichnisses
        JFileChooser fc = new JFileChooser(titel);
        //nur Verzeichnisse anzeigen lassen
        fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        fc.setAcceptAllFileFilterUsed(false);
        //Extensions-Array auf Auswahl-Dialog anwenden
        //FileNameExtensionFilter filter_all = new FileNameExtensionFilter("alle Bild Dateien", Konstanten.extensions);
        //FileNameExtensionFilter filter_gif = new FileNameExtensionFilter("gif-Dateien", "gif");
        //FileNameExtensionFilter filter_jpeg = new FileNameExtensionFilter("jpeg-Dateien", "jpeg");
        //fc.setFileFilter(filter_all);
        //fc.setFileFilter(filter_gif);
        //fc.setFileFilter(filter_jpeg);
        fc.setDialogTitle("Root-Verzeichnis auswählen");
        int antw = fc.showDialog(null, titel);
        //falls auf Abbrechen geklickt
        if (antw == JFileChooser.CANCEL_OPTION)
        {
            return null;
        }
        return fc.getSelectedFile();
    }
}

alles klappt, nur wenn der jtree ausgegeben wird dann sehe ich keine dateien, nur das root verzeichnis das ich vorher ausgewählt habe. wenn ihr mir noch ein tipp geben könntet wie ich nur die dateiendungen rausfiltern lassen könnte die ich vorher in ein array gepackt habe wäre das perfekt.

hier das interface dass die konstanten enthält:

Code:
package konstanten;

/**
 * Das Interface Konstanten stellt Konstanten für die Anwendung bereit.
 * 
 */
public interface Konstanten
{
    //Dateiendungen in Array packen
    final String extensions[] = {"jpeg", "gif", "bmp"};
}
 
JAVA-Tags wären weitaus lesbarer,

schau dir deine baumAusgeben()-Methode genau an, prüfe doch Schritt für Schritt was passiert, was verknüpft wird,
statt unbekannte Nodes zu verknüpfen, wo 10 andere Fehler noch Ursache für falsche Anzeige sein können,
bietet sich bei jeden Algorithmus der Welt erstmal an, das ganze auf Papier durchzugehen/ im Code Ausgaben a la 'hänge nun X an Y an' usw.,

das einzige add() in der ganzen Methode steht bei jpg-Blättern,
wie soll bei 5 Verzeichnissen ineinander, offensichtlich ohne jpg, irgendwas aufgebaut werden?
 
danke für die antwort. also ich muss sagen rekursion und JTree sind mir relativ neu und ich hab da nur nen groben durchblick, meine dozentin hat mir halt einen beispiel code gegeben den ich nur ein wenig angepasst habe. ich habe mir ein testverzeichnis angelegt wo nur jpg und txt dateien drinne sind, also müsste das doch klappen oder? ich habe vor den filter später noch zu erweitern, ich will ja lediglich 3-4 grafikdateiendungen rausfiltern, mehr nicht.

sorry aber ich kenne mich da wirklich noch nicht so aus mit rekursion deswegen kann ich das noch nicht nachvollziehen was da passiert....
 
wie gesagt kannst du JTree vorerst weglassen und einfach nur mit System.out.println() arbeiten

dass du nachvollziehst was da passiert, ist nicht ungewöhnlich, aber als letzter Stand nicht akzeptabel,
gerade deswegen musst du es nun selber verstehen, Schritt für Schritt durchgehen,

schau dir deine Festplatte an, leg evtl. extra paar Verzeichnisse mit günstigen Namen an,
Root
- A1
- A2
- A3
---B1
---B2
---B3
oder ähnliches


die ganze Rekursion musst du nicht mit einem Schlag erfassen, schaue dir nach und nach an, was passiert,
was wird vor dem ersten Aufruf schon alles gemacht, welche Knoten vielleicht angelegt?

was passiert exakt im ersten Aufruf der Methode? was sind die Parameter, welches File wird übergeben, welcher TreeNode, für welches Verzeichnis steht der?
was wird neu angelegt und womit verknüpft durch welchen Befehl? usw.
/ parallel abweichend davon vielleicht darstellen, was der Theorie nach passieren sollte,
aber wenn du dabei schon Unterschiede erkennst, ist das Ziel ja quasi erreicht

wenn du selbst davon nicht alles beantworten kannst, ist das kein Beinbruch,
aber versuche soviel wie möglich durch deine Worte zu erarbeiten,
stelle vielleicht intelligente Fragen wo du ausdrücken kannst was dir unverständlich ist,

dann ist der Rest einfacher zu ergänzen als nur bei 'ich nix wissen'..

--

> ich habe mir ein testverzeichnis angelegt wo nur jpg und txt dateien drinne sind, also müsste das doch klappen oder?
mag sein, kannst du ja testen, ich denke gerade vor allem an Unterverzeichnisse,
nur mit Bildern ist nicht so viel Rekursion da, hauptsächlich die eine Schleife, wobei immer noch manches schiefgehen kann
 
Zuletzt bearbeitet von einem Moderator:
die aufbauweise vom jtree hab ich soweit verstanden, nur wirds kompliziert wenn man mittels rekursion da was erreichen will, jedenfalls für meine temporären verhältnisse😀

naja bin den code nochmal mit meiner dozentin durchgegangen, nach ner 30 minütigen diskussion haben wir das problem soweit behoben. hier die neue baumAusgeben() methode:

Code:
private void baumAusgeben(File file, DefaultMutableTreeNode ast)
    {
        DefaultMutableTreeNode blatt =  new DefaultMutableTreeNode(file.getPath());
        ast.add(blatt);
        if (file.isDirectory())
        {
            File verzeichnisInhalt[] = file.listFiles();
            if (verzeichnisInhalt != null)
            {
                for (int i = 0; i < verzeichnisInhalt.length; i++)
                {
                    if ( verzeichnisInhalt[i].isDirectory() )
                            if (verzeichnisInhalt[i].listFiles().length > 0)
                                baumAusgeben(verzeichnisInhalt[i], blatt);
                   if (verzeichnisInhalt[i].isFile() && verzeichnisInhalt[i].getPath().endsWith("jpg"))
                             baumAusgeben(verzeichnisInhalt[i], blatt);
                }
            }
        }

problem ist, das programm zeigt zwar jetzt nur jpg-dateien an, aber es zeigt leere verzeichnisse (oder verzeichnisse wo es keine jpg-dateien findet) als leaf an, was bei vielen ordnern schnell für verwirrung sorgen kann. hab mir überlegt meinem programm eine baumPruefen methode hinzuzufügen die dann bei der ausgabe die leeren verzeichnisse rausfiltert. nur den inhalt der methode muss ich mir noch ausdenken😉
 
alternativ kannst du etwas andersrum vorgehen:
wenn kein directory, dann adden und gut ist, ein frühes return schadet auch nicht,
dann muss der Rest nicht mit if eingerückt werden

für directory erst die Schleife, und wenn am Ende nix drin ist im Node (kein Childs), dann den aktuellen Node selber auch nicht nach oben adden(),
gehe das gedanklich durch oder teste es einfach

-------

file.listFiles() liefert übrigens beliebige Dateien in einem Verzeichnis, da wird nicht gefiltert,
mit FileChooser hat das nichts zu tun, du musst hier auf die Endung schauen, falls wichtig

gibt erfreulicherweise auch Methoden listFiles(FileFilter filter)/ listFiles(FilenameFilter),
nicht vergessen auch Directorys zu erlauben
 
Zuletzt bearbeitet von einem Moderator:
danke für die tipps, habs jetzt hinbekommen, ich habe aber da noch ein letztes problemchen😀

und zwar wenn man mittels

Code:
private void btnOeffnenActionPerformed(java.awt.event.ActionEvent evt)                                           
    {                                               
        DateiBaum baum = new DateiBaum(DateiAuswahl.getDirectory("Einlesen"));
        this.jTreeBaum.setModel(DateiBaum.baum.getModel());
        
    }

ein neues verzeichnis auswählen will, dann wird automatisch die methode

Code:
public void valueChanged(TreeSelectionEvent e)
    {
        GUIBildbetrachter bilderrahmen = new GUIBildbetrachter(e.getPath().getLastPathComponent().toString());
       
    }

aufgerufen die wiederrum ein neues bildbetrachter-objekt erzeugt. dies passiert jedesmal wenn ich ein neues verzeichnis auswählen will, was aber nicht so sein soll. gibt es da einen weg das zu unterdrücken? ich brauche die 2. methode um grafik-dateien in separaten jframes anzeigen zu lassen wenn diese im jframe dass den jtree enthält ausgewählt werden.
 
die einfache Variante wäre, vor und nach dem setModel-Aufruf einen boolean zu setzen, so dass der Listener solange nichts macht
(der muss dann den boolean prüfen), bzw. den Listener solange entfernen
 

Neue Themen


Zurück
Oben