问题
I have a table on database (code, composant, parent) where each node has a parent (a parent is also a component code), I need to fill a treeView dynamically from a select
@FXML
private TreeView tree;//declaration of the treeView
HashMap<Integer, composant> node = new HashMap<>(); //for child nodes
HashMap<Integer, composant> pere = new HashMap<>(); //for parent nodes
composant c; //object from component class
private void fillTree(String idSys) {
String query = "SELECT * FROM composant WHERE id=?";
try {
ps = cnx.prepareStatement(query);
ps.setString(1, idSys);
rs = ps.executeQuery();
while (rs.next()) {
int code = rs.getInt("code");
String composant = rs.getString("composant");
int parent = rs.getInt("parent");
String niveau = rs.getString("niveau");
int id = rs.getInt("id");
c = new composant(code, composant, niveau, parent, id);
node.put(code, c);
pere.put(parent, c);
}
ps.close();
rs.close();
} catch (Exception e) {
System.err.println("Error" + e);
}
TreeItem<String> system = new TreeItem<>(sys);
//brows and fill parents node
for (Integer k : pere.keySet()) {
composant p = pere.get(k);
TreeItem<String> parent = new TreeItem<>();
parent.setValue(p.getComposant());
//brows and fill child hashmap
for (Integer i : node.keySet()) {
composant c = node.get(i);
TreeItem<String> noeud = new TreeItem<>();
noeud.setValue(c.getComposant());
if (c.getParent() == k) {
//if the parent = 1 it must attach to the root node
if (k == 1) {
system.getChildren().add(noeud);
} else {
parent.getChildren().add(noeud);
}
}
}
}
tree.setRoot(system);
}
when compiling nothing appear on the window this is what I've got
回答1:
I'm almost sure the logic of creating the tree structure is wrong.
It's best if you simply create the TreeItem
s and store them by code in a map. Then iterate over the map and add every child to it's parent:
Map<Integer, TreeItem<String>> itemById = new HashMap<>();
Map<Integer, Integer> parents = new HashMap<>();
while (rs.next()) {
int code = rs.getInt("code");
String composant = rs.getString("composant");
int parent = rs.getInt("parent");
String niveau = rs.getString("niveau");
int id = rs.getInt("id");
itemById.put(code, new TreeItem<>(composant));
parents.put(code, parent);
}
ps.close();
rs.close();
TreeItem<String> root = null;
for (Map.Entry<Integer, TreeItem<String>> entry : itemById.entrySet()) {
Integer key = entry.getKey();
Integer parent = parents.get(key);
if (parent.equals(key)) {
// in case the root item points to itself, this is it
root = entry.getValue();
} else {
TreeItem<String> parentItem = itemById.get(parent);
if (parentItem == null) {
// in case the root item has no parent in the resultset, this is it
root = entry.getValue();
} else {
// add to parent treeitem
parentItem.getChildren().add(entry.getValue());
}
}
}
tree.setRoot(root);
Note that the above code assumes there is a unique root stored in the table. in case the query returns a forest where each root should be added to the root item of the TreeView
, simply initialize root
with a item instead
TreeItem<String> root = new TreeItem<>();
and add the items to root
instead of setting the root
// root = entry.getValue();
root.getChildren().add(entry.getValue());
来源:https://stackoverflow.com/questions/41185996/fill-javafx-treeview-from-database-dynamically