Adding a context-menu to a uitree

A CSSM poster asked a few days ago whether it was possible to add a context (right-click) menu to uitree nodes. Uitree is an internal, undocumented and unsupported Matlab function, which does not enable easy setting of a uicontextmenu like its uicontrol relatives.

However, using some undocumented Java magic, it is possible to do so. Being undocumented and unsupported, this solution might break in future releases, although this is unlikely since it relies on some very basic Java functionality that is unlikely to be broken soon.

Note that the context-menu in the following example uses HTML formatting. As explained in an earlier post, all Swing components (and by extension, most Matlab uicontrols) support HTML formatting.

% Prepare the context menu (note the use of HTML labels)
menuItem1 = javax.swing.JMenuItem('action #1');
menuItem2 = javax.swing.JMenuItem('<html><b>action #2');
menuItem3 = javax.swing.JMenuItem('<html><i>action #3');

% Set the menu items' callbacks
set(menuItem1,'ActionPerformedCallback',@myFunc1);
set(menuItem2,'ActionPerformedCallback',{@myfunc2,data1,data2});
set(menuItem3,'ActionPerformedCallback','disp ''action #3...'' ');

% Add all menu items to the context menu (with internal separator)
jmenu = javax.swing.JPopupMenu;
jmenu.add(menuItem1);
jmenu.add(menuItem2);
jmenu.addSeparator;
jmenu.add(menuItem3);

% Set the tree mouse-click callback
% Note: MousePressedCallback is better than MouseClickedCallback
%       since it fires immediately when mouse button is pressed,
%       without waiting for its release, as MouseClickedCallback does
set(jtree, 'MousePressedCallback', {@mousePressedCallback,jmenu});

% Set the mouse-press callback
function mousePressedCallback(hTree, eventData, jmenu)
   if eventData.isMetaDown  % right-click is like a Meta-button
      % Get the clicked node
      clickX = eventData.getX;
      clickY = eventData.getY;
      jtree = eventData.getSource;
      treePath = jtree.getPathForLocation(clickX, clickY);
      try
         % Modify the context menu or some other element
         % based on the clicked node. Here is an example:
         node = treePath.getLastPathComponent;
         nodeName = ['Current node: ' char(node.getName)];
         item = jmenu.add(nodeName);

         % remember to call jmenu.remove(item) in item callback
         % or use the timer hack shown here to remove the item:
         timerFcn = {@removeItem,jmenu,item};
         start(timer('TimerFcn',timerFcn,'StartDelay',0.2));
      catch
         % clicked location is NOT on top of any node
         % Note: can also be tested by isempty(treePath)
      end

      % Display the (possibly-modified) context menu
      jmenu.show(jtree, clickX, clickY);
      jmenu.repaint;
   end
end

% Remove the extra context menu item after display
function removeItem(hObj,eventData,jmenu,item)
   jmenu.remove(item);
end

% Menu items callbacks must receive at least 2 args:
% hObject and eventData – user-defined args follow after these two
function myfunc1(hObject, eventData)
   % ... 

function myFunc2(hObject, eventData, myData1, myData2)
    % ... 

uitree node-specific context-menu

uitree node-specific context-menu
(note the HTML formatting of menu items)

If the issue of undocumented Matlab interests you, please review the list of future post topics and let me know if you have any preference, or would like to see some other (unlisted) topics.

Yair

Bookmark and Share

Related posts:

  1. Setting listbox mouse actions Matlab listbox uicontrol can be modified to detect mouse events for right-click context menus, dynamic tooltips etc....
  2. Context-Sensitive Help Matlab has a hidden/unsupported built-in mechanism for easy implementation of context-sensitive help...
  3. FindJObj GUI - display container hierarchy The FindJObj utility can be used to present a GUI that displays a Matlab container's internal Java components, properties and callbacks....
  4. Setting system tray icons System-tray icons can be programmatically set and controlled from within Matlab, using new functionality available since R2007b....
  5. Uicontrol callbacks This post details undocumented callbacks exposed by the underlying Java object of Matlab uicontrols, that can be used to modify the control's behavior in a multitude of different events...
  6. Customizing Matlab labels Matlab's text uicontrol is not very customizable, and does not support HTML or Tex formatting. This article shows how to display HTML labels in Matlab and some undocumented customizations...

Tags: , ,

PoorSo-soHelpfulVery helpfulExcellent! (3 votes, average: 5.00 out of 5)
Loading ... Loading ...
Bookmark and Share Print Print

4 Responses to “Adding a context-menu to a uitree”

  1. Darik Gamble Darik Gamble says:

    Yair,

    I’m glad to see you’ve got a blog — I remember learning from your newsgroup posts a couple years ago that I could add custom properties and event listeners to handle graphics objects, and both features have helped me immensely (and made it into the Matlab documention!)

    My votes on your to do list include customizing menus and the two schema topics.

    Cheers,

    dg

  2. Venky Venky says:

    Yair,
    It’s interesting to know that it is possible to add uicontextmenus to uitree.
    Your post saved my time.
    Thanks a lot

  3. Scott Koch Scott Koch says:

    If you have access to the figure handle (stored as User Data for instance) you could also use the click event coordinates to display a GUIDE created context menu:

    ...
    if eventData.isMetaDown
      fh = get(hTree,'UserData');%Get figure handle
      cm = findobj(fh,'tag','mycontextmenu');%Get context menu handle.
      tpos = get(hTree,'PixelPosition');
     
      set(cm,'position',[eventData.getX()+tpos(1) (tpos(4)-eventData.getY)+tpos(2)],'Visible','on');
     
    ...
  4. [...] months ago I explained how to set a context (right-click) menu on a uitree control. I shall now show how to implement a similar dynamic context-menu on a listbox. The code is an [...]

Leave a Reply


Wrap code fragments inside <pre lang="matlab"> tags, like this:

   <pre lang="matlab">
   a = magic(3);
   sum(a)
   </pre>