Uitable sorting

uitable is probably the most complex basic GUI controls available in Matlab. It displays data in a table within a figure, with settable properties as with any other Matlab Handle-Graphics (HG) control. After many years in which the uitable was available but semi-documented and not officially supported in Matlab, it finally became fully documented and supported in R2008a (aka Matlab 7.6). At that time its internal implementation has changed from a MathWorks-developed Java table to a JIDE-based Java table (another JIDE-derived table was described here last year). Since R2008a, both versions of uitable are available – the old version is available by adding the ‘v0’ input arg.

Matlab’s uitable exposes only a very limited subset of functionalities and properties to the user. Numerous other functionalities are available by accessing the underlying Java table and hidden Matlab properties. Today I will describe a very common need in GUI tables, that for some unknown reason is missing in Matlab’s uitable: Sorting table data columns.

Last week I explained how we can modify table headers of an ActiveX table control to display sorting icons. In that case, sorting was built-in the control, and the question was just how to display the sorting arrow icon. Unfortunately, Matlab’s uitable does not have sorting built-in, although it’s quite easy to add it, as I shall now show.

Old uitable sorting

The old uitable is the default control used until R2007b, or that can be selected with the ‘v0’ input arg since R2008a. It was based on an internal MathWorks extension of the standard Java Swing JTable – a class called com.mathworks.widgets.spreadsheet.SpreadsheetTable.

Users will normally try to sort columns by clicking the header. This has been a deficiency of JTable for ages. To solve this for the old (pre-R2008a) uitable, download one of several available JTable sorter classes, or my TableSorter class (available here). Add the TableSorter.jar file to your static java classpath (via edit('classpath.txt')) or your dynamic classpath (javaaddpath('TableSorter.jar')).

% Display the uitable and get its underlying Java object handle
[mtable,hcontainer] = uitable('v0', gcf, magic(3), {'A', 'B', 'C'});   % discard the 'v0' in R2007b and earlier
jtable = mtable.getTable;   % or: get(mtable,'table');
 
% We want to use sorter, not data model...
% Unfortunately, UitablePeer expects DefaultTableModel not TableSorter so we need a modified UitablePeer class
% But UitablePeer is a Matlab class, so use a modified TableSorter & attach it to the Model
if ~isempty(which('TableSorter'))
   % Add TableSorter as TableModel listener
   sorter = TableSorter(jtable.getModel());
   jtable.setModel(sorter);
   sorter.setTableHeader(jtable.getTableHeader());
 
   % Set the header tooltip (with sorting instructions)
   jtable.getTableHeader.setToolTipText('<html>&nbsp;<b>Click</b> to sort up; <b>Shift-click</b> to sort down<br />&nbsp;...</html>');
 
else
   % Set the header tooltip (no sorting instructions...)
   jtable.getTableHeader.setToolTipText('<html>&nbsp;<b>Click</b> to select entire column<br />&nbsp;<b>Ctrl-click</b> (or <b>Shift-click</b>) to select multiple columns&nbsp;</html>');
end

Sorted uitable - old version

Sorted uitable - old version

New uitable sorting

The new uitable is based on JIDE’s com.jidesoft.grid.SortableTable and so has built-in sorting support – all you need to do is to turn it on. First get the underlying Java object using my FindJObj utility:

% Display the uitable and get its underlying Java object handle
mtable = uitable(gcf, 'Data',magic(3), 'ColumnName',{'A', 'B', 'C'});
jscrollpane = findjobj(mtable);
jtable = jscrollpane.getViewport.getView;
 
% Now turn the JIDE sorting on
jtable.setSortable(true);		% or: set(jtable,'Sortable','on');
jtable.setAutoResort(true);
jtable.setMultiColumnSortable(true);
jtable.setPreserveSelectionsAfterSorting(true);

Note: the Matlab mtable handle has a hidden Sortable property, but it has no effect – use the Java property mentioned above instead. I assume that the hidden Sortable property was meant to implement the sorting behavior in R2008a, but MathWorks never got around to actually implement it, and so it remains this way to this day.

A more detailed report

I have prepared a 30-page report about using and customizing Matlab’s uitable, which greatly expands on the above. This report is available for a small fee here (please allow up to 48 hours for email delivery). The report includes the following (more details here):

  • comparison of the old vs. the new uitable implementations
  • description of the uitable properties and callbacks
  • alternatives to uitable using a variety of technologies
  • updating a specific cell’s value
  • setting background and foreground colors for a cell or column
  • using dedicated cell renderer and editor components
  • HTML processing
  • setting dynamic cell-specific tooltip
  • setting dynamic cell-specific drop-down selection options
  • using a color-selection drop-down for cells
  • customizing scrollbars
  • customizing column widths and resizing
  • customizing selection behavior
  • data sorting (expansion of today’s article)
  • data filtering (similar to Excel’s data filtering control)
  • merging table cells
  • programmatically adding/removing rows
  • numerous links to online resources
  • overview of the JIDE grids package, which contains numerous extremely useful GUI controls and components
Categories: GUI, Handle graphics, Hidden property, High risk of breaking in future versions, Java, Semi-documented function, Stock Matlab function, Undocumented feature

Tags: , , , , , , , , ,

Bookmark and SharePrint Print

32 Responses to Uitable sorting

  1. Arda says:

    Hello Yair,
    Without knowing your post, i have posted about this subject at Matlab Newsreader. :)
    http://www.mathworks.com/matlabcentral/newsreader/view_thread/310934/

    However i still couldnt find a way to get the selected cell information. After sorting the data, I try to get the selected cell position (relative to table) with “eventData.Indices” and using the getSortedRowAt with column indice, it is supposed to give me the position of selected cell relative to the original data. My code is;
    jtable.getSortedRowAt(eventData.Indices(1))
    The results are incorrect most of the time unfortunately. Do i make any mistake?

  2. Aurélien says:

    WOW ! thanks Yair: I was rightly looking for this week an easy way to achieve this task : sorting an uitable.
    You gave me the answer. Thanks again!

  3. Yun says:

    Maybe I’m not doing this right, but the new JIDE uitable sort is sorting the values as string only. Even though it is displayed as numbers, right justified, it sorts 3,10,30 as 10,3,30.

    • Yun says:

      Okay it looks like the the new uitable uses default table model, getColumnClass always returns java.lang.Object, so sorting would not be correct for numbers fields even if column format is set to numeric. If there is no reasonably easy way to change this, it significantly reduces the usefulness the new uitable sorting capability.

    • A workaround for sorting numbers in uitable is detailed in the report

    • Yun says:

      I’m feeling dumb. I read through the report, and can’t seem to find any reference to the workaround for dealing with numbers with the new uitable.

    • @Yun – I believe that you read the blog post, not the report. The report is a 35-page document that is available for a small fee here.

  4. Drew says:

    When I have a large number of rows in the uitable, sorting doesn’t function correctly. Do you run into this problem? If yes, is there a way to fix it?
    System info: Windows 7 64-bit, Matlab r2011a 64-bit

    % integers for display
    data = round(9*rand(1000,3));
     
    % Display the uitable and get its underlying Java object handle
    mtable = uitable(gcf,'Data',data,'units','normalized','position',[0 0 1 1]);
    jscrollpane = findjobj(mtable);
    jtable = jscrollpane.getViewport.getView;
     
    % turn JIDE sorting on
    jtable.setSortable(true);
    jtable.setAutoResort(true);
    jtable.setMultiColumnSortable(false);
    jtable.setPreserveSelectionsAfterSorting(true);
    • @Drew – strange indeed. Looks like a JIDE bug to me… Maybe this is the reason for sorting not being exposed in Matlab.

    • Marie-Helene Lavoie says:

      I have the same problem with large number of rows. Moreover, the sorting doesn’t comply with the locale (I’m french canadian). In the following example, ‘Éric’ and ‘Eric’ should be sorted after ‘Aude’ and before ‘Marc’.

      data = {'Lavoie3','Éric';'Lavoie','Marc';'Lavoie','Aude';'Lavoie2','Éric';'Lavoie2','Eric';'Lavoie','Eric'};
      % figure and table
      f=figure;
      p=get(f,'pos');
      th=uitable(f,'pos',[0 0 p(3:4)],'ColumnName',{'Nom','Prénom'},'data',data);
      jPane = findjobj(th,'-nomenu','property',{'Width',p(3)}); %pane
      jTable = jPane.getViewport.getView; %table
      % sorting
      jTable.setSortable(true);
      jTable.setAutoResort(true);
      jTable.setPreserveSelectionsAfterSorting(true);
      jTable.setMultiColumnSortable(true);

      Using jTable.setAutoCreateRowSorter(true) comply with the locale but do not allow for multi column sorting…

  5. Nath says:

    As we can change the column-format property to checkbox, popupmenu options in the uitable, I need help for changing the column-format property to radio-button.

    Help me regarding this issue……….

  6. Pingback: Uitable cell colors | Undocumented Matlab

  7. Jayveer says:

    Hi

    For some strange reason, the ‘new uitable sorting’ isn’t working on windows 7 64 bit. It works fine on lion.

    I get the following error:

    No appropriate method, property, or field getViewport for class
    handle.handle.

    Error in MPMSimPre>MPMSimPre_OutputFcn (line 349)
    jtable = jscrollpane.getViewport.getView;

    Error in gui_mainfcn (line 265)
    feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);

    Error in MPMSimPre (line 280)
    gui_mainfcn(gui_State, varargin{:});

    Please advise.

    Matlab Version: R2011b Win 64bit

    • @Javveer – this is because findjobj doesn’t find the table reference for some unknown reason. Try playing around with different parameters, maybe move the table a bit in the figure, maybe download the latest version of findjobj. If all this still doesn’t work, you can either debug findjobj step-by-step with the debugger, or use a different sorting mechanism, or implement a pure-Java table. As a last resort, you can always use my consulting skills…

    • Jveer says:

      @Yair

      Thank you for the suggestions. Unfortunately none of the simple solutions suggested worked. On snow leopard, placing the sorting code below the one that updates the table seems to do the trick. The only OS the code works flawlessly from within OutputFcn is Lion.

  8. Sebas says:

    Ciao Yair,

    first, thanks you for your fantastic website!

    I’m using the JIDE-based Java table, your example works perfectly. There is only one problem when I try to use a specific filter: “condition”->”is in”->”value(s)”. It opens a checkbox list but when I click on one checkbox, I get a very long error in my command window starting with:

    Exception occurred during event dispatching:
    java.lang.NullPointerException
    	at com.jidesoft.combobox.ExComboBox.validateValueForNonEditable(Unknown Source)
    	at com.jidesoft.combobox.MultiSelectListExComboBox.validateValueForNonEditable(Unknown Source)
    	at com.jidesoft.combobox.ExComboBox.setSelectedItem(Unknown Source)
    	at com.jidesoft.combobox.MultiSelectListExComboBox.setSelectedItem(Unknown Source)
    ...
    

    and of course the filtering does not work. This is a shame because this kind of filter is what I was looking for!

    Have you got any idea about how to fix this problem?

    Thank you very much for your help.

    Seb

    • @Sebas – I’m not sure exactly how you got there but in any case it looks like something that requires some investigation. If you’d like me to check this out for you, contact me by email for a short consulting proposal.

  9. Luc Le Blanc says:

    Is it me or doubles are not properly sorted by the new uitable? In decreasing order (arrow pointing down), I have:

    750.1248
    671.5008
    2.1361e+03

    I double-checked and the data is doubles (…), not strings. Integers don’t exhibit this problem.

  10. Ange Kouemo says:

    Hi Yair,

    I am using Matlab 2014b and created a Uitable that I want to display in a Jpanel. I tried to get the underlying Java object handle of the uitable using the functions you suggested above:

    [mtable,hcontainer] = uitable('v0', gcf, magic(3), {'A', 'B', 'C'});   % discard the 'v0' in R2007b and earlier
    jtable = mtable.getTable;   % or: get(mtable,'table');

    Unfortunately I get the following error:

    No appropriate method, property, or field getTable for class matlab.ui.control.Table.

    Can you please help to come up with this problem? Thanks!

    Regards,
    Ange Laure

  11. Amit says:

    Hi Yair,

    Like you mention that the workaround to sort numerically (rather than lexically) is mentioned in your uitable report, is it mentioned in your ‘Undocumented secrets of MATLAB’ book? Or do I need to get that uitable report too specifically for this?

    Many thanks for all your articles. You had been a life saver so many times.

    Cheers…

    • @Amit – unfortunately I only refer to this issue in my report, not the book. My Matlab-Java book was published 4.5 years ago and in the meantime I expanded the coverage of uitable in my uitable customization report, so it now contains more contents than the book, including this specific feature. On the other hand, the book includes a lot of other content that is not related to uitable. Also, the report is in full-color PDF format, whereas the book is not. So while there is overlap between the book and the report, they are different in important ways, and complement each other.

    • Amit says:

      Are you working on new editions of both of your books? I would love get updated editions. I am going for your uitable report meantime. Thanks for your help.

  12. Praneeth says:

    Hi Yair,

    I tried using getSelectionModel and Valuechangedcallback but with a single mouse click function is getting executed multiple times with same data and finally giving output and an error saying “exception in thread AWT=EventQueue-0”

    can you please help with this

    • @Praneeth – you need to handle this programmatically, within your Matlab callback function. For example:

      function myCallbackFunc(hObject, eventData)
         if eventData.getValueIsAdjusting,  return,  end  % immediate bail-out for intermediate events
         ...
      end

      Also look at the various mechanism to avoid callback reentrancy here: http://undocumentedmatlab.com/blog/controlling-callback-re-entrancy

    • Praneeth says:

      @Yair – I tried it always value in Valueisadjusting is 0 but still its running in a loop and finally throwing the error “exception in thread AWT=EventQueue-0”.

      Also can you tell me in which page did u mention about sorting numerically with JIDE. i read through your undocumented matlab book but didint find

    • @Praneeth – You did not listen to what I told you: you need to prevent callback reentrancy yourself, in your callback function. Multiple ways to do this are discussed in the webpage that I linked in my previous answer.

      As for numeric sorting, I did not discuss this issue in my book. You basically need to create a custom data model Java class that handles this (or contract me to do it for you).

    • Praneeth says:

      To make it more clear its running multiple times on a single cell value

    • Praneeth says:

      @Yair. Thanks a lot for the reply.

      Callback reentrancy is now controlled but still i am getting the java exception “exception in thread AWT=EventQueue-0”

      Anyway to avoid this?

Leave a Reply


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