Spark Tree

Unfortunately Flex 4 does not have Spark Tree and MX Tree has 99 bugs at this moment.

In our project we were in need of Spark-based Tree for some time so inspired by Alex Harui I wrote it:

Download SparkTree4.0.swc for Flex SDK 4.0. and 4.1
Download SparkTree4.5.swc for Flex SDK 4.5 and higher
Download source code

Creating tree item renderers

Tree item renderers should extend TreeItemRenderer. Here is the default item renderer.

License: MIT.

140 responses to “Spark Tree”

  1. Very cool, nicely done.

  2. [...] just updated the Spark Tree custom component. Here are the improvements and new [...]

  3. [...] have heavily used the Spark Tree in our project and have fixed plenty of bugs. Feel free to get the updated [...]

  4. Very nice indeed! Can you tell me if it’s possible (and how) to make your Tree component open specific branches (i.e. folders) on load? When I refresh the dataProvider, everything collapses. Many thanks in advance!

  5. The whole collection is recreated, but it’s the same items in the dataProvider. Thanks for the quick reply!

  6. Can you recommend an approach to create a duplicate tree with the same open branches? Many thanks in advance.

  7. Is there a way to open all nodes when first shown/loaded?

    Many Thanks
    Daniel

  8. Is there any equivalency to the openItems property of the mx:Tree component? I’m looking for the best approach with your Tree component to track which branch nodes the user opens, so that on refresh/relaunch of app, the same nodes can be opened automatically. Many thanks in advance.

  9. I’m having difficulty storing in a local SharedObject the right data to know which branch nodes to open–and I know why: I’m using the Tree’s selectedIndex, which isn’t always going to point to a branch–depending on how other branches are opened or closed. So, using ITEM_OPEN and ITEM_CLOSE, what’s the best way to store and then later re-use for re-initialization branch info? My problem is that I don’t understand the best way to calculate a “branch index” so that regardless of which branches are opened/closed, I can reopen branches without using selectedIndex.

  10. Figured it out… All of my branches had unique ids, so I stored the unique ids in my shared object, and on updateComplete, I compare the stored unique id to the uid’s of the new branches and then expand on that new item. Seems to work great!

  11. Good work, Thank you !
    What do you think about moving your files to a package (com.kachurovskiy.sparktree ?), and releasing your SparkTree as a swc ?

  12. you have any advice on how i could make this tree animate when the branches open / close?

  13. I’ve implemented a custom item renderer with a multi-line label (vertical layout). I get some odd affects such as the two bottom items in the visiable scroll are tripple the height (but resize when scrolling starts for the first time) and then scrolling calculations seem to go a little whack – the scrollbar jumps up and down when in use. Scroll wheel has no ill effects.

    I did extend the Tree class and manually gave it a layout in the constructor and that seems to fix the two large item height issues but the scrolling still jumps a bit.

    Any idea why this might happen. I also have used multi-line items in List components and the “jump” doesn’t occur during scrolling.

    Thanks!

    1. Hmm…I changed the default item renderer of yours to use mulit-line and I don’t seem to get that same issue. I believe it might be my item renderer. I do have my elements wrapped in a BorderContainer which might be causing the issue.

      I think this actually might be a Flex List vs ItemRender bug.

      Thanks anyway for a great component!

  14. Thank your share the great component!

  15. Looks good! Does this component support drag reordering?

  16. Hi do you know of any possible way i could show the names of the branches in an mx tree? for now, it only displays the icons but the branch names are not given :(

  17. Awesome piece of code !

  18. Posted a sample of this spark tree with a three state checkbox in the renderer
    http://www.premsweb.com/spark-tree-with-a-three-state-checkbox

  19. Hi, wonderful work, quick question.
    Whats the best way to specify the default icons for each node?

    I notice you have the line in the Tree:

    var mxTreeDeclaration:CSSStyleDeclaration = FlexGlobals.topLevelApplication.styleManager.getStyleDeclaration("mx.controls.Tree");
    ... MX Tree may not be used in the application

    What’s the best way to set the icons/styles for the tree? Is there a ‘switch’ I can use to use the icons specified with your embedded icons embedding, or should I set each one in my own code?

    Thanks

  20. Hi,
    Is there any way to scroll to a selected children node?
    Thx

  21. Hi,
    Is there anyway to implement showRoot?
    Cheers
    Trist

  22. I have been trying to make your tree work on a “lazy load mode” every time you click on a node it makes a service call and returns the childrens, the problems is that when you get your services results back and you assign it to the selected node it does not update the tree…, I just cant figure it out…
    any help would be apreciated. :)

  23. Thanks, that helped a lot ;) I now am trying to display a current bread crub to the current node selected but when I check the parents on the ItemRenderer is Null… any feed back on this ?

  24. Please see my blog post: http://www.smithfox.com/?e=85

    I attach the test.mxml there.

    After my research, I found the issue is caused by the Flex SDK4.5.1 ListBase’s Caret.

    So I try to give my solution: http://www.smithfox.com/?e=155

    My SDK is flex_sdk_4.5.1.21328

  25. “Disable the Caret” is a temp solution, there is still more issues.
    Now I give out a full solution, and it has been tested in myself project.

    http://www.smithfox.com/?e=155

    Note: it should be used under flex_sdk_4.5.1.xx

  26. This may be a silly question, but is this designed to work with multiple columns in a Spark Data Grid? Or just the Tree column?

    Thanks for the release.

  27. I’m trying to use the sparkTree but getting a compile error in the Tree class where you override:
    override protected function adjustSelectionAndCaretUponNavigation(event:KeyboardEvent):void
    Specifically, the compiler can’t find:
    mapKeycodeForLayoutDirection(event)

    I’ve looked through UIComponent (is that where the original function lies?), but can’t find it.

    Is this possibly a version issue? I’m using Flex 4 SDK (not yet on 4.5).

    I notice also on one of your issues, that someone has made some changes to that override, back in March, but that is not part of my problem.

    Any feedback is appreciated.

    thanks, Mike

  28. Thanks for the quick reply Maxim.
    Busted, I have 4.0.0 build 14159 so I may just have a release with an old UIComponent. They do warn us that mx_internal tends to be stuff that changes frequently.
    I’ve been thinking I should upgrade to 4.5 so maybe today’s a good day to do it.
    btw, great work on the tree. I’m trying to integrate it into my Google Docs flex explorer.

  29. Looks good Maxim, apart from TreeDataPpovider.as I can’t see any licence file or specific mention of type of licence. Can you please elaborate and perhaps include a license file

    cheers Denis

  30. I find the hit area [+] requires the user to need to be too precise with the mouse. I will poke about the code to see if it can be improved, but if you have suggestion to make this bigger then jump in. I think the image size is probably fine, but it would be nice to have an extra few pixels around it that e.g. from the image edge to the top, left & bottom boundary of the renderer

  31. Hi,

    I found a bug, when you expand all nodes of a tree populated from XML, and try to close from the root node, there’s an exception.
    I have the same problem with your demo

  32. Hi there, first of all – great work, really like the Spark Tree

    Have you tried using it in an mx:HDividedBox? In our application, we have the Spark Tree as a Table of Contents on the left, and on the right the content itself. If you drag the slider left and right the Spark Tree is not getting redrawn.

    Is this a known issue? If not, I’d like to report it
    Thanks
    Neal

  33. Hi there,
    Unfortunately, I think we found another bug with Spark Tree. The error occurs when you ALT+TAB out of the AIR Application to another window (in Windows), and ALT+TAB back in. We have the data provider set to an XMLListCollection

    Here is the error generated:
    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at spark.components::Scroller/focusInHandler()[E:\dev\4.5.1\frameworks\projects\spark\src\spark\components\Scroller.as:1273]
    at flash.display::Stage/set focus()
    at mx.core::UIComponent/setFocus()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\core\UIComponent.as:9895]
    at mx.managers::FocusManager/activateWindowHandler()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\managers\FocusManager.as:729]
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.core::UIComponent/dispatchEvent()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\core\UIComponent.as:13128]
    at spark.components::WindowedApplication/nativeWindow_activateHandler()[E:\dev\4.5.1\frameworks\projects\airspark\src\spark\components\WindowedApplication.as:2739

  34. Apologies Maxim – the second one is not a bug with the tree.

    I’m still fairly sure the first one is though

  35. Hi, Maxim!

    Is there any chance to build tree with your component, having this properties:
    - one-column tree (grows from up to down, not from left to right)
    - tree have vertical scroll if tree have too much “rows”
    - tree have horizontal scroll if there too long tree item?

    Thank you for Your answer!

  36. Maxim, thank you for quick answer!

    Please, tell me – where i can see sample source code?

    1. Sorry for my question :) For others – to view sources, press right button at example and choose “View source”

  37. Hi there, I tried to use your sample code to build my own test project http://ifolder.ru/26041882 .

    When I run this application, i fixed this bugs (or not?):
    - when I open “tc2 – Test2″ node, horizontal scrollbar not added. Only when I clicked twice on “plus” sign, scrollbar was added;
    - when I close “tc2 – Test2″ node, horizontal scrollbar wasn’t removed (all Tree contents are in the box – horiz.scrollbar not needed).

    Please, tell me – what I need to fix to remove such errors?

    Thank you for Your answers!

  38. Hi Maxim,

    Is there an easy way to prevent the closing of a branch when the children property is empty. It seems that the ItemClose event is called when i set the children = new array()

    Thanks, Rene

  39. Thanks for your anwer!

    One more question. After refreshing the dataprovider, the indentation of the third level is equal to that of the second level. Any idea why that is?

    Thanks again, Rene

  40. Hi, could you possibly explain to me how can I use spark-tree with my own dataDescriptor? I already implemented my own data structure representing tree hierarchy and dataDescriptor (extending ITreeDataDescriptor2) which describes it. I already used it successfully with mx:Tree implementation, but this component was extremely buggy. I tried to use my structure with your component, but it complains that dataDescriptor should implement IList interface. Why is that? Is it necessary even when i provided dataDescriptor? Do i need to reimplement my data structure?

  41. When I use the defaultLeafIcon property, I get an error –
    1178: Attempted access of inaccessible property defaultLeafIcon through a reference with static type com.sparkTree:Tree.

    I’m passing this as the value: @Embed(‘views/assets/images/icons/database.png’) (in MXML)

    Any ideas?

  42. Hi

    Thanks for the component, it is awesome!

    I am trying to implement the dragging of items to inside other items, i.e. turning leafs into nodes. So you would be able to drag an item above a leaf, below it, or onto it in which case the leaf would become a node. Any pointers about how I would go about this would be much appreciated.

    Thanks

    Isambard.

  43. Hi,

    I’m trying to implement your sparktree. I’ve got an object that has a list of another object which in turn has a list of other objects. How do I go ahead with this?

    e.g.: User>Courses>Levels. I want to display the Courses and Levels in a tree. The courses are no problem, the levels on the other hand.

    Thx in advance,

    Didier

  44. Hi,

    I can’t see more than one level when I use an itemrenderer based on TreeItemRenderer. Any ideas?

    1. Solved :)

  45. Hi, I’m using your Tree component and it’s working just fine, but I cannot set it to do word-wrapping with variable row height.

    I’ve already tried to set a VerticalLayout to it, with variableRowHeight=”true” and horizontalAlign=”justify”, but it didn’t work.

    How can I do this with your component?

  46. Hi,

    I’m trying to get the SparkTree working with Flex 4.6.
    Could you give me an advice how to do that?

    Many Thanks,
    Stefan

  47. Hello Maxim,

    I want to use your SparkTree component because it looks good and the mx Tree component is acting up all the time. :)

    But i’m having a problem with showing the data. I only see the top levels and no branches in the tree. I thought i was as simple as giving the objects in the ArrayCollection a property “children” but nothing is showing except for the top levels.

    The objects i use are generated objects from Flash Builder and are retrieved from our backend. This is the same for the objects in the children property. This is a ArrayCollection of generated objects.

    Any idea what the problem might be?

    Thanks in advance!

  48. Hi Maxim,
    I am trying to filter the dataprovider of the Tree. Basically I am doing a custom filter function on a multi level tree data provider and then want to refresh the tree while maintaining the open nodes that match the filter.

    Problem Number 1: invalidateDisplayList() does not refresh the tree only reassigning the dataProvider does

    Problem Number 2: reassigning the dataProvider causes all the nodes to go into the original collapse state !

    Any suggestions ?

    Thank you much,
    Prem

  49. I am not filtering the dataprovider , I am filtering the original correction that has been assigned to tree.dataprovider using a method similar to this article since I dont want to filter the parents with the filter criteria http://www.kalengibbons.com/blog/index.php/2009/01/filtering-a-flex-tree-using-an-arraycollection/

    Whenever the search text changes in a text input I recursively filter the children of the collection and then refresh the collection but that does not reflect on the tree.

    Am I missing something ?

  50. Thanks Maxim. I guess I was looking for a quick fix to an urgent problem. Could you please tell me what you found wrong in the code?

    I followed your advice and got it working. Should have looked at the code a little better, I have a custom implementation of your tree ( like the sample i posted a while back http://www.premsweb.com/spark-tree-with-a-three-state-checkbox ) but a little more complex and wanted to implement this quick .

    Anyway , thank you again for your help and the great spark tree :)

  51. Hi,
    Very nice component!

    There is a bug that can be reproduced in your own demo:

    1. Click “+” to expand the “parent Element 0″
    2. Drag the “child Element 2″, just before “child Element 0″
    3. Bug: “child Element 2″ is kicked out of “parent Element 0″
  52. Maxim,

    Your component saved my project!
    One minor suggestion (so it can be embedded in mobile applications): in file DefaultDisclosureButtom.mxml, there is a component. If you change it to it works also in mobile, otherwise you get a packaging error.
    Thank you for the great work!!!!

  53. Hi Maxim,

    In my previous comment, I meant to say that there is a mx:Image component that may be worth changing to s:Image. Unfortunately, I wrote them as xml tags without formatting them as code, so they don’t show.

  54. To make SparkTree work with remote data (list classes that throw itemPending errors):

    • Change all index based branch references in TreeDataProvider to use getItemAt(), e.g branch[i] becomes branch.getItemAt(i). You should really always use the getItemAt() accessor for IList classes.
    • Your remote list class must implement ICollectionView (required by the getChildren() method of DefaultDataDescriptor). I just extended the built-in AsyncListView to AsyncListCollectionView and didn’t bother to implement the actual functionality. I just throw errors in all the ICollectionView specific methods.
    • Use a custom data descriptor class and override isBranch(), hasChildren(), and getChildren(). Your child property should be an instance of your remote collection class, AsyncListCollectionView in my case.
    • I used James Ward’s PagedList class (http://www.jamesward.com/2010/10/11/data-paging-in-flex-4/). In the getItemAt() function I had to add a null check in addition to the undefined check.
    • Depending on your model implementation, you may want to provide a ‘typicalItem’ that doesn’t have children so that itemPending errors won’t be thrown during default layout.

    Once it’s working, usage is simple:

    <fx:Declarations>
      <collections:PagedList id="pagedData"
        loadItemsFunction="loadItems" length="0"/>
    </fx:Declarations>
    	
    <sparkTree:Tree labelField="label" typicalItem="{typicalNode}">
      <sparkTree:dataProvider>
        <collections:AsyncListCollectionView list="{pagedData}"
          createPendingItemFunction="{createPendingItem}"
          createFailedItemFunction="{createFailedItem}" />	
      </sparkTree:dataProvider>
      <sparkTree:dataDescriptor>
        <support:NodeDescriptor />
      </sparkTree:dataDescriptor>
    </sparkTree:Tree>

    Hopefully that saves somebody a day of their life. I already paid that bounty…

  55. Hi Maxim,
    I’m attempting to set a spark VScrollBar skin against the SparkTree control using CSS, but finding that it’s not being recognised. I was thinking that doing this should be ok given SparkTree is based on the spark List control? I was wondering whether you might have any clues at all please?
    My CSS definition is as follows:

    s|List s|VScrollBar sparkTree|Tree {
        skinClass: ClassReference("com.arenaeast.localskins.VScrollBarSkin");
    }

    Thanks very much! :)

  56. Your components seems to be not compatible with the Mobile App developement.
    I met the following error when I tried to compile a Mobile Phone App :
    VerifyError: Error #1014: Class mx.controls.treeClasses::ITreeDataDescriptor2 could not be found.

    I don’t met this problem with AIR & Web Applications.

    Is this normal ?

  57. Hi Maxim,

    As per your solution below
    1. Copy ITreeDataDescriptor2, DefaultDataDescriptor and related classes to your own package

    I have made my spark tree component for mobile.Thank you very much.

    Thanks,
    Sunil Rana

    1. hi Sunil Rana,
      I Copy ITreeDataDescriptor2, ITreeDataDescriptor, DefaultDataDescriptor, HierarchicalViewCursor, version, HierarchicalCollectionView to src/com/sparktree directory, it can complie ok.
      But when i run it. It has following error info:
      ReferenceError: Error #1065: Variable SampleData_ICON1 is not defined.

      at flash.display::MovieClip/nextFrame()
      at mx.managers::SystemManager/deferredNextFrame()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\SystemManager.as:278]
      at mx.managers::SystemManager/preloader_preloaderDocFrameReadyHandler()[E:\dev\4.y\frameworks\projects\framework\src\mx\managers\SystemManager.as:2627]
      at flash.events::EventDispatcher/dispatchEventFunction()
      at flash.events::EventDispatcher/dispatchEvent()
      at mx.preloaders::Preloader/timerHandler()[E:\dev\4.y\frameworks\projects\framework\src\mx\preloaders\Preloader.as:515]
      at flash.utils::Timer/_timerDispatch()
      at flash.utils::Timer/tick()

      Did you meet it?

      Thanks,
      zhd

      1. hi all,
        I create a new application and copy all source. And run it well.

        Thanks.
        zhd

    2. Hi

      Where can I get related classes like “ITreeDataDescriptor2″ which are not available on mobile? (I’m new in flex development…)
      Could you share sources of tree view for mobile please?

      Thanks in advance.

      John N.

  58. Eric September 2, 2011 at 14:36 | Permalink | Reply

    Hi,

    I found a bug, when you expand all nodes of a tree populated from XML, and try to close from the root node, there’s an exception.
    I have the same problem with your demo

    I have this very same issue, im getting a XML from an HTTPService and i couldnt find a “simple cast” for it, the best i could get was this:
    var arr:ArrayCollection = new ArrayCollection;
    for each (var value:XML in myXML.children())
    arr.addItem(value)
    And folders jump out to another level while exploring em (really weird behavior) =/

  59. 1) TypeError: Error #1034: Ошибка типа Coercion: невозможно преобразовать XMLList@8e348b1 в Class.
    at com.sparkTree::Tree/getOwnItemIcon()[C:\W\Flash\SparkTree\src\com\sparkTree\Tree.as:474]

    2) и еще если в примере нажать “Set XML as dataProvider” развернуть все три уровня и потом свернуть верхний то верхние два просто пропадают из видимости, третий остается неизменным.

  60. great work bud! I think I inadvertently discovered a bug in that setting indentation on the tree never makes it too the itemrenderer and just sits at the default value of 17. So far haven’t been able to track down why this is but workin gon it. Put a break on TreeItemRenderer.as line 255
    ~ JT

  61. Still get the same problem
    Class mx.controls.treeClasses::ITreeDataDescriptor2 could not be found.
    Under FlexBuilder 4.6

    how to solve the problem ?

  62. Hi Maxim,

    If i have chapters with a children property which is an array with documents, how can i delete/remove a document? Removing a document from the children array works, but the tree is not updated visually. Is it a problem that the children property in the chapter is an array? Should it be an arraycollection?

    Thanks, Rene

  63. Spark tree really works awesome.
    Saved a lot of time.
    the current Adobe Mx:Tree sucks.

    Thanks much

  64. Hey guys,
    I currently have a project where I just want to have a visual representation of the structure of some IVisualElements + Containers inside the SparkTree,
    but having the top most Container (inside an ArrayCollection) added as the Dataprovider to the tree and using the normal Container.addElement Method doesn’t work as expected, in some cases adding a graphical object to a container crashes the whole tree with an Index out of Bounds exception
    what can I do, Ive been working on it for days!

  65. Hello Maxim,
    I am using your spark tree code. Can you please tell, how I can use Datadescriptor and Itemrenderer in Spark Tree. I changed my code as ItreeDescriptor2 after that it is showing error on “getParent”, “getNodeDepth” & “getHierarchicalCollectionAdaptor”. So, Please help me to know, will it work in Spark tree?,

    Thanks.

Leave a Reply