im JTree suchen



  • Hi,

    wie kann ich in einem JTree nach dem angezeigten Namen eines Nodes suchen (ich verwende DefaultMutableTreeNodes und eine Klasse NodeContent, die das Attribut name enthält)?
    Als return hätte ich gerne in Form von TreePath, da ich die Methode expandPath(TreePath path) darauf anwenden kann.

    Bsp.
    Irgendwo im JTree gibts einen Knoten namens "Buch". Ich möchte diesen nun finden und Expandieren.

    Vielen Dank schon mal.



  • Schau mal hier nach, da wirst du fündig.
    http://javaalmanac.com/egs/javax.swing.tree/FindNode.html



  • Titus schrieb:

    Schau mal hier nach, da wirst du fündig.
    http://javaalmanac.com/egs/javax.swing.tree/FindNode.html

    Der Tipp ist super! Danke für die URL, ist auch für mich interessant.

    Gruß, seppelina



  • Vielen Dank erst mal.

    getNextMatch() nützt nicht viel, weil es dummerweise nur in sichtbaren Knoten sucht.

    Der folg. Code von javaalmanac.com nützt irgendwie auch nicht viel, denn man muss den kompletten Pfad des zu suchenden Strings als String-Array angeben.
    Wenn ich aber irgendeinen Knoten suche, weiss ich doch nicht im voraus welchen Pfad dieser hat!!! 😮

    Bsp.:

    Dokumente
    |_irgendwas
      |_Autor
    

    Die Suche nach "Autor" funzt so nicht:

    TreePath currPath = findByName(jTree1, new String[]{"Autor"});
    

    Dazu müsste man das so angeben:

    TreePath currPath = findByName(jTree1, new String[]{"Dokumente", "irgendwas", "Autor"});
    

    Das kann doch nicht der Sinn einer Suchfkt. sein, oder?

    der Code:

    // Finds the path in tree as specified by the array of names.
        // The names array is a sequence of names where names[0]
        // is the root and names[i] is a child of names[i-1].
        // Comparison is done using String.equals().
        // Returns null if not found.
        public TreePath findByName(JTree tree, String[] names) {
            TreeNode root = (TreeNode)tree.getModel().getRoot();
            return find2(tree, new TreePath(root), names, 0, true);
        }
        private TreePath find2(JTree tree, TreePath parent, Object[] nodes, int depth, boolean byName) {
            TreeNode node = (TreeNode)parent.getLastPathComponent();
            Object o = node;
    
            // If by name, convert node to a string
            if (byName) {
                o = o.toString();
            }
    
            // If equal, go down the branch
            if (o.equals(nodes[depth])) {
                // If at end, return match
                if (depth == nodes.length-1) {
                    return parent;
                }
    
                // Traverse children
                if (node.getChildCount() >= 0) {
                    for (Enumeration e=node.children(); e.hasMoreElements(); ) {
                        TreeNode n = (TreeNode)e.nextElement();
                        TreePath path = parent.pathByAddingChild(n);
                        TreePath result = find2(tree, path, nodes, depth+1, byName);
                        // Found a match
                        if (result != null) {
                            return result;
                        }
                    }
                }
            }
    
            // No match at this branch
            return null;
        }
    


  • Dann geh doch rekursiv vom Root-Knoten des Baums alle möglichen Wege ab. So findest du auf jeden Fall den gewünschten Knoten / das gewümschte Blatt.

    public static DefaultMutableTreeNode searchTreeNodeByInstanceID(DefaultMutableTreeNode myParentNode, String myInstanceID){
    		DefaultMutableTreeNode tmpTreeNode = null;
    		String tmpInstanceID = null;
    
    		// Loop through all children and ...
    		int tmpChildCount = myParentNode.getChildCount();
    		for(int i = 0; i < tmpChildCount; i++){
    			tmpTreeNode = (DefaultMutableTreeNode)myParentNode.getChildAt(i);
    
    			// ... search for the instance ID
    			tmpInstanceID = ((NodeInfo)tmpTreeNode.getUserObject()).getProperty("InstanceID");
    			if((tmpInstanceID != null) && tmpInstanceID.equals(myInstanceID)){
    				return tmpTreeNode;
    			}
    
    			// Continue the recursive search
    			if((tmpTreeNode = searchTreeNodeByInstanceID(tmpTreeNode, myInstanceID)) != null){
    				return tmpTreeNode;
    			}
    		}
    
    		return null;
    	}
    


  • Ah ja, thx.
    Ich kenne mich mit der Navigierung durch JTree und allem was dazugehört (Nodes, ...) nicht so gut aus. Deswegen wollte ich selbst keine Suchfkt. schreiben, da ich zuviel Zeit mit dem suchen von irgendwelchen Methoden aufbrigen müsste und das ganze dann sicher auch ziemlich ineffizient wäre.

    Ich hatte halt gedacht, dass es schon eine sinnvolle Suchmethode standardmässig gibt...scheint aber irgendwie nicht so.

    Ich verwende kein NodeInfo zum Verwalten der Inhalte..habe es daher auf meine eigene Klasse NodeContent umgebaut.

    Jetzt müsste ich aber irgendwie den DefaultMutableTreeNode noch in einen TrePath umwandeln, damit z.B. expandPath() und setSelectionPath() nutzen kann.

    Kannst Du mir noch sagen, wie das geht ?



  • NodeInfo war mein benutzerspezifisches Objekt. Da musst du natürlich deins reinstecken, was du ja auch gemacht hast.

    Den TreePath bekommst du über getPath() der Klasse DefaultMutableTreeNode. So stehts jedenfalls in der API.



  • Thx.
    Aber getPath() liefert einen TreeNode, anstatt einen TreePath zurück.
    Und soweit ich sehe gibt es keinen TreePath-Konstruktor, dem man einen TreeNode übergeben kann, oder?
    Und TreeNode hat auch keine Methode die einen TreePath zurück gibt. 😞



  • Ups, du hast recht. Versuchs mal mit ...
    http://javaalmanac.com/egs/javax.swing.tree/Node2Path.html



  • Danke, jetzt funzt alles supi.

    PS: Ich finde SUN muss den JTree in Zukunft etwas kompfortabler gestallten. Macht doch keinen Spass, wenn man jedes kleine Detail selber machen muss...


Anmelden zum Antworten