Dateibrowser

Nelki

Grünschnabel
Moin!

Ich habe folgendes Problem und zwar möchte ich einen Dateibrowser welchen ich in ein JScrollPane eingearbeitet habe verändern. Wenn das Programm gestartet wird, dann wird das C Laufwerk im Dateibrowser angezeigt.
Zur Laufzeit soll die Möglichkeit bestehen das Verzeichnis noch zu wechseln und dieses habe ich einmal in einer Test Version von meinem Programm dargestellt (hier wirklich ganz kurz, damit man auch schnell sehen kann was Sache ist), wird auf „Verzeichniswechsel“ gedrückt dann soll im Dateibrowser nicht mehr der Inhalt des C Laufwerkes sondern der des E Laufwerkes angezeigt werden und genau dort liegt auch das Problem. Wenn auf „Verzeichniswechsel“ gedrückt wird, dann passiert gar nichts, der Inhalt wird einfach nicht aktualisiert. Ich habe schon alles erdenklich ausprobiert (hier leider nicht mehr zu finden) das einzig was noch Abhilfe geschafft hat ist, dieses Fenster zu schließen und dann ein neues mit veränderter Laufwerk Angabe zu öffnen. Doch in meinem Eigentlichen Programm ist das so einfach nicht möglich. Wäre echt super wenn mir jemand helfen könnte.

Vielen Dank im Voraus und dann folgt hier auch erst einmal der Quellcode.
Code:
public class test extends JFrame implements ActionListener{

	private JButton verzeichniswechsel;
	private JTree fileTree;
	private FileSystemModel fileSystemModel;
	private String directory;
	
	test(){
		super("Super ein Test");
		directory = "c:\\";
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLayout(new GridLayout(3,3,10,10));
		
		fileSystemModel = new FileSystemModel (new File(directory));
		fileTree = new JTree(fileSystemModel);
	
		verzeichniswechsel = new JButton("Verzeichniswechsel");
		verzeichniswechsel.addActionListener(this);
		add(verzeichniswechsel);
		
		JScrollPane sp = new JScrollPane(fileTree);
		add(sp);
				
		pack();
		setVisible(true);
	}
	
	
	public static void main(String[] args) {
		new test();
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getActionCommand() == "Verzeichniswechsel"){
			directory = "e:\\";
		}
		
	}
}
 

Fabio Hellmann

Erfahrenes Mitglied
Hi und Willkommen bei Tutorials.de,

das Problem bei deinem Programm ist, dass du nur der Variable 'directory' einen neuen Wert zuweißt. Diese Änderung bekommt allerdings das FileSystemModel nicht mit. Daher wird dein FileSystem auch nicht upgedated.
Ich kenn mich mit dieser Klasse nicht aus und kann dir daher leider nicht sagen, wie du dem FileSystemModel sagen kannst, dass sich das Directory geändert hat.
Aber vielleicht hilft dir das erstmal schon ein bischen weiter.

Gruß

Fabio
 

genodeftest

Erfahrenes Mitglied
Hallo
Java-Code bitte in die Java-Tags, das erhöht die Lesbarkeit! (siehe meine Signatur)

Dein Problem ist, dass du zwar die Variable 'directory' änderst, aber weder den JTree, das Model noch den ViewPort deiner JScrollPane.

Die Lösung ist ganz einfach: du fügst in deine actionPerformed nach Zeile 35 noch diese Zeilen ein:
Java:
fileSystemModel = new FileSystemModel(new File(directory));
fileTree = new JTree(fileSystemModel);
sp.setViewport(fileTree);
(ungetesteter Code, sollte aber so funktionieren)

EDIT: Fabio war schneller...
Eleganter wäre es natürlich, wenn du das FileSystemModel auf das neue Verzeichnis ansetzt.
Wenn du fremde Bibliotheken nutzt solltest du auch erwähnen, welche das sind!
 
Zuletzt bearbeitet:

Nelki

Grünschnabel
Erst einmal Danke für die schnellen Antworten!

Das mit den Java Tags hab ich so nicht gewusst, werde dieses in Zukunft beherzigen.

Habe dann die drei Zeilen eingefügt und bekomme folgende Fehlermeldung:

„The methode setViewport(JViewport) in the type JScrollPane is not applicable fort he arguments (JTree)“
Was mach ich jetzt?

Der Vollständigkeit halber folgt nun noch der Quellcode von dem FileSystemModel, da muss ich auch noch eben sagen, dass ich das auch so aus dem Internet habe:

Java:
package test_GUI;

import java.io.File;
import java.util.Iterator;
import java.util.Vector;

import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;


public class FileSystemModel implements TreeModel {
	private File root;
	private Vector listeners = new Vector();
	
	public FileSystemModel(File rootDirectory){
		root = rootDirectory;
	}
	
	public Object getRoot(){
		return root;
	}
	
	public Object getChild(Object parent, int index){
		File directory = (File) parent;
		String[] children = directory.list();
		return new TreeFile(directory, children[index]);
	}
	public int getChildCount(Object parent) {
		File file = (File) parent;
		if (file.isDirectory()) {
			String[] fileList = file.list();
			if (fileList != null)
				return file.list().length;
		}
		return 0;
	}
	public boolean isLeaf(Object node) {
		File file = (File) node;
		return file.isFile();
	}
	
	public int getIndexOfChild(Object parent, Object child) {
		File directory = (File) parent;
		File file = (File) child;
		String[] children = directory.list();
		for (int i = 0; i < children.length; i++) {
			if (file.getName().equals(children[i])) {
				return i;
			}
		}
		return -1;

	}
	
	public void valueForPathChanged(TreePath path, Object value) {
		File oldFile = (File) path.getLastPathComponent();
		String fileParentPath = oldFile.getParent();
		String newFileName = (String) value;
		File targetFile = new File(fileParentPath, newFileName);
		oldFile.renameTo(targetFile);
		File parent = new File(fileParentPath);
		int[] changedChildrenIndices = { getIndexOfChild(parent, targetFile) };
		Object[] changedChildren = { targetFile };
		fireTreeNodesChanged(path.getParentPath(), changedChildrenIndices,
				changedChildren);

	}
	
	private void fireTreeNodesChanged(TreePath parentPath, int[] indices,
			Object[] children) {
		TreeModelEvent event = new TreeModelEvent(this, parentPath, indices,
				children);
		Iterator iterator = listeners.iterator();
		TreeModelListener listener = null;
		while (iterator.hasNext()) {
			listener = (TreeModelListener) iterator.next();
			listener.treeNodesChanged(event);
		}
	}
	public void addTreeModelListener(TreeModelListener listener) {
		listeners.add(listener);
	}
	public void removeTreeModelListener(TreeModelListener listener) {
		listeners.remove(listener);
	}
	private class TreeFile extends File {
		public TreeFile(File parent, String child) {
			super(parent, child);
		}

		public String toString() {
			return getName();
		}
	}
	

}
 

genodeftest

Erfahrenes Mitglied
die Methode heißt auch
Java:
setViewportView();
(mein Fehler... ).

Es wäre aber einfacher, wenn du nur das Model vom JTree setzt:
Java:
fileSystemModel = new FileSystemModel(new File(directory));
fileTree.setModel(fileSystemModel);
 

Nelki

Grünschnabel
Also eine Fehlermeldung bekomme ich jetzt keine mehr, aber es passiert immer noch nichts. Muss ich denn jetzt noch irgend eine Funktion aufrufen, damit das auch wirklich noch mal aktualisiert wird?
 
S

SE

Auf dein Frame anwenden in dem es angezeigt wird :
Java:
JFrame.validate();
JFrame.update(JFrame.getGraphics());
Wobei JFrame durch die Variable zu ersetzen ist.
 

Nelki

Grünschnabel
Moin,
so endlich auf die Lösung gekommen, war noch ein anderer Klopfer drin, warum das gestern Abend nicht wollte, aber es funktioniert wenn ich ab Zeile 35 im actionPerformed folgendes einfüge:

Java:
            fileSystemModel = new FileSystemModel(new File(directory));
            fileTree = new JTree(fileSystemModel);
            sp.setViewportView(fileTree);

Den Tipp mit dem validate() und update habe ich auch ausprobiert, dabei erhilt ich jedoch immer eine Fehlermeldung, das dieses Methoden nicht für mein JFrame definiert sind, hätte wahrscheinlich geklappt wenn ich das ganze im Main angelegt hätte und den Frame direkt angelegt hätte, aber jetzt läuft es ja so wie ich mir das vorgestellt habe.

Ein große Danke an alle die mir geholfen haben. Danke
 
S

SE

validate() und update(Graphics) sinde definitiv für die Klasse JFrame definiert da validate() von java.awt.Container und update(Graphics) von java.awt.Component geerbt werden.
Was bei dir vermutlich das Problem sein wird ist das du in deiner actionPerformed(ActionEvent) scheinbar keine Referenz auf das JFrame hast in dem es angezeigt wird ... diese musst du entweder dynamisch über java.awt.Component.getParent() holen *rekursiv aufrufen bis NULL kommt* oder aber eine Referenz bei erzeugen des Objektes der Klasse mitgeben.