jTree nach löschen von path erneuern?

Status
Nicht offen für weitere Antworten.
D

David

Gast
Ich möchte das sich der JTree nach dem Löschen einer Datei erneuert so das die Datei im jTree nicht mehr zu sehen ist. Wie mach ich das? Muss ich dazu den jTree neu aufrufen oder das TreeModel und wie kann ich das machen?

mein Aufbau:

Code:
private javax.swing.JTree getJTree() {
	if(jTree == null) {
		myFile root = new myFile(System.getProperty("file.separator")); 
		final FileTreeModel model = new FileTreeModel(root);
		jTree = new javax.swing.JTree(model);
.
.
//hier ist noch ein selektion Listener für die Selektion im JTree der einen pathname zurück gibt
}

// mit der Methode bekomme ich den pathname und lösche das Verzeichniss samt inhalt
public static void deleteTree (File pathname)
{.....
}
 
G

Guest

Gast
So in der Art?
Code:
model.addTreeModelListener (new TreeModelListener()	{
	public void treeNodesChanged(TreeModelEvent e) {}
						 
	public void treeNodesInserted(TreeModelEvent e) {}
						
	public void treeNodesRemoved(TreeModelEvent e) { //WAS muss hier dann rein//?}
					
	public void treeStructureChanged(TreeModelEvent e) {}
}
);
 
B

Beni

Gast
Verkehrt herum.

Was Du schreibst ist: "Ich muss einen Listener implementieren"
Was ich sagen wollte ist: "Du musst einen Listener aufrufen"

Der Code den Du im FileTreeModel noch hinzufügen musst, könnte etwa so aussehen:
Code:
public class FileTreeModel implements TreeModel{
  private Vector listeners = new Vector();

  (...) // anderer Code
  
  // wird von aussen aufgerufen
  public void addTreeModelListener( TreeModelListener x ){ 
    listeners.add( x );
  }

  public void fileDeleted( File x ){
    TreeModelEvent event = new TreeModelEvent( ... ) // Die Argumente in der API nachschauen, kenne sie nicht auswendig

    for( int i = 0, n = listeners.size(); i<n; i++ )
      ((TreeModelListener)listeners.get(i)).treeNodesRemoved( event );
  }
}

Sie dir doch mal den Quellcode des DefaultTreeModel (API hier) an. (besonders die Methoden die mit fireXXX beginnen)

mfg Beni
 
G

Guest

Gast
Ja ich hatte bei der erneurung meines Tables wenn ich einen anderen path im JTree selektiere auch eine fire MEthode genutzt
Code:
FileTableModel mod = (FileTableModel)getJTable().getModel();
	mod.setDir(pathname);
				   
	mod.fireTableChanged( new TableModelEvent(mod));

Aber so richtig ist mit nicht klar wie ich z.B. fireTreeStructureChanged nutzen kann.

Arg ich verzweifel an einer simplen Tree erneuerung :/
 
B

Beni

Gast
Einfach rumspielen bis es funktioniert :D

Schau mal, wie das in diesem Tutorial gelöst wurde!
(Funktioniert nicht ganz gleich wie dein FileTreeModel, aber der Aufruf der Listeners (vorallem das wann und wo) entspricht dem, was ich dir sagen will)

Ein Ausschnitt:
Code:
public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
                                        Object child,
                                        boolean shouldBeVisible) {
    DefaultMutableTreeNode childNode =
            new DefaultMutableTreeNode(child);
    ...

//>>> an dieser Stelle wird dem JTree (auf Umwegen) gesagt, dass es einen neuen Node gibt.
//>>> treeModel ist hier ein "DefaultTreeModel". Aber es geht ja auch nur ums Prinzip
    treeModel.insertNodeInto(childNode, parent, parent.getChildCount());

    //Make sure the user can see the lovely new node.
    if (shouldBeVisible) {
        tree.scrollPathToVisible(new TreePath(childNode.getPath()));
    }
    return childNode;
}
 
G

Guest

Gast
Hab nun folgendes gemacht.
Neue klasse erstellt:

Code:
class MyTreeModelListener implements TreeModelListener {
			public void treeNodesChanged(TreeModelEvent e) {
				DefaultMutableTreeNode node;
				node = (DefaultMutableTreeNode)(e.getTreePath().getLastPathComponent());
				try {
						int index = e.getChildIndices()[0];
						node = (DefaultMutableTreeNode)
						(node.getChildAt(index));
					} catch (NullPointerException exc) {}
			}
			public void treeNodesInserted(TreeModelEvent e) {
			}
			public void treeNodesRemoved(TreeModelEvent e) {
			}
			public void treeStructureChanged(TreeModelEvent e) {
			}
	}

und dann ans model rangehangen

Code:
model.addTreeModelListener(new MyTreeModelListener());
[/code]


Ist das bis dahin korrekt? weil es nicht ganz klappt is jetzt
 
B

Beni

Gast
Man, du bist immer noch auf der falschen Seite:

Mal zur Erklärung von Listenern


Beispiel: Button und ActionListener

Du kennst doch den Button und den ActionListener?

man fügt dem Button einen ActionListener hinzu:
Code:
ActionListener listener = ...
JButton button = ...
button.addActionListener( listener );

Wenn nun jemand auf den Button klickt, benachrichtig der Button den Listener ( actionPerformed( ActionEvent e) ).

User klickt auf Button -> Button bemerkt dies -> Button benachrichtig Listener -> Listener arbeitet mit irgendetwas weiter.
graphische Oberfläche (Button geklickt) -> innere Strukturen (Code ausführen, z.B. Datei speichern)

:arrow: Es gibt also zwei Seiten: den Button (der "Sender") und der ActionListener (der "Empfänger").

Soweit alles klar? gut, weiter geht es.


Tree und Model

Bei dem Tree und dem Model gibt es nun ebenfalls einen Sender und einen Empfänger.

Es gibt zwei Möglichkeiten:
JTree = Sender, Model = Empfänger: Das hast Du bis jetzt versucht. Das funktioniert offenbar nicht. Wie auch, wie soll der Empfänger dem Sender mitteilen, dass sich etwas verändert hat?
:arrow: falsch


JTree = Empfänger, Model = Sender: Auf diese Weise kann das Model den JTree benachrichtigen, sollten Nodes hinzugefügt, Nodes entfernt, ... werden.
:arrow: richtig

Du musst erkennen: diesmal kommt das Ereignis nicht von der graphischen Oberfläche, sondern vom inneren des Programmes aus.
innere Strukturen (Node hinzugefügt, ...) -> graphische Oberfläche (Baum neuzeichnen)

:arrow: Du schickst das Event ab, und Du musst nicht den Listener implementieren.

Vielleicht lösst das deinen Knopf?
Sonst melde dich.

mfg Beni
 
G

Guest

Gast
Ok also das Model ist mein Sender und der Tree ist der Empänger. Das heisst wenn jemand ein path löscht sendet das Model und der Tree empfängt das sich die Structur geändert hat.
Ok und ich soll nicht den Listener implementieren sondern das Event abschicken. Ok Grundprinzip klar nur Umsetztung noch nicht ganz. :cry: ???:L
 
B

Beni

Gast
Dann implementieren wir mal einen Teil eines TreeModels:
(Ich gebs zu, dieser Code ist nicht getestet, aber die Richtung stimmt :wink:)

Beginnen wir mal mit dem einfachen Teil. Hier halten wir uns einfach an das Interface TreeModel.
Es gibt einen Konstruktor und einen Vector, der TreeModelListener's speichert (diese werden später gebraucht)
Code:
import java.io.File;
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 abstract class FileTreeModel implements TreeModel{
	private Vector vector = new Vector();
	
	public FileTreeModel(){
	}
	
	/**
	 * Speichert einen zusätzlichen TreeModelListener
	 * @param l Der neue TreeModelListener
	 */
	public void addTreeModelListener(TreeModelListener l) {
		vector.add( l );
	}

So, kommen wir zum Löschen einer Datei.
Die Datei löschen wir im Model selbst. Das ist nicht unbedingt notwendig, aber praktisch.

Wir gehen folgendermassen vor:
1. Position der Datei im Verzeichnisbaum finden und speichern.
2. Datei löschen
3. Sofern sie gelöscht wurde, den JTree benachrichtigen (Darum mussten wir die Position der Datei speichern).
Code:
	/**
	 * Diese Methode löscht eine Datei und benachrichtigt anschliessend den JTree, 
	 * das eine Datei gelöscht wurde.
	 * @param file Die Datei die gelöscht werden soll.
	 */
	public void deleteFile( File file ){
		// Als erster benötigen wir die Position dieses Files im Baum
		File parent = file.getParentFile();
		
		TreePath path = createPath( parent );
		int index = getIndexOfChild( parent, file );
		
		// Jetzt die Datei löschen
		boolean deleted = file.delete();
		
		if( deleted ){
			// jetzt den JTree benachrichtigen
			fireNodeRemoved( path, index, file );
		}
	}

Da fehlt doch noch was!
Richtig, die Methode "createPath" benötigen wir noch.
Sie stellt einfach einen TreePath her, zu einer Datei die wir ihr übergeben.
Code:
	/**
	 * Diese Methode liefert den TreePath zu dem angegebenen File.
	 * @param file Das File
	 * @return Der TreePath
	 */
	protected TreePath createPath( File file ){
		Vector files = new Vector(); // Zwischenspeicher
		
		// Die Parents der Reihe nach auslesen
		do{
			files.add( file );
			file = file.getParentFile();
		}while( file != null );
		
		// Verkehrt herum in einen Array kopieren
		int size = files.size();
		Object[] path = new Object[ size ];
		
		for( int i = 0; i < size; i++ )
			path[i] = files.get( size - 1 - i );
			
		// TreePath initialisieren und zurückgeben.
		return new TreePath( path );
	}

Jetzt brauchen wir noch eine Möglichkeit den JTree zu benachrichtigen.
Dazu schreiben wir die Methode "fireNodeRemoved". Diese Methode stellt zuerst ein TreeModelEvent her, und sendet es danach in die grosse Welt hinaus.
Code:
	/**
	 * Benachrichtigt alle registrierten TreeModelListener, dass ein Node
	 * entfernt wurde.
	 * @param path Der Pfad zum Parent des entfernten Nodes
	 * @param index Der ehemalige Index des Nodes
	 * @param removed Der entfernte Node
	 */
	protected void fireNodeRemoved( TreePath path, int index, Object removed ){
		// Event herstellen
		TreeModelEvent event = new TreeModelEvent( this, path, new int[]{ index }, new Object[]{ removed } );
		
		// Event verschicken
		for( int i = 0, n = vector.size(); i<n; i++ )
			((TreeModelListener)vector.get(i)).treeNodesRemoved( event );
	}

Damit können wir Dateien löschen, und der JTree wird es bemerken. Einige Methoden fehlen noch, aber die kannst du sicher selbst implementieren.

mfg Beni
 
G

Guest

Gast
hmm ok aber ich habe mein model etwas anders aufgebaut:

Code:
 class FileTreeModel implements TreeModel {
		
		
			protected myFile root; // Wurzel
			public FileTreeModel (myFile root) { this.root = root; }
			
			public void setroot (myFile pathnamer){
				this.root = pathnamer;
			}
		
			public Object getRoot() { return root; } // Liefert die Wurzel des Funktionsbaumes
			public boolean isLeaf(Object node) {  return ((myFile)node).isFile(); } // ist es ein Blatt oder nicht
			
			private Vector listeners = new Vector(); 
				

			
			public int getChildCount(Object parent) {  //bekommt object Eltern und soll Anzahl Kind-Knoten dieses Knotens liefern
				String[] children = ((myFile)parent).list(); //gibt String Liste von parent 
				if (children == null) return 0; //wenn keine children dann 0
				return children.length; // sonst Länge der Kinder zurückgeben
			}
	
		public Object getChild(Object parent, int index)  { // bekommt parent und Index des gesuchten Kind-Knotens und liefert Object Kind-Knoten
					String[] children = ((myFile)parent).list(); //gibt String Liste von parent 
					if ((children == null) || (index >= children.length)) return null;
					return new myFile((myFile) parent, children[index]);	
				}
				
			
	
	
		public int getIndexOfChild(Object parent, Object child) { //bekommt parent und object Kind
					String[] children = ((myFile)parent).list();
					if (children == null) return -1; //wenn kinder 0 dann ende -1
					String childname = ((myFile)child).getName(); //String name des Kindes ist 
					//childname = childname.substring(0,6);
					for(int i = 0; i > children.length; i++) { 
						if (childname.equals(children[i])) return i;
					}
					return -1;
				}
				
				public void valueForPathChanged(TreePath path, Object newvalue) {} // Wird aufgerufen, wenn der Wert für den Pfad geändert wurde.
				public void addTreeModelListener(TreeModelListener l) {
					listeners.add( l );
				} //Fügt den Listener hinzu
				
										
				public void removeTreeModelListener(TreeModelListener l) {} // Entfernt den Listener		
		
	}
[/code]


und mein path lösche ich indem ich bei der selektion ein path(file) bestimme und das übergeben an:
Code:
public static void deleteTree (File pathname)
		{
			
			File files [] = pathname.listFiles(); //File Array mit Wurzel pathname
			
			for (int i = 0; i < files.length; i++) //von Anfang bis zum Ende des Arrays
			{
				
				if (files [i].isDirectory() )	//Wenn File i ein Verzeichniss ist 
				{deleteTree (files [i] );} 		// Lösche den Inhalt des Verzechniss
				files [i].delete();		
			}
			pathname.delete();					// Lösche dann noch den pathnamen(Wurzel)
			
		}
 
B

Beni

Gast
Das meiste ist ja ziemlich dasselbe.

Du musst jetzt einfach noch den JTree benachrichtigen, indem Du ein TreeModelEvent erzeugst (in der API steht, welche Argumente benötigt werden), und dann auf eine ähnliche Art wie in protected void fireNodeRemoved( TreePath path, int index, Object removed ) versendest.

Diese Methode deleteTree muss halt noch eine Verbindung zu den Models bekommen. Vielleicht speicherst Du irgendwo alle Models die etwas darstellen, so dass Du in deleteTree Zugriff hast, oder oder ... es gibt viele Varianten.

mfg Beni
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
D JTree nach Klick auf einen Hyperlink aktualisieren AWT, Swing, JavaFX & SWT 3
S JTree Elemente nach BaumLevel abspeichern AWT, Swing, JavaFX & SWT 2
H JTree - nach Auswahl aus JFileChooser wird nur der erste Knoten angezeigt AWT, Swing, JavaFX & SWT 3
F Weiße Lücke nach expandieren eines Pfades im JTree? AWT, Swing, JavaFX & SWT 4
A JTree wird erst nach Klick aktualisiert AWT, Swing, JavaFX & SWT 2
G JTree -- Node nach ändern in anderen Knoten AWT, Swing, JavaFX & SWT 15
W JTree je nach selektion JPane ein und ausblenden AWT, Swing, JavaFX & SWT 7
m@nu JTree: Äste nach refresh wiederherstellen AWT, Swing, JavaFX & SWT 3
M JTree Elemete zeigen nach 2. Mausklick Object an. Warum? AWT, Swing, JavaFX & SWT 2
H JTree nach instanzierung füllen AWT, Swing, JavaFX & SWT 4
M JTree nach LaF-Änderung komisch AWT, Swing, JavaFX & SWT 4
A JTree nach Node durchsuchen und expanden AWT, Swing, JavaFX & SWT 5
H JTree nach setzen eines neuen TreeModels aufklappen AWT, Swing, JavaFX & SWT 2
X JTree: Selektion nach dem Entfernen von Knoten AWT, Swing, JavaFX & SWT 2
FrittenFritze JTree, LazyLoading und "Rückwärtstraversion" AWT, Swing, JavaFX & SWT 3
J Falsches Rendern durch JCheckBox in eigenem JTree AWT, Swing, JavaFX & SWT 6
F jTree und das Model aus einer eigenen Klasse AWT, Swing, JavaFX & SWT 1
F Jtree aus Klasse mit Arraylisten AWT, Swing, JavaFX & SWT 1
A Swing JList zu JTree AWT, Swing, JavaFX & SWT 11
richis-fragen JTree +/- verschwidet wenn Knoten keine Kinder hat... AWT, Swing, JavaFX & SWT 6
RalleYTN Modaler Dialog und JTree Node mit sehr... seeeeehr vielen Elementen AWT, Swing, JavaFX & SWT 6
Z Swing JTree DefaultMultipleTreeNode Repräsentation ändern AWT, Swing, JavaFX & SWT 1
Z Swing Drag&Drop zwischen JTable und JTree AWT, Swing, JavaFX & SWT 4
W Swing Anzeigefehler bei JTree AWT, Swing, JavaFX & SWT 1
S Zwei JTree, ein Model, bei Selection im ersten JTree soll der zweite die Inhlate anzeigen AWT, Swing, JavaFX & SWT 2
S JRadioButton und JCheckBox im JTree AWT, Swing, JavaFX & SWT 14
H Swing JTree: Zählt der rootNode mit? AWT, Swing, JavaFX & SWT 2
krgewb Swing JTree - Farbe von nodes ändern AWT, Swing, JavaFX & SWT 4
R JTree behandeln AWT, Swing, JavaFX & SWT 2
E Swing Copy und Paste eines einzelnen Knoten aus einem JTree AWT, Swing, JavaFX & SWT 1
U dynamisches JTree erstellen AWT, Swing, JavaFX & SWT 2
J JTree updaten AWT, Swing, JavaFX & SWT 2
N Swing JTree Problem beim erstellen der Knoten AWT, Swing, JavaFX & SWT 0
H JTree in JScrollPane passt sich nicht an Größe von JPanel an AWT, Swing, JavaFX & SWT 2
T Swing API Frage zu Verzeichnisbäumen und JTree AWT, Swing, JavaFX & SWT 1
T JTree mit Symbolen? AWT, Swing, JavaFX & SWT 8
R Anfängerfrage: Ansichten des JTree AWT, Swing, JavaFX & SWT 1
H Swing JTree Minimumgröße AWT, Swing, JavaFX & SWT 2
F Swing JTree + DiffUtils // Markierung Nodes aufheben AWT, Swing, JavaFX & SWT 2
I JTree wird nicht angezeigt AWT, Swing, JavaFX & SWT 3
M Swing JTree AWT, Swing, JavaFX & SWT 4
M Nodes in JTree nicht anzeigen AWT, Swing, JavaFX & SWT 0
T JTree mit Cloud verbinden AWT, Swing, JavaFX & SWT 0
H JTree Probleme AWT, Swing, JavaFX & SWT 9
F Swing Drag and Drop in JTree aus verschiedenen Listen AWT, Swing, JavaFX & SWT 6
M JButton wird von JTree überdeckt AWT, Swing, JavaFX & SWT 4
J Auf Dateien in JTree zugreifen AWT, Swing, JavaFX & SWT 15
F jTree.startEditingAtPath(path); funktioniert nicht bei eigenem CellEditor? AWT, Swing, JavaFX & SWT 8
D Swing JTree Steuerung AWT, Swing, JavaFX & SWT 11
S Swing JTree verwirrt mich AWT, Swing, JavaFX & SWT 2
T JTree - Elemente mit Doppelklick auswählen AWT, Swing, JavaFX & SWT 6
J JTree speichern AWT, Swing, JavaFX & SWT 4
N Swing JTree TreeCellRenderer mit html und automatischen Zeilenumbruch AWT, Swing, JavaFX & SWT 8
O Swing JTree um Label (oder Panel) erweitern AWT, Swing, JavaFX & SWT 9
T JTree, Knoten mehrmals verwenden AWT, Swing, JavaFX & SWT 5
B JTree mit Ordneransicht in JPanel einbinden AWT, Swing, JavaFX & SWT 4
D JTree node reagiert bei Klick nicht immer AWT, Swing, JavaFX & SWT 2
M Swing JTree: Wie kann ich die Hintergrundfarbe der selection ändern?!?! AWT, Swing, JavaFX & SWT 7
D Mehrmals auf Node im JTree klicken AWT, Swing, JavaFX & SWT 2
D JSplitPane, Jtree, CardLayout (constraint must be a string) AWT, Swing, JavaFX & SWT 9
N Swing FileFilter lässt JTree sich nicht öffnen AWT, Swing, JavaFX & SWT 2
X Swing 2 TreeModel und ein JTree synchronisieren AWT, Swing, JavaFX & SWT 3
N Swing JTree TreePath zu Windows Pfad? AWT, Swing, JavaFX & SWT 2
RELAXccc Swing JTree + JScrollPane, refresh Problem AWT, Swing, JavaFX & SWT 17
X Swing JTree aktualisieren AWT, Swing, JavaFX & SWT 2
V Swing JTree - Umbenennen selbst handlen. AWT, Swing, JavaFX & SWT 2
E Übergebenem JTree Blätter hinzufügen AWT, Swing, JavaFX & SWT 2
E Wert eines selektierten Knotens in einem JTree auslesen AWT, Swing, JavaFX & SWT 3
A Swing JTree - Nodes expanden AWT, Swing, JavaFX & SWT 2
B JTree AWT, Swing, JavaFX & SWT 9
T Menüacceleratoren verschwinden bei JTree AWT, Swing, JavaFX & SWT 5
1 Swing JTree collapse child nodes AWT, Swing, JavaFX & SWT 4
B JTree - sehr individuell AWT, Swing, JavaFX & SWT 3
G Swing JTree - Verbindungslinien entfernen AWT, Swing, JavaFX & SWT 4
A Swing Herausfinden ob bei JTree Klick auf "+"/"-" anahnd x,y AWT, Swing, JavaFX & SWT 2
S Swing JTree und seine Listener... AWT, Swing, JavaFX & SWT 4
L Swing JTree wird nicht selektiert AWT, Swing, JavaFX & SWT 2
P [JTree] Markierhilfe der Drop-Location selber gestalten. AWT, Swing, JavaFX & SWT 4
A JTree aus Pfaden erzeugen AWT, Swing, JavaFX & SWT 3
K Swing Hilfe beim JTree! AWT, Swing, JavaFX & SWT 3
X Datensätze in JTree AWT, Swing, JavaFX & SWT 2
L Update JTree Verzeichnisse AWT, Swing, JavaFX & SWT 9
E JTree Auswahl AWT, Swing, JavaFX & SWT 2
K JTree width der Treenodes auf 100% AWT, Swing, JavaFX & SWT 6
C JTree LastSelectedPathComponent benutzen? AWT, Swing, JavaFX & SWT 3
S Swing JTree Node Text nicht richtig angezeigt AWT, Swing, JavaFX & SWT 2
Landei Swing JTree mit "Tabellenzeilen"? AWT, Swing, JavaFX & SWT 5
Rudolf Swing JTree Node anhand vom Namen finden AWT, Swing, JavaFX & SWT 4
Z JTree rootChilds AWT, Swing, JavaFX & SWT 2
D JTree DefaultMutableTreeNode ActionPerformed AWT, Swing, JavaFX & SWT 3
T JTree Daten in DB schreiben am besten SQL AWT, Swing, JavaFX & SWT 21
O JTree/TreeModel/DefaultMutableTreeNodes thread safe machen AWT, Swing, JavaFX & SWT 3
J Lazy Loading eine JTree während Scrollen AWT, Swing, JavaFX & SWT 11
S JTree & JComboBox - Elemente übers Fenster hinaus anzeigen AWT, Swing, JavaFX & SWT 9
E Swing JTree AWT, Swing, JavaFX & SWT 2
J Swing Lazy Loading in JTree wenn gescrollt wird AWT, Swing, JavaFX & SWT 3
N Knotenanordnung in JTree AWT, Swing, JavaFX & SWT 4
S JTree mit Liste zur Speicherung AWT, Swing, JavaFX & SWT 3
S Jtree CheckNode mit JPanel AWT, Swing, JavaFX & SWT 32
G JTree entfernt Nodes nicht AWT, Swing, JavaFX & SWT 12

Ähnliche Java Themen


Oben