PDA

View Full Version : Building a Tree using XML



sachinsurvase
9 Dec 2008, 4:51 AM
Hi,

How to create a Tree using XML file data. I have data in a String.
So I want to create a Tree nodes based on the XML elements.
I have never used Ext- GWT tree component so some detailed explanation will help me a lot.
So please can anybody guide me how should I do it?

I have done it in GWT but I want to use Ext-GWT.


Sachin.

jmhwhite2001
9 Dec 2008, 6:58 AM
I'm working on this as well and I'm sure other folks are... :(

If I get it working, I'll post code.

karacutey
9 Dec 2008, 11:40 AM
tree builder class - creates the tree from xquery using RESTful request to db server which returns back XML. this code is in its first stage of dev, so its a lil rough and not as compact or efficent as i like, but it works.

tree builder class (for model):

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.bluestone.client.layout.trees;

import com.allen_sauer.gwt.log.client.Log;
import com.bluestone.client.ComponentRegistry;
import com.bluestone.client.Util;
import com.bluestone.client.layout.contextmenu.CompanyTreeContextMenu;
import com.extjs.gxt.ui.client.data.BaseTreeModel;
import com.google.gwt.xml.client.Element;
import com.google.gwt.xml.client.Node;
import com.google.gwt.xml.client.NodeList;
import com.extjs.gxt.ui.client.binder.TreeBinder;
import com.extjs.gxt.ui.client.data.DefaultModelComparer;
import com.extjs.gxt.ui.client.data.Model;
import com.extjs.gxt.ui.client.store.TreeStore;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.Response;

/*
*
* @author john
*/
public class BuildTree {

public static void BuildTree() {

String xquery = "<query xmlns=\"http://exist.sourceforge.net/NS/exist\"\n" +
" start=\"1\"\n" +
" max=\"20\">\n" +
" <text>\n" +
" import module namespace bst = \"xmldb:exist:///db/bstlib/confgui.xqm\";" +
" bst:listAllCompanies(\"bridges/root.bridge.xml\")" +
" </text>\n" +
"</query>";

RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, Util.DB_URL);

try {
Request request = builder.sendRequest(xquery, new RequestCallback() {

public void onError(Request request, Throwable exception) {
}

public void onResponseReceived(Request request, Response response) {
NodeList companies = Util.getNodeList(response.getText(), "company");

if (companies != null) {
NavTree navTree = new NavTree();

TreeStore<Model> store = new TreeStore<Model>();

store.setModelComparer(new DefaultModelComparer<Model>());
store.setMonitorChanges(true);

TreeBinder<Model> binder = new TreeBinder<Model>(navTree, store);

binder.setDisplayProperty("name");
binder.init();

for (int i = 0; i < companies.getLength(); i++) {
if (companies.item(i).toString() != null) {
Node companyNode = companies.item(i);
Element company = (Element) companyNode;

String companyID = company.getElementsByTagName("companyid").item(0).getChildNodes().item(0).getNodeValue();
String companyName = company.getElementsByTagName("name").item(0).getChildNodes().item(0).getNodeValue();
String companySeats = company.getElementsByTagName("seats").item(0).getChildNodes().item(0).getNodeValue();

if (companyName != null) {
BaseTreeModel companyFolder = new BaseTreeModel();
companyFolder.set("companyid", companyID);
companyFolder.set("companyname", companyName);
companyFolder.set("companyseats", companySeats);
companyFolder.set("name", companyName);
companyFolder.set("id", "BST-CB-Folder-Comp-" + companyID);
companyFolder.set("type", "company");

Util.addCompany(companyName, companyID, companySeats);

String[] subFolders = {"Moderators", "Users", "Conferences"};
store.add(companyFolder, false);

for (int j = 0; j < subFolders.length; j++) {
BaseTreeModel subFolder = new BaseTreeModel();
subFolder.set("companyid", companyID);
subFolder.set("companyname", companyName);
subFolder.set("name", subFolders[j]);
subFolder.set("id", "BST-CB-SubFolder-Comp-" + companyID + "-" + subFolders[j]);
subFolder.set("type", subFolders[j].toLowerCase());
store.add(companyFolder, subFolder, false);

if (subFolders[j].equalsIgnoreCase("conferences")) {
String[] subSubFolders = {"Scheduled", "Active", "History"};
for (int k = 0; k < subSubFolders.length; k++) {
BaseTreeModel subSubFolder = new BaseTreeModel();
subSubFolder.set("companyid", companyID);
subSubFolder.set("companyname", companyName);
subSubFolder.set("name", subSubFolders[k]);
subSubFolder.set("id", "BST-CB-SubFolder-Comp-" + companyID + "-" + subSubFolders[k]);
subSubFolder.set("type", subSubFolders[k].toLowerCase());
store.add(subFolder, subSubFolder, false);
}
}
}
}
}
}

CompanyTreeContextMenu contextMenu = new CompanyTreeContextMenu(navTree);

navTree.setContextMenu(contextMenu);

ComponentRegistry.NavigationPanel.add(navTree);
}
}
});
} catch (RequestException e) {
Log.info("Failed to send the request:" + e.getMessage());
}
}
}
nav tree (for the view)

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.bluestone.client.layout.trees;

import com.bluestone.client.ComponentRegistry;
import com.extjs.gxt.ui.client.data.BaseTreeModel;
import com.extjs.gxt.ui.client.widget.tree.Tree;
import com.extjs.gxt.ui.client.widget.tree.TreeItem;
import com.extjs.gxt.ui.client.widget.tree.TreeSelectionModel;

/**
*
* @author john
*/

public class NavTree extends Tree {


public NavTree() {
getStyle().setLeafIconStyle("tree-folder");

setSelectionModel(new TreeSelectionModel() {

@Override
protected void onSelectChange(TreeItem item, boolean select) {
if (select) {
BaseTreeModel model = (BaseTreeModel) item.getModel();

String type = model.get("type");
String id = model.get("companyid");
String companyName = model.get("companyname");

// if (type.equals("company")) {
// Util.getCenterTabPanel().createNewCompanyTab(id, companyName);
// }

if (type.equals("moderators")) {
ComponentRegistry.CenterTabPanel.createViewCompanyModsTab(id, companyName);
}

if (type.equals("users")) {
ComponentRegistry.CenterTabPanel.createViewCompanyUsersTab(id, companyName);
}

if (type.equals("scheduled")) {
ComponentRegistry.CenterTabPanel.createViewCompanyConfsSchedTab(id, companyName);
}

if (type.equals("active")) {
ComponentRegistry.CenterTabPanel.createViewCompanyConfsActTab(id, companyName);
}

if (type.equals("history")) {
ComponentRegistry.CenterTabPanel.createViewCompanyConfsHistTab(id, companyName);
}
}
}
});
}
}

nav panel which instiants the tree that builds

package com.bluestone.client.layout;

import com.bluestone.client.layout.trees.BuildTree;
import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;

/**
*
* @author Kara
*/

public class NavigationPanel extends ContentPanel{

public NavigationPanel() {
setId("navPanel");
setHeading("Bridge Explorer");

BuildTree.BuildTree();
}

public BorderLayoutData getBorderLayoutData(){
BorderLayoutData borderLayoutData = new BorderLayoutData(LayoutRegion.WEST, 200);
borderLayoutData.setSplit(true);
borderLayoutData.setCollapsible(true);
borderLayoutData.setMargins(new Margins(5));

return borderLayoutData;

}
}

xml that is returned from server

<exist:result xmlns:exist="http://exist.sourceforge.net/NS/exist" exist:hits="3" exist:start="1" exist:count="3">
<company>
<companyid>aaa</companyid>
<name>bluestone</name>
<seats>20</seats>
</company>
<company>
<companyid>aab</companyid>
<name>rpi</name>
<seats>30</seats>
</company>
<company>
<companyid>aac</companyid>
<name>albanymolecular</name>
<seats>20</seats>
</company>
</exist:result>

karacutey
9 Dec 2008, 11:41 AM
oo0 that has a context menu in it too, maybe someone could strip this code down and into an example that can be posted up.

jmhwhite2001
9 Dec 2008, 11:51 AM
My code is beginning to look a lot like what you just put up. Here's the deal. GXT doesn't have support for XML trees (if it does, it's not easy) while GWT-Ext does. It's very easy to create trees from xml!

Now, I'm at a very large company and I'm evaluating both of these packages. I'm totally shocked that somebody from the GXT team hasn't responded or provided code since there has been a lot of questions about XML trees.

In my opinion, it's becoming too much of a hassle especially considering that my company might purchase licenses of this framework and I, not other folks, haven't received hardly any help on this topic. I'm just baffled.

With that being said, I will continue to look at this issue because there is no way I will hard code the tree values.

karacutey
9 Dec 2008, 12:13 PM
there is no comparison between ext gwt and gwt ext

GXT is better becuase it is fully java, where as gwt ext is just java methods calling javascript methods, so you can do any junit testing or low level coding and logic, it also runs alot slower becuase of this.

as far as someone not getting back to you the gxt dev team is extremely small, so you have to keep that in mind,

the reaso ni said my code is rough is that it hasn't been generisized, to meet the criteria your talkin gabout, once this is done you can make a plugin with it, and use it as your own xml tree builder and reused it again and again.

gxt is still pretty young in its dev, and there aren't really a whole lot of people that really understand how it works yet. most of the examples are scattered though this forum.

karacutey
9 Dec 2008, 12:16 PM
as far as hard coding goes, we just haven't gotten to building methods to iterate though the xml, its just faster for us to do it hardcoded right now, as we are in crunch time for this project right now.

as like your company i work for large companies too, this tree is used to display anywhere from 20 to 100 companies, with many sub items.

have a look at the async tree in the examples, that dynamically builds trees, but like you said there isn't really too much support for xml trees or xml really for that matter. kinda disappointing, but gxt has so much other things to offer that make it better then the rest so really what your complaining about is very trivial in the grand scheme of things.

jmhwhite2001
9 Dec 2008, 7:04 PM
Ok, the difference in what I've done and what you did was create a new tree inside the onResponseReceived method. When I put it outside, the xml is always null b/c it hasn't been read in yet.

So, I mimicked your code, but still there's one class that you developed internal that's missing and that's the ComponentRegistry class. I'd assume this class is responsible for keeping track of all gui components added to the system?

Since I don't have that, of course, I'm running into the issue of trying to add the tree to the panel. Even if I use static methods, I run into the problem with non-static to static calls.

Can you provide info about this class?

Thanks for your help!

sachinsurvase
10 Dec 2008, 2:39 AM
Thank you very much karacutey

You helped me a lot.

karacutey
10 Dec 2008, 11:22 AM
i forgot where i saw some code that gave me the idea for the component registry. though using gxt, and how it handles its listeners, you are forced use static members and methods. An elegant way i found is to create a static ComponentRegistry and static Util class within the root client package of your app

you can make these classes interfaces if needed and implement them within any components class. You then are able to access any component directly via ComponentRegistry.MyComponent.myMemberOrMethod()

i have found that this has significant speed adavntages over using the myComponent.getItemByItem as this i assume searches the componets dom heriarchy for the searched component id. Iterating though the list of nodes within its children. Whera as using a static component registry you are merely pointing the the component's locating in your applications memory.

what you mentioned about how the tree building is built into the reader, that is the part that isn't refined, its not highly reusable for whatever component.

COmponentRegistry:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.bluestone.client;

import com.bluestone.client.layout.CenterPanel;
import com.bluestone.client.layout.CenterPropertyPanel;
import com.bluestone.client.layout.CenterTabPanel;
import com.bluestone.client.layout.NavigationPanel;
import com.bluestone.client.layout.ToolBarPanel;

/**
*
* This class is uses to store static refrences to static components on the app
* @author Kara
*/
final public class ComponentRegistry {

public static CenterTabPanel CenterTabPanel = new CenterTabPanel();
public static CenterPropertyPanel CenterPropertyPanel = new CenterPropertyPanel();
public static NavigationPanel NavigationPanel = new NavigationPanel();
public static ToolBarPanel ToolBarPanel = new ToolBarPanel();
public static CenterPanel CenterPanel = new CenterPanel();
}


Util class

package com.bluestone.client;

import com.allen_sauer.gwt.log.client.Log;
import com.bluestone.client.model.UsersListObject;
import com.extjs.gxt.ui.client.widget.ListView;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.NodeList;
import com.google.gwt.xml.client.XMLParser;
import com.bluestone.client.model.CompaniesObject;
import com.bluestone.client.model.ConfDurationObject;
import com.bluestone.client.model.ConfStartTimeObject;
import com.extjs.gxt.ui.client.store.ListStore;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.Response;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.xml.client.Element;
import com.google.gwt.xml.client.Node;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* This class is used to store static global application methods and objects
* @author Kara
*/
public final class Util {

/*
* Global static objects
*/

public final static String DB_URL = "../../exist/rest/db/";
public static ListStore<CompaniesObject> companyList = new ListStore<CompaniesObject>();

private static String responseString;

/*
* Getters and Setters for Global static objects
*/

public static ListStore<CompaniesObject> getCompanyList() {
return Util.companyList;
}

public static void addCompany(String companyName, String companyID, String companySeats) {
Util.companyList.add(new CompaniesObject(companyName, companyID, companySeats));
}

public static String getResponse() {
return Util.responseString;
}

public static void getCompanyUsers(final ListView<UsersListObject> list1, String companyId) {
String xquery = "<query xmlns=\"http://exist.sourceforge.net/NS/exist\"\n" +
" start=\"1\"\n" +
" max=\"20\">\n" +
" <text>\n" +
" import module namespace bst = \"xmldb:exist:///db/bstlib/confgui.xqm\";" +
" bst:listAllUsers(\"bridges/" + companyId + ".bridge.xml\")" +
" </text>\n" +
"</query>";

RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, Util.DB_URL);

try {
Request request = builder.sendRequest(xquery, new RequestCallback() {

public void onError(Request request, Throwable exception) {
}

public void onResponseReceived(Request request, Response response) {
NodeList users = Util.getNodeList(response.getText(), "user");

if (users != null) {
ListStore<UsersListObject> store = new ListStore<UsersListObject>();

store = list1.getStore();

for (int i = 0; i < users.getLength(); i++) {
if (users.item(i).toString() != null) {
Node userNode = users.item(i);
Element company = (Element) userNode;

String nameFirst = company.getElementsByTagName("first").item(0).getChildNodes().item(0).getNodeValue();
String nameLast = company.getElementsByTagName("last").item(0).getChildNodes().item(0).getNodeValue();
String resId = company.getElementsByTagName("resid").item(0).getChildNodes().item(0).getNodeValue();

if (nameFirst != null) {
store.add(new UsersListObject(nameFirst, nameLast, resId));
}
}
}
}
}
});
} catch (RequestException e) {
Log.info("Failed to send the request:" + e.getMessage());
}
}

public static void getCompanyMods(final ListView<UsersListObject> list1, String companyId) {
String xquery = "<query xmlns=\"http://exist.sourceforge.net/NS/exist\"\n" +
" start=\"1\"\n" +
" max=\"20\">\n" +
" <text>\n" +
" import module namespace bst = \"xmldb:exist:///db/bstlib/confgui.xqm\";" +
" bst:listAllModerators(\"bridges/" + companyId + ".bridge.xml\")" +
" </text>\n" +
"</query>";

RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, Util.DB_URL);

try {
Request request = builder.sendRequest(xquery, new RequestCallback() {

public void onError(Request request, Throwable exception) {
}

public void onResponseReceived(Request request, Response response) {
NodeList users = Util.getNodeList(response.getText(), "moderator");

if (users != null) {
ListStore<UsersListObject> store = new ListStore<UsersListObject>();

store = list1.getStore();

for (int i = 0; i < users.getLength(); i++) {
if (users.item(i).toString() != null) {
Node userNode = users.item(i);
Element company = (Element) userNode;

String nameFirst = company.getElementsByTagName("first").item(0).getChildNodes().item(0).getNodeValue();
String nameLast = company.getElementsByTagName("last").item(0).getChildNodes().item(0).getNodeValue();
String resId = company.getElementsByTagName("resid").item(0).getChildNodes().item(0).getNodeValue();

if (nameFirst != null) {
store.add(new UsersListObject(nameFirst, nameLast, resId));
}
}
}
}
}
});
} catch (RequestException e) {
Log.info("Failed to send the request:" + e.getMessage());
}
}

public static void setResponse(String response) {
Util.responseString = response;
}

/*
* Global Utility methods which are static to the application
*/
public static String encodeStringURL(String s) {
StringBuffer buf = new StringBuffer();
int len = (s == null ? -1 : s.length());

for (int i = 0; i < len; i++) {
char c = s.charAt(i);
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9') {
buf.append(c);
} else {
buf.append("&#" + (int) c + ";");
}
}
return buf.toString();
}

public static NodeList getNodeList(String xml, String tagName) {
Document messageDom = XMLParser.parse(xml);

if (messageDom != null) {
return (NodeList) messageDom.getElementsByTagName(tagName);
} else {
return null;
}
}

//TODO move this method to the Model Object class
public static List<ConfDurationObject> getConfDurationList() {
List<ConfDurationObject> list = new ArrayList<ConfDurationObject>();

int increment = 5; //in minutes
int totalLength = 120; //in minutes

for (int i = 0; i < totalLength; i = i + increment) {
list.add(new ConfDurationObject(i + increment));
}

return list;
}

//TODO move this method to the Model Object class
public static List<ConfStartTimeObject> getConfStartTimeList() {
List<ConfStartTimeObject> list = new ArrayList<ConfStartTimeObject>();

int increment = 5;
int th = 24;
int tm = 60;

for (int i = 0; i < th; i++) {
for (int ii = 0; ii < tm; ii = ii + increment) {
list.add(new ConfStartTimeObject(i + 1, ii));
}
}

return list;
}

public static String formatUnixTimeToDateString (String time) {
Long timestamp = Long.parseLong(time) * 1000;

return DateTimeFormat.getFormat("MM/dd/yy").format(new Date(timestamp));
}

public static String formatUnixTimeToTimeString (String time) {
Long timestamp = Long.parseLong(time) * 1000;

return DateTimeFormat.getFormat("h:mm a").format(new Date(timestamp));
}

public static String getCurrentUnixTime () {
long date = new Date().getTime();
return String.valueOf(date / 1000);
}
}



getCompanyMods method

this method builds an xquery, posts its, reads the xml, and sticks the list store into a some member.

hope that helps yea

cheers
kara

jmhwhite2001
15 Dec 2008, 9:27 AM
Ok, I finally got something going after some vacation. I noticed a big difference. In your code, you use the onResponseReceived on the request object, while my code used newLoadResult on the HTTPProxy. I now have first level folders being created. I now gotta work through the code to get subfolders. Thanks for all your help. It's been long.

=D>

karacutey
15 Dec 2008, 10:07 AM
no prob.. thats what community forums are for ^_^

cheers, and good luck

kara

jmhwhite2001
16 Dec 2008, 8:16 AM
Ok, I just updated to GXT 1.2 along with GWT 1.5. Now, I've used some of the code you specified and currently, I can definitely see the results of the "outter" folders which correlates to the outter XML elements in the xml document.

Here's the problem. I can see there is a folder, but I can't open it. I'm wondering if anyone has successfully executed the code and got it working. Here's my code snippet:




public void onResponseReceived(Request request, Response response) {
String resp = response.getText();
if (response.getText() != null) {
Document document = XMLParser.parse(response.getText());
NodeList navigationList = document.getDocumentElement().getChildNodes();

tree = new Tree();
TreeStore<Model> store = new TreeStore<Model>();

TreeBinder<Model> binder = new TreeBinder<Model>(tree, store);
binder.setDisplayProperty("title");
binder.init();

for (int i = 0; i < navigationList.getLength(); i++) {
if (navigationList.item(i).toString() != null) {
Node folderNode = navigationList.item(i);

if (folderNode.getNodeType() != Node.ELEMENT_NODE) {
continue;
}

Element folder = (Element) folderNode;

String id = folder.getAttribute("id");
String title = folder.getAttribute("title");

boolean expanded = false;

if (folder.getAttribute("expanded") != null) {
expanded = Boolean.parseBoolean(folder.getAttribute("expanded"));
}

String toolTip = folder.getAttribute("qtip");

int rank = -1;

if (folder.getAttribute("rank") != null) {
rank = Integer.parseInt(folder.getAttribute("rank"));
}

String url = folder.getAttribute("url");
String icon = folder.getAttribute("icon");

if (title != null) {
BaseTreeModel navFolder = new BaseTreeModel();
navFolder.set("title", title);
navFolder.set("id", id);
navFolder.set("tooltip", toolTip);
navFolder.set("url", url);
navFolder.set("icon", icon);
navFolder.set("rank", rank);
navFolder.set("expanded", expanded);

store.add(navFolder, false);

if (title.equalsIgnoreCase("Maintenance Control")) {
BaseTreeModel node1 = new BaseTreeModel();
node1.set("title", "Aircraft Status Board");
node1.set("id", "jamieID1");
node1.set("tooltip", "This is a test");

store.add(navFolder, node1, false);

BaseTreeModel node2 = new BaseTreeModel();
node2.set("title", "Aircraft Locator");
node2.set("id", "jamieID2");
node2.set("tooltip", "This is a test");

store.add(navFolder, node2, false);
}

/*if (folder.hasChildNodes()) {
recursivelyAddNodes(folder, store, navFolder);
}*/
}
}
}

add(tree);
tree.expandAll();
}
}
});



As you can see, I'm merely adding the "outter" XML elements to the tree, which works correctly, but any child elements underneath causes some issues.

The line:



if (title.equalsIgnoreCase("Maintenance Control")) {


merely will add two child elements underneath the "Maintenance Control" folder, which is the first folder. Here's a picture of what I get:

http://www.freeimagehosting.net/image.php?dd46ab7abb.jpg

I can click the Maintenance Planner folder, but it doesn't open with anything. Has anybody been successfully able to use similar code snippet to merely add a child to a node with the store?

Thanks!

jmhwhite2001
16 Dec 2008, 8:50 AM
I found this thread:

http://extjs.com/forum/showthread.php?t=41911&highlight=TreeStore

I put the exact same code in my code and commented the other code. At this point, I still can't expand the folder.

karacutey
17 Dec 2008, 4:36 PM
i dont think you are parsing the xml correctly, if you dont parse it correctly errors will not be thrown when you try to expand it, your treestore thinks has 0 nodes. i would try to build a tree first using static xml you put into it. then add log.info though your entire methods and hae it constantly output whats its parsing to your console.

if you can create things via your static xml you know its not your request. you can also use firebug to load the request response, to costruct your static xml to test with.

your binder looks correct. i do not see you using a model comparer though, that is used to map your model to the treestore.

also try setting the store.setMonitorCHanges to true, that turns on your listeners for the tree. I this this is used in a way to control updating content and access node items.

kara

jmhwhite2001
17 Dec 2008, 4:59 PM
My XML is being parsed correctly. I'm debugging and outputting System.out statements to show that it is indeed parsing correctly. My problem is that it's only getting the outter folders. I'm having issues adding a child to a parent, which I see has been a bug in prior releases. I'm having those same issues now.

Seems like my problem is adding the child to the parent in the TreeStore. (store.add(<parent>, <child>, boolean))

I've used simple examples, without parsing XML and have the same behavior. That's why I asked if anybody has actually used your code with adding elements to the store along with adding children to the parent.

nickibckr
28 Jan 2009, 12:50 PM
Hello -- thanks by the way for the great ideas.
I'm pretty new to GXT, and I'm really struggling with how things communicate with each other. I like the component registry idea, but I'm having problems getting the tree to then display in a layout container. What dots are not connecting for me here (for me)?
(I have an XML tree that parses correctly when extending a content panel, but as I try to make my code more modular, the functionality goes away)

nickibckr
28 Jan 2009, 1:33 PM
Never mind, I think I figured it out. I just had to break things apart differently to get it...