Toon posts:

[JAVA] JTree implementatie

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo,

Ik ben momenteel bezig met een klein projectje. Hierbij wil ik een Jtree maken, waarbij ik als 'input' een ArrayList heb die bestaat uit een Object Variabele. In deze variabele staat een naam, de naam van de parent (staat in dezelfde ArrayList) en een waarde. De Jtree leafs van de tree kunnen ook weer childeren hebben.

Ik wil dus uiteindelijk de volgende output in een JTree (het aantal variabele kan verschillen, in mijn huidige programma heb ik er 22, maar het moet ook met meer of minder kunnen):
+var1
-----+var2
------------+var4
----+-var3

Ik heb momenteel de volgende code, die het model voor de tree moet inladen:
Java: Variabele.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Variabele {

    String naam;
    String parent;
    double waarde;

    public Variabele(String p_naam, String p_parent, double p_waarde) {
        naam = p_naam;
        parent = p_parent;
        waarde = p_waarde;
    }

    public String getNaam() {
        return naam;
    }

    public String getParent() {
        return parent;
    }

    public double getWaarde() {
        return waarde;
    }
}

Java: VarTreeNode.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package programma.swing;

import programma.lib.Variabele;
import java.util.ArrayList;
import javax.swing.tree.*;
import javax.swing.JTree;


public class VarTreeNode {

    public static JTree getTreeNode(ArrayList<Variabele> list) {
        ArrayList<DefaultMutableTreeNode> nodelist = new ArrayList<DefaultMutableTreeNode>();
        JTree parent;
        nodelist.add(new DefaultMutableTreeNode(list.get(0).getAfkorting(), true)); //Maak root
        for (int k = 1; k < list.size(); k++) {
            nodelist.add(new DefaultMutableTreeNode(list.get(k).getAfkorting())); // zet alle variabele om naar TreeNodes
        }
        for (int k = 1; k < list.size(); k++) {
            String strparent = list.get(k).getParent(); // Haal de parent uit de variabele
            int index = -1;
            for (int i = 0; i < nodelist.size(); i++) {
                if (strparent.compareTo(nodelist.get(i).toString()) == 0) {
                    index = nodelist.get(0).getIndex(nodelist.get(i)); //Deze regel is om te kijken of de parent al is toegevoegd aan de root
                    if (index == -1) {
                        //De parent staat nog niet in de root, voeg de child toe aan de parent
                        nodelist.get(i).add(nodelist.get(k));
                    } else {
                        //De parent staat al in de root, voeg de child toe aan de parent die al in de root staat
                        ((nodelist.get(0)).getChildAt(index)).add(nodelist.get(k)); // Hier gaat het fout
                        /* Ik krijg 'cannot find symbol' te zien. Als ik bij de lijst van methodes kijk die ik te zien krijg
                        * als ik de punt neetzet na ((nodelist.get(0)).getChildAt(index)) staat add er ook niet bij.
                        * Enkel de methodes van de klasse javax.swing.tree.TreeNode ipv de methodes van javax.swing.tree.DefaultMutableTreeNode
                        * waar de methode add instaat. Hoe kan ik dit anders doen?
                         */
                    }
                }
            }

        }
        parent = new JTree(new DefaultTreeModel(nodelist.get(0))); //Zet het zooitje in een JTree
        return parent;
    }
}


Zoals ik al vermelde in de code loop ik dus vast op regel 29, als ik een child probeer te voegen bij een een parent die al in de root staat en dus eigenlijk zelf al een parent heeft.

De dingen die ik al heb geprobeerd:
- casten, dit leidt tot een melding: inconvertable types
- mijn breiwerk uit elkaar gehaald, maakte geen verschil

Als iemand weet hoe het moet oplossen of als ik helemaal verkeerd bezig ben, dan hoor ik dat graag. Alvast bedankt.

Acties:
  • 0 Henk 'm!

Verwijderd

Waarom sla je de naam van de parent node op ? Waarom niet een referentie naar de parent node ?

Als ik zo snel naar de code kijk denk ik dat je niet helemaal het principe van de JTree begrijpt. Ik zou je willen adviseren om hier is naar te kijken: http://java.sun.com/docs/...wing/components/tree.html

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dat kwam zo uit met programmeren, maar een referentie had wel handiger geweest.

Ik heb nog gekeken naar de link. Ik snap het nu wel beter, maar de code voorbeelden die daar worden gebruik zijn vrij concreet, terwijl mijn implementatie veel meer abstact is. (met name door het gebruik van de ArrayList)
Dus ik zie nog steeds de oplossing voor mijn probleem niet.

Acties:
  • 0 Henk 'm!

  • momania
  • Registratie: Mei 2000
  • Laatst online: 21:44

momania

iPhone 30! Bam!

Verwijderd schreef op zaterdag 20 juni 2009 @ 12:16:
Dus ik zie nog steeds de oplossing voor mijn probleem niet.
Je ziet je probleem niet, laat staan de oplossing ;)

Een single list is een totaal andere data structuur dan een tree.

Neem je whisky mee, is het te weinig... *zucht*


Acties:
  • 0 Henk 'm!

Verwijderd

Verwijderd schreef op zaterdag 20 juni 2009 @ 12:16:
Dat kwam zo uit met programmeren, maar een referentie had wel handiger geweest.
Ik kan me niet voorstellen dat het wenselijk is dat je de naam van de parent node opslaat in een child en dat je dat als aanknopingspunt gebruikt. Het enige wat ik kan bedenken waarbij dat het geval is is bij serializatie maar we hebben het nu over Swing. Wat doe je dan als je de naam van een parent wijzigd ? Dan ga je over alle childs iteraten om de naam aan te passen ? OO technisch gezien is dat gewoon bad practice en moet vermeden worden.
Ik heb nog gekeken naar de link. Ik snap het nu wel beter, maar de code voorbeelden die daar worden gebruik zijn vrij concreet, terwijl mijn implementatie veel meer abstact is. (met name door het gebruik van de ArrayList)
Dus ik zie nog steeds de oplossing voor mijn probleem niet.
Voor wat jij wilt zal je je eigen Model voor de JTree moeten maken door of TreeModel te implementen of DefaultTreeModel te extenden. Je probeert nu een kubus door een rond gat te slaan met een hamer ;)

Als algemene tip voor het gebruik van Swing zou ik zeggen kijk hier is naar: http://java.sun.com/products/jfc/tsc/articles/architecture/ . De architectuur van Swing is erg uitgebreid en maakt heel veel mogelijk (Dit kan je bijvoorbeeld doen met Swing: http://code.google.com/p/macwidgets/), echter daardoor is hij ook best complex en misschien in het begin zelfs wel intimiderend.

Acties:
  • 0 Henk 'm!

  • ingdas
  • Registratie: Mei 2007
  • Laatst online: 05-08-2013
hoi

Ik weet niet goed waar je naartoe wil. Ik heb het eventjes een implementatie gemaakt die een de naam als naam neemt voor iedere node. (die waarden uit Variabele zijn dan nutteloos, dus ik vermoed dat ik verkeerd ben op sommige punten maar misschien kan je er toch iets mee).
De klasse Variabele heb ik gewoon gekopieerd van jou, de import Variabele zal je er wel weer zelf moeten bijzetten.
Ook moet ik nog zeggen dat ik niet getest heb (had geen zin om zelf een hoop variabelen aan te maken), dus ik garandeer niet dat dit werkt.
Als je nog iets wil vragen erover, of iemand een beter alternatief heeft, hoor ik het graag
Anyway: hier mijn verise van de code.
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import java.util.ArrayList; 
import java.util.HashSet;
import java.util.Iterator;
import javax.swing.JTree; 
import javax.swing.tree.DefaultMutableTreeNode;


public class VarTreeNode { 

    /**
     * @pre de te maken root is het eerste element van de ArrayList
     *
     * @param list de ArrayList die moet geconverteerd worden naar tree
     * @return die ArrayList in een Tree-vorm gegoten, als er objecten zijn in de lijst die geen child zijn van de eerste node worden deze genegeerd
     */
    public static JTree getTreeNode(ArrayList<Variabele> list) {
        ArrayList<Variabele> clonedList=(ArrayList<Variabele>)list.clone(); //clonen van de list omdat we die later zullen wijzigen

        HashSet<DefaultMutableTreeNode> toCheckForChildren = new HashSet<DefaultMutableTreeNode>(); //maak een lege hashset aan voor nodes
        DefaultMutableTreeNode root=new DefaultMutableTreeNode(clonedList.get(0).getNaam()); //maak de root aan (het eerste element van het array)
        toCheckForChildren.add(root); //add de root aan de hashset
        clonedList.remove(0); //remove de root van de lijst (we zullen telkens als we een Variabele in de tree gestoken hebben hem uit de lijst removen
                                    //we weten immers zeker dat 1 element geen 2 keer in de tree zal voorkomen en hiermee kunnen we dus de tijdscomplexiteit verlagen)

        /* De algemene strategie an deze while-loop is als volgt:
         *  van de nodes die nog niet onderzocht zijn (elementen van toCheckForChildren) kijken we of er nog 
         *  kinderen bestaan in de lijst, indien dit het geval is voegen we ze toe als kinderen aan de juiste
         *  node en aan de verzameling toCheckForChildren.
         *  Het algoritme stopt op het moment dat er geen nog niet onderzochte nodes zijn.
         *  Let op: het kan zijn dat er elementen uit de meegegeven lijst niet in de boom zitten,
         *  dit gebeurt als niet alle Strings indirect verbonden zijn met de naam van het eerste element
         *
         * */
        
        while(!toCheckForChildren.isEmpty()){
            Iterator<DefaultMutableTreeNode> nodeIterator=toCheckForChildren.iterator();
            while(nodeIterator.hasNext()){
                DefaultMutableTreeNode nodeToCheck= nodeIterator.next();
                String nameToCheck=nodeToCheck.toString();
                
                Iterator<Variabele> varIterator=clonedList.iterator();
                //de binnenste while loop kijkt of er een (of meerdere) element(en) van de meegegeven is die overeenkomt met de naam van de huidige nodeToCheck
                while(varIterator.hasNext()){
                    Variabele varToCheck=varIterator.next();
                    String varNameToCheck=varToCheck.getParent();
                    if(nameToCheck.equals(varNameToCheck)){
                        DefaultMutableTreeNode toBeAdded=new DefaultMutableTreeNode(varToCheck.getNaam());
                        nodeToCheck.add(toBeAdded);
                        toCheckForChildren.add(toBeAdded);
                        varIterator.remove();
                    }
                }
            }
        }
        return new JTree(root);
    } 
}
Pagina: 1