Toon posts:

[JAVA] Het maken van een tree vanuit de database

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo,

aangezien ik nu al enige tijd met een probleem romvecht en ik het niet helemaal 100% goed krijg post ik dit. Ik wil vanuit de volgende database gegevens een tree maken...
code:
1
2
3
4
5
6
7
8
9
10
+----+----------+--------------------+
| ID | MainPage | Titel              |
+----+----------+--------------------+
|  1 |        0 | Mainpage           |
|  2 |        1 | Sub Page 1         |
|  3 |        1 | Sub Page 2         |
|  4 |        1 | Sub Page 3         |
|  5 |        2 | Sub Sub Page 1     |
|  6 |        5 | Sub Sub Sub Page 1 |
+----+----------+--------------------+


Mainpage geeft de id weer waaronder de pagina moet hangen en de andere twee velden verklaren zich denk ik vanzelf.

Nu heb ik volgende bean gemaakt:
code:
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package CMSDataTree;

public class TreeBean {
    private int item_id_list[] = new int[100];
    private int item_upperlevelid_list[] = new int[100];
    private String item_space_list[] = new String[100];
    private String item_name_list[] = new String[100];
    private int list_pointer = 0;
    private int list_pointer_2;
    private int notlinkedsel;
    
    public TreeBean() { 
    }
    
    public String getItem_name(int i){
        return item_space_list[i] + " <img src = \"html_doc.JPG\"> <a href=\"DataTree.jsp?notlinkedsel=" + notlinkedsel + "&linkedsel=" + item_id_list[i] + "\">" + item_name_list[i] + "</a>";
    }
    
    public int getItem_ID(int i){
        return item_id_list[i];
    }

    public String getItem_name_Special(int i){
        return item_space_list[i] + " <img src = \"html_doc.JPG\"> <SPAN STYLE=\"font-family: Verdana; background-color:#3399FF\">" + item_name_list[i] + "</SPAN>";
    }
    
    public void addtreeitem(int item_id, int item_upperlevelid, String item_name){
        boolean found = false;
        list_pointer_2 = list_pointer;
        if(item_upperlevelid > 0){
            for (int i = 0; i < 100; i++){
                if (item_upperlevelid == item_id_list[i]){
                    found = true;
                    list_pointer_2 = i + 1;
                }
            }
        }
        if(found){
            for (int i = 99; i >= list_pointer_2; i--){
                item_id_list[i] = item_id_list[i-1];
                item_name_list[i] = item_name_list[i-1];
                item_space_list[i] = item_space_list[i-1];
                item_upperlevelid_list[i] = item_upperlevelid_list[i-1];
            }
        }
        if(item_upperlevelid > 0){
            System.out.println(item_space_list[list_pointer_2] + " = " +  item_space_list[list_pointer_2 - 1] + " + " + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
            item_space_list[list_pointer_2] = item_space_list[list_pointer_2 - 1] + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
        }else{
            item_space_list[list_pointer_2] = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
        }
        item_id_list[list_pointer_2] = item_id;
        item_upperlevelid_list[list_pointer_2] = item_upperlevelid;
        item_name_list[list_pointer_2] = item_name;        
        list_pointer++;
    }
    public void initialize_values(){
        for(int i = 0; i < 100; i++){
            item_id_list[i] = 0;
            item_upperlevelid_list[i] = 0;
            item_name_list[i] = "";
            item_space_list[i] = "";
        }
        list_pointer = 0;
    }
    
    /** Getter for property notlinkedsel.
     * @return Value of property notlinkedsel.
     */
    public int getNotlinkedsel() {
        return this.notlinkedsel;
    }
    
    /** Setter for property notlinkedsel.
     * @param notlinkedsel New value of property notlinkedsel.
     */
    public void setNotlinkedsel(int notlinkedsel) {
        this.notlinkedsel = notlinkedsel;
    }
    
}


in het programma zelf (een jsp) ga ik de database gegevens ophalen en voeg deze toe aan de tree volgens deze code:
code:
1
2
3
4
5
    rs = statement.executeQuery("select * from site where linked = 1 order by mainpage, titel desc;");
    while(rs.next()){
        TreeBeanId.addtreeitem(rs.getInt(1), rs.getInt(2), rs.getString(3));
        itemsadded++;
    }


dit werkt ook goed... ten minste als de gegevens zo zijn als boven, maar als deze gegevens anders zijn, namelijk zo:
code:
1
2
3
4
5
6
7
8
9
10
+----+----------+--------------------+
| ID | MainPage | Titel              |
+----+----------+--------------------+
|  1 |        0 | Mainpage           |
|  2 |        1 | Sub Page 1         |
|  3 |        4 | Sub Page 2         |
|  4 |        5 | Sub Page 3         |
|  5 |        2 | Sub Sub Page 1     |
|  6 |        2 | Sub Sub Sub Page 1 |
+----+----------+--------------------+

... werkt het niet... heeft misschien iemand een andere oplossing hiervoor?

Dit is uitkomst als het verkeerd gaat:
code:
1
2
3
4
5
6
 Mainpage 
            Sub Page 1 
                 Sub Sub Page 1 
                      Sub Page 3 
                 Sub Sub Sub Page 1 
                      Sub Page 2

Maar dit had het moeten zijn:
code:
1
2
3
4
5
6
 Mainpage 
            Sub Page 1 
                 Sub Sub Page 1 
                      Sub Page 3 
                            Sub Page 2  
                 Sub Sub Sub Page 1


Alvast bedankt!!! _/-\o_

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 14:03

Robtimus

me Robtimus no like you

Je gebruikt een object georienteerde taal maar gebruikt geen objecten. Ik weet niet of dit een beperking van EJB is, maar ik ga ervan uit van niet.

Ik zou een nieuwe class maken, Node, met een aantal fields:
  • int/long ID
  • Node parent
  • java.util.List children (bevat Nodes)
  • String name
Zodra je dus een Node (genaamd node) moet maken (met ID, parent ID en naam), dan zoek je de parent op. Je zet van node de ID, naam en parent. Bij die parent voeg je vervolgens node toe aan de lijst van children:
Java:
1
2
3
Node parent = <find parent>;
Node node = new Node(id, name, parent);
parent.addChild(node);
In Node.java:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
public Node(int/long id, String name, Node parent)
{
    this.id = id;
    this.name = name;
    this.parent = parent;
    this.children = new <List implementatie, bv ArrayList>();
}


public void addChild(Node node)
{
    children.add(node);
}


Aangezien je niet altijd 1 volledige tree hebt maar vaak ook subtrees moet je ook alle nodes in een List hebben. Daarin kun je dan ook zoeken naar de parent.

Op het einde hoef je alleen maar te weten wat de root node is, de rest haal je uit de children, en de children van de children, etc.


PS: in code mag je gewoon " etc gebruiken, je hoeft echt geen &quot; te gebruiken.

[ Voor 46% gewijzigd door Robtimus op 01-11-2003 15:54 . Reden: Code toegevoegd ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Verwijderd

Topicstarter
dankje! ik zal het uitproberen...

ps.: dat met de " wist ik en zo staat het ook in me code, alleen heeft dit forum het veranderd...

Verwijderd

Topicstarter
Ik ben ff bezig geweest maar krijg weer deze fout:

code:
1
2
3
4
5
6
7
8
9
DataTree$jsp.java [385:1] cannot resolve symbol
symbol  : class Node  
location: class org.apache.jsp.DataTree$jsp
                        Node node = new Node(rs.getInt(1), rs.getInt(2), rs.getString(3));
                        ^
DataTree$jsp.java [385:1] cannot resolve symbol
symbol  : class Node  
location: class org.apache.jsp.DataTree$jsp
                        Node node = new Node(rs.getInt(1), rs.getInt(2), rs.getString(3));


en als ik op google zoek of men Objects mag gebruiken in JSP's vind ik niet de informatie die ik zoek... Er zijn wel wat objects die je mag gebruiken, maar dat zijn standaard objects zoals page of session... Heeft iemand hier ervaring in??? :?

Edit: Ik heb de aanroep nu in een bean geplaats, en dat werkt wel... het blijkt dus dat je geen objects mag aanmaken binnen een JSP.

[ Voor 9% gewijzigd door Verwijderd op 02-11-2003 14:09 ]


Verwijderd

Topicstarter
Nu zit ik met het volgende probleem... hoe vindt ik de parent van een node, en stel dat node nog geen parent heeft als ik hem toevoeg, wat gebeurd er dan?

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 14:03

Robtimus

me Robtimus no like you

Je moet class Node natuurlijk wel zelf schrijven he?
Verwijderd schreef op 02 november 2003 @ 14:16:
Nu zit ik met het volgende probleem... hoe vindt ik de parent van een node, en stel dat node nog geen parent heeft als ik hem toevoeg, wat gebeurd er dan?
Men neme een List, daarin stop je alle Nodes die je creeert. In die lijst zoeke men naar de eerste Node die het ID heeft van de parent:
Java:
1
2
3
4
5
6
7
8
9
Node parent = null;
for (int i = 0; i < nodes.size(); i++)
{
    if (((Node)nodes.get(i)).getID() == <parentID>)
    {
        parent = (Node)nodes.get(i);
        break;
    }
}
Als hierna parent nog steeds null is is de parent blijkbaar nog steeds niet gecreeerd. Je zou dan de Node in een andere lijst kunnen stoppen, en elke keer als je een nieuwe Node maakt kijken of hij de parent van zo'n node moet zijn. Is heel wat overhead die je kunt vermijden door de items zo in de database te stoppen dat dit geval niet voorkomt.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Verwijderd

Topicstarter
Oke... ik heb nu alle items in de lijst met de daarbijbehorende parent en childrens. (Heb het met twee lijsten opgelost, een waar de parents gevonden waren, en een waar geen parents gevonden zijn en welke niet de root is)

Ik ben nu op het moment bezig om de gegevens die ik nu zo mooi verzameld heb op een slimme manier om te zetten in een HTML lijst... wat zou hier voor een slimme manier zijn?

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 14:03

Robtimus

me Robtimus no like you

HTML lijst als in <ul>?

Maak een node to <il> functie:
<li>node naam
als hij kinderen heeft:
<ul>
"node to <il> voor alle kinderen"
</ul>

Vervolgens roep je die functie aan voor de root node (met ervoor en erna een <ul> en </ul>)

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Verwijderd

Topicstarter
Uhmm... ja... daar dacht ik ook aan... alleen heb ik eerst iets anders nodig, namelijk zeg maar een lijst met daarin de namen en het niveau... dus stel je hebt een root en daaronder hangt twee Sub Pages, en onder de eerste Sup Page een Sub Sub Page... dan wil ik dus het volgende:

1 Root
2 Sub Page
3 Sub Sub Page
2 Sub Page

dus dat alles te zien is, en dat je ook het nieveau hebt... (later wil ik die getallen vervangen door een aantal spaties... dus bij 1 = 0 spaties, en 2=5 spaties, 3=10 spaties, enz. , enz.)

ik hoop dat je nu me probleem beter snapt :)

oh ja... hartstikke bedankt voor al je hulp tot nu toe!!! _/-\o_

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 14:03

Robtimus

me Robtimus no like you

Geef elke node ook een diepteveld (initieel 0). Dat wordt bij het instellen van de parent gelijk aan het diepteveld van die parent + 1. Hoef je ook geen extra lijst te gebruiken want je houdt het bij in de nodes, dus in je al bestaande lijsten.

De volgorde die je wilt haal je uit de boom zelf.

[ Voor 3% gewijzigd door Robtimus op 02-11-2003 17:42 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Verwijderd

Topicstarter
Oke... dat met het niveau toevoegen in de Node snap ik... maar wat bedoel je met dat ik de volgorde uit de tree kan halen?

Er moet dus geen restrictie zijn in de diepte van de levels...

[ Voor 22% gewijzigd door Verwijderd op 02-11-2003 17:49 ]


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 14:03

Robtimus

me Robtimus no like you

De root heeft diepte 0. Al zijn kinderen hebben diepte 1, al hun kinderen diepte 2, etc. De enige beperking is de grote van het type van de diepte (int/long), en de hoeveelheid geheugen die je hebt (je hele tree zit er immers in).

Als je eerst de root wil, dan zijn eerste kind met al zijn kind etc, dan doorloop je gewoon de boom:
Java:
1
2
3
4
5
6
7
8
9
10
for (int i = 0; i < root.getChildren().size(); i++)
{
    for (int j = 0; j < ((Node)root.getChildren().get(i)).getChildren().size(); j++)
    {
        for (int k = 0; k < ...; k++)
        {
            ....
        }
    }
}
Zo krijg je dus alle nodes op de volgorde die je wilt.

PS: je doet dit natuurlijk wel recursief he?

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Verwijderd

Topicstarter
Johoeee het werkt :*) :*) :*)

thnx so much!!! _/-\o_


dit is trouwens de code (volgens mij bedoelde je dat met recursief):

public void generateTree(PageNode root){
HTML_Tree = HTML_Tree + "<br>     ";
for(int i = 0; i < root.niveau; i++){
HTML_Tree = HTML_Tree + "     ";
}
HTML_Tree = HTML_Tree + "<img src = \"html_doc.JPG\">" + root.name;
for (int i = 0; i < root.children.size(); i++){
generateTree((PageNode)root.children.get(i));
}
}

P.s.: ik heb het niet in code gezet, anders gaat ie weer die " veranderen... zeer vreemd

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 14:03

Robtimus

me Robtimus no like you

Verwijderd schreef op 02 november 2003 @ 18:45:
Johoeee het werkt :*) :*) :*)

thnx so much!!! _/-\o_


dit is trouwens de code (volgens mij bedoelde je dat met recursief):

public void generateTree(PageNode root){
HTML_Tree = HTML_Tree + "<br>     ";
for(int i = 0; i < root.niveau; i++){
HTML_Tree = HTML_Tree + "     ";
}
HTML_Tree = HTML_Tree + "<img src = \"html_doc.JPG\">" + root.name;
for (int i = 0; i < root.children.size(); i++){
generateTree((PageNode)root.children.get(i));
}
}

P.s.: ik heb het niet in code gezet, anders gaat ie weer die " veranderen... zeer vreemd
Dat bedoelde ik idd met recursief :)

Nog een laatste tip:
Ik ga ervanuit dat HTML_Tree een String is. Je hebt dus heel veel String concatenaties.
Probeer eens over te stappen op het gebruik van StringBuffer's.

Ipv
Java:
1
String HTML_Tree = ""; HTML_Tree = HTML_Tree + "....." + "....";
krijg je dan
Java:
1
StringBuffer HTML_Tree = new StringBuffer(); HTML_Tree.append("....").append("...."); String str = HTML_Tree.toString();
Het gebruik van een StringBuffer is, vooral met veel toevoegingen, een heel stuk efficienter dan de String, vooral gezien in tijd en geheugen gebruik.

More than meets the eye
There is no I in TEAM... but there is ME
system specs

Pagina: 1