File Exchange

image thumbnail

Tree Controls for User Interfaces

version 1.6.0.1 (276 KB) by

Provides the capability to easily create tree controls for an application or user inter

4.90909
13 Ratings

37 Downloads

Updated

View License

Please Note: If you are using R2017a or later, an improved tree is included with Widgets Toolbox. https://www.mathworks.com/matlabcentral/fileexchange/66235-widgets-toolbox
This package provides the capability to create tree controls for a MATLAB® application or user interface using a simple object-oriented interface. This package includes and wraps the Java code necessary to implement a tree, and removes the need to write new Java code to create a tree control, for a set of included features.

A rich set of features and capabilities are included:
- Full Drag and Drop support (within the tree and also between trees)
- Supports callback that tells the tree whether a node is a valid drop target
- Supports keyboard modifiers for drop action (COPY,MOVE,LINK)
- Checkbox Tree support (Both hierarchical/DigIn style and individual node style)
- Node editing support
- Customize each node with it’s own:
- Icon
- Tooltip
- Context menu
- Checkbox visibility & enable
- UserData and Value
- Settable callbacks for your user interface for each event, including mouse events

Comments and Ratings (53)

Hi,
I try the following code:

function test

import uiextras.jTree.*
f = figure;
t = Tree('Parent',f);
Node1 = TreeNode('Name','Node_1','Parent',t.Root);
Node1_1 = TreeNode('Name','Node_1_1','Parent',Node1,'TooltipString','Node1_1');
Node1.expand();
Node1_2 = TreeNode('Name','Node_1_2','Parent',Node1,'TooltipString','Node1_2');

t.SelectionChangeFcn = @(s,e)testcallback(s,e);

end

function testcallback(varargin)
disp('ok')
end

but i get the following error:

No public property 'jTree' for class 'Tree'.

Error in uiextras.jTree.Tree/get.SelectedNodes (line 1163)
srcPaths = tObj.jTree.getSelectionPaths();

Error in uiextras.jTree.Tree/onNodeSelection (line 756)
'Nodes', tObj.SelectedNodes,...

Error in uiextras.jTree.Tree>@(src,e)onNodeSelection(tObj,e)

Do you have any idea why?
Thanks

Robyn Jackey

Robyn Jackey (view profile)

If you are using R2017a or later, please try out my new entry "Widgets Toolbox", and please provide feedback on it. The toolbox incorporates an improved version of the Java Table and Java Tree wrappers along with a number of additional components.

Please see: https://www.mathworks.com/matlabcentral/fileexchange/66235-widgets-toolbox

Robyn Jackey

Robyn Jackey (view profile)

@Marcus, without spending significant time, I don't see any obvious solution here, besides trying what Sebastian mentioned.

Robyn Jackey

Robyn Jackey (view profile)

@Marcus, I know the callback is called when you are dragging a node over another. I am not sure about highlighting a node on hovering. I'll try to check on this but it will be later this month.

dieudonne

Hi.
I try the following code:

import uiextras.jTree.*
figure;
t = CheckboxTree('Parent',gcf);
func = @(x)CheckboxTreeNode('Name',x,'Parent',t.Root)

Then I want to create 3 nodes called 'Node1', 'Node2', 'Node3' with cellfun function. So I try:
cellfun(func, {'Node1', 'Node2', 'Node3'})

but i get the following error:

Undefined function 'CheckboxTreeNode' for input arguments of type
'uiextras.jTree.CheckboxTreeNode'.
Error in @(x)CheckboxTreeNode('Name',x,'Parent',t.Root)

Do you have any idea why?
Thanks

Hi. I'd like to come back to the issue Sebastian Hölz mentioned: highlight a node as the mouse hovers over it (when dragging a node). In Java this is called "show drop target" and seems to be standard behavior. It's very useful in big or complex trees to help the user drop onto the right node.
Oracle has a working demo here: https://docs.oracle.com/javase/tutorial/uiswing/dnd/locsensitivedemo.html
How can we get this to work in this MATLAB wrapper? Setting the tree's DropMode to ON has no effect. I tried to debug with Eclipse but the relevant method "canImport" of the TransferHandler seems to be never called. Any ideas?

Jun Ho Song

Igor Laposa

Robyn Jackey

Robyn Jackey (view profile)

@Robert - I have not come across that issue before, however 900 nodes is a bit larger than I have used before. Does this hold true on multiple computers? I wonder if it may be better to implement a lazy node creation in this case (adding more nodes in NodeExpandedCallback). I have not tested out that use case though.

Hi. Thank you for the good work. I have built an app with that tree control. I create ~ 900 nodes in that tree, which happens fairly fast. After deploying the same app to an executable (via including the .jar file to the deployment, as explained in a comment below), creating the nodes is way, way slower than in the Matlab environment. Do you have any idea what I can do to prevent this?

Sebastian Hölz

Hi, setting the tree's SelectedNodes property in the NodeDraggedCallback does the trick. Thanks for the hint !

Robyn Jackey

Robyn Jackey (view profile)

@Sebastian - I'm not sure if there's a way to color it as it hovers. Probably could be done by customizations in Java code itself. If you wanted to instead select a node you can just change the SelectedNodes property, but I don't think that's what you actually want.

Sebastian Hölz

Hi, is there a simple way to highlight a node as the mouse hovers over it?

I see that the MouseMotionFcn supplies the current node under the mouse pointer, but I just can't find a property to highlight the according node ...

Robyn Jackey

Robyn Jackey (view profile)

Goryn, yes if you want to hide the root that is the best way.

Goryn

Goryn (view profile)

How to create "individual node style"? Only to set visible "off" for Root?

Robyn Jackey

Robyn Jackey (view profile)

Hi Graham,
This depends a lot on how your application is structured.

For example, is the tree representing a composition hierarchy of handle objects? I use that pattern frequently, and I would typically either store temporary references to the data objects in the tree nodes' UserData, or references to the tree nodes in a transient property in the data objects. Performing an update would be a recursive function that walks the hierarchy from the top down.

In other application the tree might just have a fixed number of levels in which you should also be able to track them in your code, either by storing references to the TreeNode objects or placing data in the TreeNode's UserData.

You can also clear the tree completely by just deleting the children of the tree's Root, and recreating them. However, you lose the state of expansion and selection if you clear it and start fresh, so that only makes sense if you're removing the whole hierarchy from the application and loading in a new one.

Hi Robyn,
I've used this implementation a few times now & find it a clear improvement over uitree, and far less painful that hand-crafting my own Java implementation.
Once thing I typically need to do is to refresh the tree - i.e. to clear it down & re-populate it.
Can you please advise the best way to do this?

Robyn Jackey

Robyn Jackey (view profile)

Hi Therry,
I haven't seen that issue before. Do you have an example you can send? You can contact me directly by clicking on my name above, "view profile" and then "contact".
Thanks!

Therry

Therry (view profile)

Hello Robyn,
the tool works very well! One drawback (solved): Moving the mouse over a big figure slows down the reaction time of contextmenus in the tree wrapper (sometimes up to 10 s depending on movements). After including a "drawnow" in the embedded function "onMouseMotion" the reaction time is fast again. Is it possible to include this in your next issue?

Robyn Jackey

Robyn Jackey (view profile)

Hi Adi, please include the .jar file in the deployment

Adi Kanetti

Great Job!!
It works perfectly fine when I run my GUI .m file, but after I compile my GUI and create a standalone app, the tree isn't created when it should.

Do you have any idea why?
Thanks!

Hello,
I am trying to understand how to check the mouse event (double click and so on) in the MouseClickedCallback function.
Any idea?
Thanks

Robyn Jackey

Robyn Jackey (view profile)

Hi Graham,
Thank you! To answer your question, we don't have any immediate plan to package this with GUI Layout Toolbox, however I developed this with similar code standards.

Hi Robyn,

I'm liking this - makes using tree views considerably easier. I particularly like the included Java source, might even get round to adding to that in future.

One question - do you think this will ever be included with GUILayoutToolbox? (I note both use the +uiextras package)

Robyn Jackey

Robyn Jackey (view profile)

No, Symbolic Math Toolbox is not needed. Sorry for the mistake. I will uncheck it next update.

Tom Sh

Tom Sh (view profile)

Looks great.
But does the symbolic math toolbox realy required?
If so, what functionality would I be missing if I dont have it?
Thanks

Robyn Jackey

Robyn Jackey (view profile)

Hi Bharath, thank you for reporting this! I will take a look and push it out soon.

Bharath

Found one issue while setting 'Name' property of the TreeNode object.

When the Input Name string is empty the Name property of the object is set as an empty array. So while querying back the property in MATLAB it is returned as empty double array.

so I have made one change in the Name.Set Method in the TreeNode.m Class file.

Old code: Line 431
nObj.jNode.setUserObject(value);

New code: Line 431
nObj.jNode.setUserObject(java.lang.String(value));

Please Update it in the ToolKit if you can.

Robyn Jackey

Robyn Jackey (view profile)

Josiah,

Regarding saving the tree object to a MAT file, I didn't have that workflow in mind when building this. Usually I would design an app with separate backend object hierarchy that could be saved to disk, and then mirror that hierarchy in the tree for display.

If you really wanted to save the whole tree object to MAT file, the classdef files in this submission would need some changes to do some cleanup and reinstantiation of Java objects upon load. But I think you might want to consider other options first.

Robyn Jackey

Robyn Jackey (view profile)

Hi Daniel,

I think what you need is something like this:

ChildNames = {nodeObj.Children.Name}';

Daniel

Daniel (view profile)

Hi Robyn
This is an outstanding contribution thank you. I've a small question though when it comes to dealing with a parent node and its children.

I would like to count and create a string array consisting of the names of the children nodes. Any suggestions?

Daniel

If I create a tree and then drag and drop the elements, is there a convenient way to save it to a file so I can load the same tree structure again? Just using the save() function on the Node environment variables throws a large number of Java exceptions (Release 2016a).

dsfs

dsfs (view profile)

Excelled. reduces lot of work while creating GUI

Armindo

Hi Robyn,

How can I change the name of the Root?

Robyn Jackey

Robyn Jackey (view profile)

Please note there is currently an incompatibility with the checkbox tree component in R2015b. This is being investigated.

Robyn Jackey

Robyn Jackey (view profile)

On reordering nodes, I didn't implement that capability or the drag and drop to insert a node between others.

A simple solution is that you can change the Node's Parent property to empty and then reassign it to push it to the end of that branch.

md nahid

is there a way to reorder the nodes?
I tried the insertNode, but it creates an empty space in the place of node that needs to move.
any help is appreciated.

Robyn Jackey

Robyn Jackey (view profile)

The Java Table Wrapper is now available as a separate entry:

Java Table Wrapper for User Interfaces

http://www.mathworks.com/matlabcentral/fileexchange/49994-java-table-wrapper-for-user-interfaces

Robyn Jackey

Robyn Jackey (view profile)

Hi David,

This is a bug. I will update the submission shortly. If you need an immediate fix, update this function around line 403 of TreeNode.m to:

function updateTreeReference(nObj,Tree)
for idx=1:numel(nObj)
nObj(idx).Tree = Tree;
if ~isempty(nObj(idx).Children)
updateTreeReference(nObj(idx).Children, Tree);
end
end
end

Thanks,
Robyn

David

David (view profile)

Hi Robyn,

I was just using the supplied Tree_Example.m with no modifications.

I can prompt the error using the following process:

1. Drag and drop Node_1_1 (renamed) onto Node_2
2. Drag and drop Node_1_2 onto Node_2
3. Drag and drop Node_2 onto Node_1

This causes the error:

------------------------------------------
Incorrect number of right hand side elements in dot name assignment. Missing [] around left hand side is a
likely cause.

Error in uiextras.jTree.TreeNode/updateParent/updateTreeReference (line 405)
nObj.Tree = Tree;

Error in uiextras.jTree.TreeNode/updateParent/updateTreeReference (line 407)
updateTreeReference(nObj.Children, Tree);

Error in uiextras.jTree.TreeNode/updateParent (line 390)
updateTreeReference(nObj,newParent.Tree)

Error in uiextras.jTree.TreeNode/set.Parent (line 463)
newParent = updateParent(nObj,newParent);

Error in uiextras.jTree.Tree/onNodeDND (line 902)
set(SourceNode,'Parent',TargetNode)

Error in uiextras.jTree.Tree/createTreeCustomizations/@(src,e)onNodeDND(tObj,e)
----------------------------------------

I think it's something to do with moving a node that has more than one child as this error always occurs in the scenario.

I have also tried using your method for very large trees (e.g. highly hierarchical trees which are conversions of 57MB xml files) but I find that the callbacks from the nodes of such a tree take a long time to be called (up to 13secs, the callback itself runs almost instantaneously). Do you know of a way round this?

Cheers,
David

Robyn Jackey

Robyn Jackey (view profile)

Hi David,

Did you customize the drag/drop callback? I can't tell exactly what the issue is from the description, but a common problem is that the custom drag/drop callback needs to return a boolean indicating whether the current target is valid or not.

David

David (view profile)

Hi Robyn,

This is a real improvement on the tree solutions I've used in Matlab in the past.

I'm particularly interested in the drag and drop capability but I'm having some trouble using it. I'm not sure if the error in the same, or similar, to the error below but when I try to drag a node with more than one sub-node I get the following error:

------------------------------------------
>> Tree_Example
Loading customizations in UIExtrasTree.jar
Incorrect number of right hand side elements in dot name assignment. Missing [] around left hand side is a likely cause.

Error in uiextras.jTree.TreeNode/updateParent/updateTreeReference (line 405)
nObj.Tree = Tree;

Error in uiextras.jTree.TreeNode/updateParent/updateTreeReference (line 407)
updateTreeReference(nObj.Children, Tree);

Error in uiextras.jTree.TreeNode/updateParent (line 390)
updateTreeReference(nObj,newParent.Tree)

Error in uiextras.jTree.TreeNode/set.Parent (line 463)
newParent = updateParent(nObj,newParent);

Error in uiextras.jTree.Tree/onNodeDND (line 902)
set(SourceNode,'Parent',TargetNode)

Error in uiextras.jTree.Tree/createTreeCustomizations/@(src,e)onNodeDND(tObj,e)
------------------------------------------

Does this sound familiar?

Many Thanks for the toolbox,
David

Robyn Jackey

Robyn Jackey (view profile)

Hi Darik,

I hadn't designed for that use case, but I'll take a look at that next time I make updates. I think it would be useful for limited use cases where the structure is large (and slow to read), like a file/directory structure.

Darik

Darik (view profile)

This is great. Is it possible to create expandable nodes without children, constructing children lazily only when the user expands the node? From what I can tell, nodes without children don't show the + sign, and double clicking doesn't trigger a expandnode callback

David Barry

Hi Robyn,

I recently shared our table requirements with David Sampson. I would be interested to hear which of those you will be covering in your forthcoming Java table.

Regards
David

Robyn Jackey

Robyn Jackey (view profile)

Hi David,

Thanks for your review. I do hope to submit a Java table wrapper in the coming months. It's in testing phase now.

Thanks,
Robyn

David Barry

Hi Robyn,

Fantastic submission. I had to recently write my own code for drag/drop with checkbox trees and it was a headache to say the least. I think I'll be moving over to using this straight away. Please push the developers to get this in to the product ASAP!

If you could now just submit a similar quality submission to wrap a Java table to fix all of uitables shortfalls that would be fantastic as I can then ditch my own code for this.

Regards
David

Robyn Jackey

Robyn Jackey (view profile)

Actually, as I look at it closer, the issue is because NodeDraggedCallback is supposed to return a Boolean result. It needs to tell the tree whether the current location is a valid drop point or not. The disp command doesn’t produce an output result. However, the fprintf works without erroring out.

Robyn Jackey

Robyn Jackey (view profile)

Hi Julien,

I think this issue with setting NodeDraggedCallback is related to the disp() command and/or the hgfeval() command. I will inform the development team.

For now, you could use fprintf instead:

TreeObj.NodeDraggedCallback = @(h,e)fprintf('NodeDragged\n');

Robyn Jackey

Robyn Jackey (view profile)

I think the drop "insert" mode to change order is possible, but time consuming to implement. I think you would need to change the tree as jTree.setDropMode(javax.swing.DropMode.ON_OR_INSERT), but there seem to be other things needed.

Robyn Jackey

Robyn Jackey (view profile)

Hi Julien, I will take a look soon. I think 2 is possible with the Java tree, but I didn't implement it in the wrapper.

Julien

Julien (view profile)

Impressive work, very nice submission!
2 points:
1 - An error occurs when 'NodeDraggedCallback' is set (hgfeval does not return outputs).
2 - When DnD is enabled, is it possible to interactively change node order by dropping a source node between 2 destination nodes (insert mode)? It would be very nice!

Matthew

Works, well documented, clean code. A professional standard.

Updates

1.6.0.1

Please Note: If you are using R2017a or later, an improved table is included with Widgets Toolbox. https://www.mathworks.com/matlabcentral/fileexchange/66235-widgets-toolbox

1.6.0.1

Updated license

1.6

Updated description only. Removed dependency for System Identification Toolbox, which was an error.

1.6

Bugfix when deleting a tree. This bug didn't manifest until R2015b where it caused a hang.

1.5

Bugfix for tree node drag and drop

1.3

Add font settings
Fixed callback firing when programmatically setting SelectedNodes to []
Allow hiding root
Fixed node structure changes causing collapsed branches
Fixed unintended command window text in CheckboxTree when DigIn was off

1.1

Updated readme file

MATLAB Release
MATLAB 8.0 (R2012b)

MATLAB Online Live Editor Challenge

Win cash prizes and have your live script featured on our website

Learn more

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video