Since Matlab 7.0 (R14), Matlab has included a built-in GUI table control (uitable), at first as a semi-documented function and in release 7.6 (R2008a) as a fully-documented function. Useful as this control is, it lacks many features that are expected in modern GUIs, including sorting, filtering, cell-specific appearance and behavior, gridline customization etc. In past articles I have explained how uitable can be customized to achieve a more professional-looking table. I expanded on this in my book and my detailed uitable customization report.

Today I explain how a grouping hierarchy can be achieved in a table control that can be used in Matlab GUI. Such a control, which is a combination of a uitree and uitable, is typically called a tree-table. We can find numerous examples of it in everyday usage. I have encapsulated the functionality in a utility called treeTable on the Matlab File Exchange (#42946). The utility is provided with full source code and open-source license, and readers are welcome to use and modify it. A detailed explanation of the technicalities follows below, but if you’re just interested in having a sortable, rearrangeable, customizable, groupable table control, then all you need to do is download and use the utility.

treeTable utility

treeTable utility

headers = {'ID','Label','Logical1','Logical2','Selector','Numeric'};
data = {1,'M11',true, false,'One', 1011;  ...
        1,'M12',true, true, 'Two', 12;   ...
        1,'M13',false,false,'Many',13.4; ...
        2,'M21',true, false,'One', 21;  ...
        2,'M22',true, true, 'Two', 22;   ...
        3,'M31',true, true, 'Many',31;   ...
        3,'M32',false,true, 'One', -32;  ...
        3,'M33',false,false,'Two', 33; ...
        3,'M34',true, true, 'Many',34;  ...
selector = {'One','Two','Many'};
colTypes = {'label','label','char','logical',selector,'double'};
colEditable = {true, true, true, true, true}
icons = {fullfile(matlabroot,'/toolbox/matlab/icons/greenarrowicon.gif'), ...
         fullfile(matlabroot,'/toolbox/matlab/icons/file_open.png'), ...
         fullfile(matlabroot,'/toolbox/matlab/icons/foldericon.gif'), ...
% Create the table in the current figure
jtable = treeTable('Container',gcf, 'Headers',headers, 'Data',data, ...
                   'ColumnTypes',colTypes, 'ColumnEditable',colEditable, ...
                   'IconFilenames',icons, 'Groupable',true, 'InteractiveGrouping',false);
% Collapse Row #6, sort descending column #5 (both are 0-based)
jtable.expandRow(5,false);  % 5=row #6; false=collapse
jtable.sortColumn(4,true,false);  % 4=column #5; true=primary; false=descending

The basic implementation concept

Unfortunately, uitable as-is cannot be customized to have groupable rows. It derives from JIDE’s SortableTable, rather than one of its groupable derived classes. On the other hand, uitree (don’t you agree that after a decade of this so-useful function being semi-documented it ought to be made official?) uses a different class hierarchy outside com.jidesoft.grid, and so it cannot be easily customized to display rows (as opposed to simple labels).

These limitations mean that we cannot use uitable or uitree and need to use a custom component. Luckily, such a component is available in all Matlab installations, on all platforms. It is part of the grid components package, on which Matlab GUI has relied for many years, by JIDE Software. JIDE Grids is a collection of components that extend the standard Java Swing JTable component, and is included in each Matlab installation (/java/jarext/jide/jide-grids.jar under the Matlab root). I discussed multiple JIDE controls in this blog over the years. You can find further details on JIDE Grids in the Developer Guide and the Javadoc documentation.

In fact, there are no less than three different components that we could use in our case: TreeTable, GroupTable and HierarchicalTable:

JIDE Grids class hierarchy (we normally use only one of the marked classes)

JIDE Grids class hierarchy (we normally use only one of the marked classes)

Note that we cannot use PropertyTable since that component is limited to only two columns. This is perfect for presenting property names and values, which is the reason it is used by Matlab’s inspect function and my generic propertiesGUI utility or Levente Hunyadi’s Property Grid utility. But in this case we wish to display a general multi-column table, so PropertyTable is a no-go.

TreeTable and GroupTable enable data rows that have similar type (class), whereas HierarchicalTable enables more flexibility, by allowing display of any component type (including full tables) in child rows. This flexibility comes with a price that customizing a HierarchicalTable is more difficult than TreeTable or GroupTable. These latter two components are quite similar; we use GroupTable, which extends TreeTable with the ability to automatically group rows that have the same value in a certain column.

Data model

The above-mentioned table classes all derive from SortableTable (which also underlies uitable). Unfortunately, something in the Matlab-Java interface breaks the ability of the JIDE table classes (or rather, their data model) to understand numeric values for what they are. As a result, sorting columns is done lexically, i.e. “123” < “34” < “9”. To fix this, I’ve included a custom Java table model (MultiClassTableModel) with the treeTable utility, which automatically infers the column type (class) based on the value in the top row (by overriding the getColumnClass() method).

Using this new class is pretty easy:

% Create the basic data-type-aware model using our data and headers
javaaddpath(fileparts(mfilename('fullpath')));  % add the Java class file to the dynamic java class-path
model = MultiClassTableModel(data, headers);  % data=2D cell or numeric array; headers=cell array of strings
% Wrap the standard model in a JIDE GroupTableModel
com.mathworks.mwswing.MJUtilities.initJIDE;  % initialize JIDE
model = com.jidesoft.grid.DefaultGroupTableModel(model);
model.addGroupColumn(0);  % make the first column the grouping column
model.groupAndRefresh;  % update the model data
% Use the generated model as the data-model of a JIDE GroupTable
jtable = eval('com.jidesoft.grid.GroupTable(model);');  % prevent JIDE alert by run-time (not load-time) evaluation
jtable = handle(javaObjectEDT(jtable), 'CallbackProperties');  % ensure that we're using EDT
% Enable multi-column sorting
% Present the tree-table within a scrollable viewport on-screen
scroll = javaObjectEDT(JScrollPane(jtable));
[jhscroll,hContainer] = javacomponent(scroll, tablePosition, hParent);
set(hContainer,'units', 'normalized','pos',[0,0,1,1]);  % this will resize the table whenever its container is resized

Here, com.mathworks.mwswing.MJUtilities.initJIDE is called to initialize JIDE’s usage within Matlab. Without this call, we may see a JIDE warning message in some Matlab releases. We only need to initJIDE once per Matlab session, although there is no harm in repeated calls.

javacomponent is the undocumented built-in Matlab function that adds Java Swing components to a Matlab figure, using the given dimensions and parent handle. I discussed it here.


There are two main callbacks that can be used with treeTable:

  • table data update – this can be set by uncommenting line #237 of treeTable.m:
    set(handle(getOriginalModel(jtable),'CallbackProperties'), 'TableChangedCallback', {@tableChangedCallback, jtable});

    which activates the sample tableChangedCallback() function (lines #684-694). Naturally, you can also set your own custom callback function.

    % Sample table-editing callback
    function tableChangedCallback(hModel,hEvent,jtable)
        % Get the modification data
        modifiedRow = get(hEvent,'FirstRow');
        modifiedCol = get(hEvent,'Column');
        label   = hModel.getValueAt(modifiedRow,1);
        newData = hModel.getValueAt(modifiedRow,modifiedCol);
        % Now do something useful with this info
        fprintf('Modified cell %d,%d (%s) to: %s\n', modifiedRow+1, modifiedCol+1, char(label), num2str(newData));
    end  % tableChangedCallback
  • row selection update – this is currently enabled in line #238 of treeTable.m:
    set(handle(jtable.getSelectionModel,'CallbackProperties'), 'ValueChangedCallback', {@selectionCallback, jtable});

    which activates the sample selectionCallback() function (lines #696-705). Naturally, you can also set your own custom callback function.

    % Sample table-selection callback
    function selectionCallback(hSelectionModel,hEvent,jtable)
        % Get the selection data
        MinSelectionIndex  = get(hSelectionModel,'MinSelectionIndex');
        MaxSelectionIndex  = get(hSelectionModel,'MaxSelectionIndex');
        LeadSelectionIndex = get(hSelectionModel,'LeadSelectionIndex');
        % Now do something useful with this info
        fprintf('Selected rows #%d-%d\n', MinSelectionIndex+1, MaxSelectionIndex+1);
    end  % selectionCallback

Some useful features of treeTable

treeTable with InteractiveGrouping, multi-column sorting, column rearranging

treeTable with interactive grouping, multi-column sorting, column rearranging

  • Sortable columns (including numeric columns)
  • Rearrangeable columns (drag headers left/right)
  • Auto-fit the table columns into the specified container width
  • Manually resize columns by dragging the column divider gridlines (not just the header dividers as in uitable)
  • Flat or groupable table, based on the specified Groupable parameter (default=true)
  • Ability to interactively group columns (just like Microsoft Outlook) using the InteractiveGrouping parameter (default=false)
  • Selector cells only show the drop-down arrow of the currently-selected cell (unlike uitable which shows it for all the column cells)
  • Selector cells enable editing, unlike uitable that only enables selecting among pre-defined values
  • Ability to attach user-defined icons for the leaf rows and the grouping rows (expanded/collapsed)
  • Easily attach custom cell editors or renderers to any table column (see my book and my detailed uitable customization report for details)

All of these features can be turned on/off using the control’s properties. Again, see my book or report for details (or ask me to do it for you…).

I remind readers that I will be visiting clients in Austria (Vienna, Salzburg) and Switzerland (Zurich) in August 18-29. If you live in the area, I will be happy to meet you to discuss how I could bring value to your needs, as consultant, contractor or trainer (more details).

Categories: GUI, High risk of breaking in future versions, Java, Semi-documented function, Undocumented feature

Tags: , , , , ,

Bookmark and SharePrint Print

69 Responses to treeTable

  1. Jim Hokanson says:

    Wow, this looks perfect for a couple of projects that I have in mind. I look forward to looking at the code and trying it out. Thanks.

  2. Assaf says:

    Quick Q here..
    Is there a way to do an “automatically” subgrouping — i.e. Directly set it in the source code (and not in the interactive way)?

    • Yair Altman says:

      @Assaf – It’s good to see you here!

      You can do something similar to

      model = jtable.getModel.getActualModel;
    • Assaf says:

      Hi, Yair.
      Thanks for the quick reply!

      For some reason your suggestion didn’t work for me\

      This is what I got:
      >> model.addGroupColumn(1);
      No appropriate method, property, or field addGroupColumn for class com.jidesoft.grid.SortableTreeTableModel.

    • I had a typo in the code snippet – it’s now fixed

    • Assaf says:


  3. Assaf says:

    Another Quick Q here..
    How can I update the “selector” (the drop-down list) on the fly — i.e. I want to add \ remove entries on the list – based on values ​​entered into other cells.
    Many Thanks!

  4. Alex says:

    I have noticed that


    returns a different value depending on how the TreeTable rows are sorted. Is there a way to tell the corresponding row of the data cell array when a row in the TreeTable has been selected?

    • This will get you the original data model row number (note: 0-based value):

      selectedVisualRow = hTree.getSelectionModel.getMinSelectionIndex;
      selectedActualRow = hTree.getModel.getActualRowAt(selectedVisualRow);
  5. Pingback: Using JIDE combo-boxes | Undocumented Matlab

  6. Sam says:

    Hi Yair,

    I’d like to adjust the tableChanged callback in the function I’m writing (perform a plotting task when a box is checked/unchecked) and leave treeTable.m generic. I’m only familiar with the basic set(,’Callback’,{@updateplot}) syntax and I’m not sure how to adjust for this type of object, could you point me in the right direction? I’ve been playing around with the first block of code on this page as an example.



  7. kefang says:

    hi Yair
    i’d like to use a timer to update the data in can i realize it ?


    • Yair Altman says:

      Matlab timers are described here

    • kefang says:

      hi Yair
      i know matlab timers. my question is how to change the data in treetable when i use matlab timers callback function?
      Thanks! could you leave me your email?

    • @Kefang – You can use the setValueAt method. To understand how to use it, refer to any Java table tutorial.

      Re my email, there’s a link on the top-right of every page on this blog. For personal assistance via email I usually charge a consulting fee.

    • kefang says:

      thank you for your help.

  8. Viktor says:

    Hi Yair,

    many thanks for another fine hack!
    I have a questions regarding the treeTable:
    So far i have not been able to remove the treeTable from a figure. I’ve managed to hide it
    by using the setVisible(false) method but couldn’t use the space for anything else afterwards.
    So is it possible to remove the treeTable from the container i linked it to?


    • @Viktor – right now there is no easy way to remove the treeTable. You can delete the Matlab container hcontainer from lines 200-204 if you store it somewhere (e.g., the treeTable’s ApplicationData property using setappdata/getappdata).

      If you don’t have the hcontainer handle, you can directly remove it from view as follows:

      jtree = treeTable(...);
      jtreePanel = jtree.getParent.getParent.getParent;
      jtreePanelParent = jtreePanel.getParent;
  9. Kevin says:

    This is awesome. I would like to have a hierarchical tree. I got some sample data to create a uitree, and understand adding uinodes to the uitree are connected by:

    node() = uinode('fullParentName', 'displayname'...)

    To get:


    After some tinkering with the sample data for treetable, I was unable to get a hierarchy (sub-folders grouped under sub-folders), although the construct of the data is similar to the uinode. I am confused if I am just formatting the sample data wrong, or if what I am hoping to achieve relies on a deeper issue being addressed: = {'A1','A1',true, false,'One', 1011;  ... %root node
                         'A1','M11',false,false,'Many',13.4; ...
                         'A1','A2',true, true, 'Two', 12;   ...
                         'A2','M21',true, false,'One', 21;  ...
                         'A1A2','M22',true, true, 'Two', 22;   ...

    Also, I would like to know how to add data to the displayed folder rows. Currently they are empty, but I would like to add numeric values to the leaf nodes, and have parent branches contain roll-up values for the child leaves (and other child sub-branches) beneath it.



    • Kevin says:

      Sorry – in my above post I meant to say ‘I would like to have a hierarchical tree with a table to the right of it’. So, I want a treetable functionality where I can put data and widgets, and yet have the full hierarchy for data in the first column.

  10. kefang says:

    how can i get the row and col in the treetable when i use the function selectionCallback

    • row = jtable.getSelectedRow + 1;     % Java row # starts at 0, not 1 as in Matlab
      col = jtable.getSelectedColumn + 1;  % Java col # starts at 0, not 1 as in Matlab
  11. frankie says:

    i want to set different color in the odd and even can i do it ?

  12. Jan says:

    Hi again,

    I’m having a problem with the treeTable utility. As soon as I call the treeTable function, my workspace gets cleared. I haven’t seen a ‘clear xxx;’ or anything in your code. Can you help me?

    Thanks again,

    • @Jan – blame MathWorks… This undocumented side-effect of javaaddpath has been reported numerous years ago, and was never fixed.

    • Jan says:

      Hi Yair,
      then I have to deal with this somehow …

      Another thing: why is the ‘ValueChangedCallback’ called twice?

      I apologize for those many questions I had for the last few days…


    • @Jan – I’m sorry but if you would like dedicated support, I would be happy to provide it for you as a consultant. Please approach me via email (link at the top-right of this page).

  13. frankie says:

    Hi Yair
    In the following codes ,


    No appropriate method, property, or field getGroup for class com.jidesoft.grid.DefaultGroupTableModel.

    • @Frankie – there are variations between JIDE releases used by different Matlab releases. This specific method probably does not exist on your specific Matlab release. You’d need to search for alternatives, it is possible that in your particular release the method is called something else, or perhaps the functionality can be done by some other means. If you’d like me to investigate your specific case as a consultant, then email me.

  14. James says:

    Very nice. Is there a way to programmatically select or de-select a row? When I try

    jtable.setSelectedRows([2, 3])

    I get no appropriate method, and when I try

    set(jtable, 'SelectedRows', [2, 3])

    I get something like ‘changing ‘SelectedRows’ property of …. is not allowed. I also tried it with ‘SelectedRow’, but that gives the same errors.
    Thank you for all of help!
    Best regards,

    • @James – use the changeSelection(rowIdx,colIdx,flag,flag) to programmatically set the selected row(s). More details in my book and uitable customization report.

  15. Geert says:

    HI Yair,

    Is it easy to add additional columns to an existing tree table?


  16. Julien says:

    Hello Yair,
    Nice post !! Is it possible to display data in the cells of the rows which are expandable ?

    • @Julien – take a look at the screenshots: the expandable columns automatically display their data in [columnName]: [value] format

      Maybe I did not understand your question…

    • Julien says:

      Actually, I would like to display statistics of the grouped rows at the expanded rows levels.
      For example: I have a table which first column is a label (column on which grouping is done) and the other columns are Numbers. I would like to display on the expandable rows the mean values of all the expanded rows in the corresponding cells. First column will contain indeed the [columnName]: [value] and the others will contain the means (no spanning).
      TableModel example :

      Animal      Name    Age       Weight
      Dog          Rex      5           12
      Dog       Brutus      7            8
      Cat          Tom     15            4
      Cat        Kitty      3            1

      After grouping on the first column :

      Name            Age              Weight
      +Animal:Dog      6                   10
      Rex              5                   12
      Brutus           7                    8
      +Animal:Cat      9                  2.5
      Tom             15                    4
      Kitty            3                    1

      Maybe it is clearer?

    • You will probably need to use some Java class code for this, I don’t think it can be done directly in Matlab.

  17. LG says:

    Is there a simple way to add and control a uitree to a guide created gui ?

    • @LG – you cannot (as of R2014a) do it from within the GUIDE application, but once you create your application with GUIDE you can modify the generated m-file to add the corresponding Matlab commands, for example in the *_OpeningFcn function at the top of the m-file.

  18. Geert van Kempen says:

    Hi Yair,

    Is it possible to make a particular row editable instead of cloumns?



  19. vinod chauhan says:

    sir can i get the full source code of treetable

  20. Peter Dowell says:

    Hi Yair,

    I’ve come accross an interesting issue running TreeTable.
    When I sub group a column either interactively, or programatically as described above, columns which previously were non-editable become editable.

    For example, if you call TreeTable as per the code in the article, except with:

    colEditable = {false, false, false, false, false}

    Everything works fine (i.e. you cannot edit the columns), until you run:

    model = jtable.getModel.getActualModel;

    At which point, the columns become editable again. Any suggestions?

    • @Peter – indeed: when you add a grouping column you affect the model and the old definitions are forgotten. You can do the following (a variant can be found in the treeTable source code):

      jtf = JTextField;
      jte = DefaultCellEditor(jtf);
      for colIdx = 0 : jtable.getColumnCount-1
    • Peter Dowell says:


      Thanks for the quick reply. I guess the states of the renderers/editors would have to be updated when the user changes the grouping. I was thinking that the setColumnRenderersEditors function could be called by a listener function on the re-grouping event. What do you think?

    • Sounds reasonable. You’re welcome to try. Come back and post a followup comment here after you figure out the exact specifics.

  21. Ruedi says:

    Hi Yair,
    Thanks for this great GUI table control. One more question: is there an easy way to include kind of a “total” row? For e.g. in your figure above, if the ID3 has some total (column Numeric may sum up to 1) I would like to show this sum in the same row as the ID3-icon.
    Thanks for your help

  22. In treeTable.m there are references to setTableData and getTableData. Where exactly are these functions defined?

    Alternatively thought I could something like


    to update the treeTable panel.

    • @Simon – setTableData() and getTableData() are simply placeholders for functions to get/set the data from the table. They are not defined anywhere, they are merely used to illustrate a sample row insertion function. You would need to implement these functions in your own code.

  23. Markus Jakobsen says:

    Hi Yair

    Why do I get this error when I run the following code?

    [data,headers] = getTableData(jtable);

    Undefined function ‘getTableData’ for input arguments of type

    • Yair Altman says:

      @Markus – I answered this exact question only 2 weeks ago

      It’s right there above your comment – didn’t you see it?

    • Markus Jakobsen says:

      Hi Yair

      I saw it, but must have misunderstood the meaning of “placeholders”. So the only way to get the entire data table is to run the following through a loop? Or?

      Val = jtable.getValueAt(i,j)

      How do I append data to an existing table? I can’t access rows beyond the data size with setValueAt.

      jtable.setValueAt(11, i, j)

      So all in all, could you give a few pointers on how to get the entire dataset and set new data to an existing jtable.

      Thanks a lot

    • @Markus – you could do that, plus various other underlying Java methods to do this, which is beyond the scope of a blog comment. You can read about this in my Matlab-Java book or my more recent/detailed uitable report. Or hire me for a short consultancy

  24. Ruedi says:

    Hi Yair,

    Trying the example above, the “numeric” column is not shown as doubles but as chars, i.e. left-aligned in the cell. Even with

    colTypes = {'label','label','char','logical',selector,'double'};

    Is there any additional java library I need to include in the code?


    • @Ruedi – the file includes various Java files – they should all be placed in the same folder as the treeTable.m Matlab file.

  25. Alex says:

    Hi Yair,

    do you see any easy way to implement data filtering as it is done in Excel? (i.e., offer the user the possibility to restrict the display to the only rows containing a given user-selected value in a given column)


  26. Clayton Valentine says:

    Hi Yair,

    I was wondering how to set the significant decimal digits for the table?



  27. Marc says:


    Thank you very much for this work. It is very handy.

    I was wondering if we were any way to adjust ColumnWidth ?


  28. Alex says:

    Hi Yair,

    to prevent editability of cells, I see in your code that you take two actions (in the subfunction setColumnRenderersEditors):


    In practice, this, however, does not prevent the user to enter in some sort of in-between editable mode when starting to type in a cell after having selected it with the mouse; upon exiting the cell, the tableChangedCallback function is fired. The effect is equivalent to setting the number of clicks to start edition to zero but without having the cell content selected.

    How could one prevent that from happening? That is, if a user starts typing, nothing happens at all and the callback function is not fired? Thanks for your reply.


    • @Alex – have you actually tried this? I do not think that the cells can be interactively edited after editing has been prevented as in my code.

    • Alex says:

      I have. I have sent you by e-mail a MWE showing this behavior.

    • Alex says:

      A quick follow up on the issue mentioned above. Even though it’s a bit of a dirty fix—which kills some of the flexibility—it appears that blocking editing directly in the java class ( by explicitly defining the isCellEditable method seems to prevent that unexpected behavior…

  29. Petr says:

    Works perfect, thanks Yair! Let me ask you how do I get the real row number in the table if my above label is collapsed? Thanks, Petr

Leave a Reply

Your email address will not be published. Required fields are marked *