-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Dear All,
I require a Tree List in a following fashion which has been filled by a Database Table. and also require manipulation effects to Tree List (I tried it in many way but I am not able to do)
-ASSET (Group) -Fixed Asset (Group) +Furniture (Group) - Electronics Machineries (Group) - Computers & Printers (Group) - Dell Server (Item) - HP Notebook (Item) + UPS Systems (Group) + Current Assets(Group) + Liablities(Group) + Income(Group) + Expenditure(Group)
Thanks in advance
Hi
you can refer to Tree Model
In this threads is all what you need. But it should be optimized because it have too much DB calls.
The magic is the right table structure.
- Each ChildNode have a field 'parentNode' wich holds the record ID of it's parent.
- In your case you must extend it to a flag field 'Group' (boolean) = true/false and handle this flag in the ItemRenderer.
In my case the structure (simplified) for a tree that depends on a master entry looks like:
MasterTable /* EN: Create the NAMES of the several charts of accounts for the tenants */ /* DE: Erzeuge Kontenrahmen Bezeichnung fuer die Test-Mandanten */ INSERT INTO fib_kto_rahmen ( ktr_id, ktr_tnt_id, ktr_shorttext, ktr_longtext ) values ( 1, 10, 'DATEV SKR03', 'Standardkontenrahmen 03 fuer Personengesellschaften'), ( 2, 10, 'DATEV SKR04', 'Standardkontenrahmen 04 fuer Kapitalgesellschaften'); DETAIL Tree records /* EN: Create the names of the several account categories for charts of accounts */ /* here for: 'KontoRahmen SKR03' for test tenant-ID='10' */ /* DE: Erzeuge Konten-Kategorien fuer die Kontenrahmen der Test-Mandanten */ /* hier fuer 'KontoRahmen SKR03' fuer Test Mandant ID='10' */ INSERT INTO fib_kto_kategorie ( kkg_id, kkg_tnt_id, kkg_ktr_id, kkg_shorttext, kkg_parent_node ) values /* Debitoren */ ( 1, 10, 1, 'SKR03 Kontorahmen', 0 ), ( 5, 10, 1, 'Debitoren', 1 ), ( 6, 10, 1, 'sonstige', 5 ), /* Kreditoren */ ( 10, 10, 1, 'Kreditoren', 1 ), ( 11, 10, 1, 'sonstige', 10 ), /* Sachkonten */ ( 20, 10, 1, 'Sachkonten', 1 ), /* Abschreibungen */ ( 30, 10, 1, 'Abschreibungen', 20 ), ( 31, 10, 1, 'Finanzanlagen', 30 ), ( 32, 10, 1, 'Geringwertige WG', 30 ), ( 33, 10, 1, 'Sachanlagen', 30 ), ( 34, 10, 1, 'sonstige', 30 ), /* Aktive Rechnungsabgrenzung */ ( 40, 10, 1, 'Aktive Rechnungsabgrenzung', 20 ), ( 41, 10, 1, 'sonstige', 40 ), /* Anlagevermoegen */ ( 50, 10, 1, 'Anlagevermögen', 20 ), ( 51, 10, 1, 'Finanzanlagen', 50 ), ( 52, 10, 1, 'Firmenwert', 50 ), ( 53, 10, 1, 'Geringwertige WG', 50 ), ( 54, 10, 1, 'Sachanlagen', 50 ), ( 55, 10, 1, 'sonstige', 50 ), /* Betriebsausgaben */ ( 60, 10, 1, 'Betriebsausgaben', 20 ), ( 61, 10, 1, 'betriebliche Steuern', 60 ), ( 62, 10, 1, 'Bewirtungskosten', 60 ); . . . Looks like /* RootNode */ SKR03 Kontorahmen - Debitoren - sonstige - Kreditoren - sonstige - ( ID=20) Sachkonten - (ID=30) Abschreibungen (parentNode=20) - Finanzanlagen (parentNode=30) - Geringwertige WG (parentNode=30) - Sachanlagen (parentNode=30) . . .
Hope it helps a little bit. Here is a pic of the running tree.
best
Stephan
Hi samchuang,
I am confused how to fill ModelTree with Parent & Child relationship. Following is the snapshot of Table Data.
acno acgroupflag parentgrp acname 1 G 0 ASSET 2 G 1 Fixed Asset 3 G 2 Furniture (Group) 4 G 3 Electronics Machineries 5 G 4 Computers & Printers 6 I 5 Dell Server (Item) 7 I 5 HP Notebook (Item) 8 G 4 UPS Systems (Group) 9 G 1 Current Assets(Group) 10 G 0 Liablities(Group) 11 G 0 Income(Group) 12 G 0 Expenditure(Group)
Thanks
again, there's all in Rico's thread with good explanations. You must adapt it to your needs (beans).
Here's my adaptions for a special need. And yes, that's a few classes. That's the reason why answering is difficult. It costs much time to prepare such things for demonstration.
So i can only give you the codes. In hope you take the time for studying.
So it's java, there is the way over objects. So we take objects to hold the DB's data. For a tree we need special classes that holds the data.
Remember: The tree is hierarchical ordered. So it's necessary to use ordered db data ( by PerantNodeID ) by a fit table select statement.
Tree --> TreeitemRenderer --> TreeModel --> hold TreeItems --> holds TreeNodes
.
call in the controller
/** * EN: Fill the accountCategories Tree with data depended on the defined * chart of accounts.<br> * DE: Fuellt den KontoKategorie Baum abhaengig vom gewaehlten KontoRahmen.<br> */ public void doFillKontoKategorieTree() { doFitSize(); // Force to start filling the root's children if (getSelectedKontoRahmen() != null) { Tenant tenant = ((UserImpl) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUserTenant(); // CREATE the ROOT Node RootKontoKategoryNode root = new RootKontoKategoryNode(); root.setTenant(tenant); root.setKontoRahmen(getSelectedKontoRahmen()); // START reading the Nodes root.readChildren(); // CREATE and SET the model to tree FDTreeModel tm = new FDTreeModel(root); tree_KontoKategorie.setModel(tm); tree_KontoKategorie.setTreeitemRenderer(new KontoKategorieTreeItemRenderer()); } } ONLY FOR SHOWING (this method is from an other Tree, sorry) /** * Selects the object in the tree by a doubleClick.<br> * Event is forwarded in the corresponding * ItemRenderer(FibuReportCategoryTreeItemRenderer). */ public void onDoubleClickedFibuBerichtKategoryItem(Event event) { // logger.debug(event.toString()); /** * We CAST it down to the right component */ Treeitem ti = (Treeitem) ((ForwardEvent) event).getOrigin().getTarget(); FibuBerichtKategorie fibuBerichtKategorie = ((FibuReportCategoryNode) ti.getAttribute("data")).getFibuBerichtKategorie(); if (fibuBerichtKategorie != null) { setSelectedFibuBerichtKategorie(fibuBerichtKategorie); . . . } }
TreeItemRenderer
/** * ItemRenderer for the Tree.<br> * First and second level have different icons.<br> * * @author Stephan Gerth */ public class KontoKategorieTreeItemRenderer implements TreeitemRenderer { @Override public void render(Treeitem item, Object data) throws Exception { item.setAttribute("data", data); Treerow tr = new Treerow(); tr.setParent(item); Treecell tc = new Treecell(); // set the icon, depending of the level of the tree if (data instanceof RootKontoKategoryNode) { // Cast it down KontoKategorie kontoKategorie = ((RootKontoKategoryNode) data).getKontoKategorie(); tc.setLabel(kontoKategorie.getShorttext()); tc.setStyle("text-align: left"); tc.setParent(tr); if (kontoKategorie.getParentNode() == 0) { tc.setImage("/images/icons/view.gif"); } else if (kontoKategorie.getParentNode() != 0) { tc.setImage("/images/icons/index_16x16.gif"); } } else if (data instanceof KontoKategoryNode) { KontoKategorie kontoKategorie = ((KontoKategoryNode) data).getKontoKategorie(); tc.setLabel(kontoKategorie.getShorttext()); tc.setStyle("text-align: left"); tc.setParent(tr); if (kontoKategorie.getParentNode() == 0) { tc.setImage("/images/icons/view.gif"); } else if (kontoKategorie.getParentNode() != 0) { tc.setImage("/images/icons/index_16x16.gif"); } } item.setOpen(false); ComponentsCtrl.applyForward(item, "onDoubleClick=onDoubleClickedKontoKategorieItem"); } }
TreeModel
/** * TreeModel class. * */ public class FDTreeModel extends AbstractTreeModel { private static final long serialVersionUID = 1L; FDTreeNode root; public FDTreeModel(FDTreeNode root) { super(root); this.root = root; } @Override public Object getChild(Object parent, int arg1) { return ((FDTreeNode) parent).getChild(arg1); } @Override public int getChildCount(Object parent) { return ((FDTreeNode) parent).getChildCount(); } @Override public boolean isLeaf(Object node) { if (node == null) { return true; } return ((FDTreeNode) node).isLeaf(); } }
/** * The method <b>readChildren</b> is defined as <b>'abstract'</b> so it must be * coded in the SubClass that inherits from this class, because the codes are * different dependend of the used beans where we will bind in that SubClass.<br> * */ public abstract class FDTreeNode { protected ArrayList<FDTreeNode> children = null; public abstract void readChildren(); public ArrayList<FDTreeNode> getChildren() { return children; } public FDTreeNode getChild(int arg1) { FDTreeNode child = null; if (children == null) { readChildren(); } if (children != null && (arg1 > -1) && (arg1 < children.size())) { child = children.get(arg1); } return child; } public int getChildCount() { if (children == null) { readChildren(); } if (children != null) { return children.size(); } return 0; } public boolean isLeaf() { return (getChildCount() == 0); } }
/** * Starter Class. * * KontoKategory SubClass for the <b>ROOT</b> TreeNode. <br> * Here we coded the <b>abstract readChildren() method</b> of the ParentClass. * * @author Stephan Gerth */ public class RootKontoKategoryNode extends FDTreeNode { // Services / DAO's / Beans private AccountingService accountingService; private Tenant tenant; private KontoKategorie kontoKategorie; private KontoRahmen kontoRahmen; @Override public void readChildren() { List<KontoKategorie> dbList = getAccountingService().getKontoKategoriesByParentNodeIdAndByKontoRahmen(getTenant().getId(), new Long(0), getKontoRahmen()); if (dbList != null) { // System.out.println(dbList.size()); children = new ArrayList<FDTreeNode>(); for (int i = 0; i < dbList.size(); i++) { KontoKategoryNode k = new KontoKategoryNode(); // we must set the Identifier for this child node k.setTenant(getTenant()); k.setKontoRahmen(getKontoRahmen()); k.setParentNodeId(dbList.get(i).getId()); k.setKontoKategorie(dbList.get(i)); children.add(k); } } } // +++++++++++++++++++++++++++++++++++++++++++++++++ // // ++++++++++++++++ Setter/Getter ++++++++++++++++++ // // +++++++++++++++++++++++++++++++++++++++++++++++++ // public void setKontoKategorie(KontoKategorie kontoKategorie) { this.kontoKategorie = kontoKategorie; } public KontoKategorie getKontoKategorie() { return kontoKategorie; } public void setAccountingService(AccountingService accountingService) { this.accountingService = accountingService; } public AccountingService getAccountingService() { if (accountingService == null) { accountingService = (AccountingService) SpringUtil.getBean("accountingService"); } return accountingService; } public void setKontoRahmen(KontoRahmen kontoRahmen) { this.kontoRahmen = kontoRahmen; } public KontoRahmen getKontoRahmen() { return kontoRahmen; } public void setTenant(Tenant tenant) { this.tenant = tenant; } public Tenant getTenant() { return tenant; } }
/** * KontoKategory SubClass for the TreeNodes. <br> * Here we coded the <b>abstract readChildren() method</b> of the ParentClass. * * @author Stephan Gerth */ public class KontoKategoryNode extends FDTreeNode { // Services / DAO's / Beans private KontoKategorie kontoKategorie; private AccountingService accountingService; private long parentNodeId; private Tenant tenant; private KontoRahmen kontoRahmen; @Override public void readChildren() { // get the list of nodes from db List<KontoKategorie> dbList = getAccountingService().getKontoKategoriesByParentNodeIdAndByKontoRahmen(getTenant().getId(), getParentNodeId(), getKontoRahmen()); if (dbList != null) { // System.out.println(dbList.size()); children = new ArrayList<FDTreeNode>(); for (int i = 0; i < dbList.size(); i++) { KontoKategoryNode k = new KontoKategoryNode(); // we must set the Identifier for this child node k.setParentNodeId(dbList.get(i).getId()); k.setKontoKategorie(dbList.get(i)); k.setTenant(getTenant()); k.setKontoRahmen(getKontoRahmen()); children.add(k); } } } // +++++++++++++++++++++++++++++++++++++++++++++++++ // // ++++++++++++++++ Setter/Getter ++++++++++++++++++ // // +++++++++++++++++++++++++++++++++++++++++++++++++ // public void setKontoKategorie(KontoKategorie kontoKategorie) { this.kontoKategorie = kontoKategorie; } public KontoKategorie getKontoKategorie() { return kontoKategorie; } public void setAccountingService(AccountingService accountingService) { this.accountingService = accountingService; } public AccountingService getAccountingService() { if (accountingService == null) { accountingService = (AccountingService) SpringUtil.getBean("accountingService"); } return accountingService; } public void setParentNodeId(long parentNodeId) { this.parentNodeId = parentNodeId; } public long getParentNodeId() { return parentNodeId; } public void setTenant(Tenant tenant) { this.tenant = tenant; } public Tenant getTenant() { return tenant; } public void setKontoRahmen(KontoRahmen kontoRahmen) { this.kontoRahmen = kontoRahmen; } public KontoRahmen getKontoRahmen() { return kontoRahmen; } }
best
Stephan
Thanks Stephan,
Sorry to say but still I am confused. Nothing any simple solution to bind an Array to treemodel? or when i click to tree item it display his nodes?
A tree is one of the most complex things to handle :-(
You said you would get the logic from database...
Asked: 2011-01-21 01:13:42 +0800
Seen: 601 times
Last updated: Feb 05 '11