Undocumented Matlab
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT

Matlab toolstrip – part 9 (popup figures)

February 10, 2019 6 Comments

In previous posts I showed how we can create custom Matlab app toolstrips using various controls. Today I will show how we can incorporate popup forms composed of Matlab figures into our Matlab toolstrip. These are similar in concept to drop-down and gallery selectors, in the sense that when we click the toolstrip button a custom popup is displayed. In the case of a popup form, this is a fully-customizable Matlab GUI figure.

Popup figure in Matlab toolstrip

Toolstrips can be a bit complex to develop so I’m proceeding slowly, with each post in the miniseries building on the previous posts. I encourage you to review the earlier posts in the Toolstrip miniseries before reading this post.
Also, remember to add the following code snippet at the beginning of your code so that the relevant toolstrip classes will be recognized by Matlab:

import matlab.ui.internal.toolstrip.*

import matlab.ui.internal.toolstrip.*

Main steps and usage example

To attach a figure popup to a toolstrip control, follow these steps:

  1. Create a new figure, using GUIDE or the figure function. The figure should typically be created modal and non-visible, unless there’s a good reason to avoid this. Note that the figure needs to be a legacy (Java-based) figure, created with GUIDE or the figure function — web-based uifigure (created with AppDesigner or the uifigure function) is not [currently] supported.
  2. Create a callback function that opens and initializes this figure, and then moves it to the expected screen location using the following syntax: hToolGroup.showFigureDialog(hFig,hAnchor), where hFig is the figure’s handle, and hAnchor is the handle for the triggering toolstrip control.
  3. Attach the callback function to the triggering toolstrip control.

Here’s a simple usage example, in which I present a file-selector popup:

% Create a toolstrip section, column & push-button
hSection = hTab.addSection('Popup');
hColumn = hSection.addColumn();
hButton = Button('Open',Icon.OPEN_24);
hButton.ButtonPushedFcn = {@popupFigure,hButton};  % attach popup callback to the button
hColumn.add(hButton);
% Callback function invoked when the toolstrip button is clicked
function popupFigure(hAction, hEventData, hButton)
    % Create a new non-visible modal figure
    hFig = figure('MenuBar','none', 'ToolBar','none', 'WindowStyle','modal', ...
                  'Visible','off', 'NumberTitle','off', 'Name','Select file:');
    % Add interactive control(s) to the figure (in this case, a file chooser initialized to current folder)
    jFileChooser = handle(javaObjectEDT(javax.swing.JFileChooser(pwd)), 'CallbackProperties');
    [jhFileChooser, hComponent] = javacomponent(jFileChooser, [0,0,200,200], hFig);
    set(hComponent, 'Units','normalized', 'Position',[0,0,1,1]);  % resize component within containing figure
    % Set popup control's callback (in this case, display the selected file and close the popup)
    jhFileChooser.ActionPerformedCallback = @popupActionPerformedCallback;
    function popupActionPerformedCallback(jFileChooser, jEventData)
        fprintf('Selected file: %s\n', char(jFileChooser.getSelectedFile));
        delete(hFig);
    end
    % Display the popup figure onscreen, just beneath the triggering button
    showFigureDialog(hToolGroup,hFig,hButton);
    % Wait for the modal popup figure to close before resuming GUI interactivity
    waitfor(hFig);
end

% Create a toolstrip section, column & push-button hSection = hTab.addSection('Popup'); hColumn = hSection.addColumn(); hButton = Button('Open',Icon.OPEN_24); hButton.ButtonPushedFcn = {@popupFigure,hButton}; % attach popup callback to the button hColumn.add(hButton); % Callback function invoked when the toolstrip button is clicked function popupFigure(hAction, hEventData, hButton) % Create a new non-visible modal figure hFig = figure('MenuBar','none', 'ToolBar','none', 'WindowStyle','modal', ... 'Visible','off', 'NumberTitle','off', 'Name','Select file:'); % Add interactive control(s) to the figure (in this case, a file chooser initialized to current folder) jFileChooser = handle(javaObjectEDT(javax.swing.JFileChooser(pwd)), 'CallbackProperties'); [jhFileChooser, hComponent] = javacomponent(jFileChooser, [0,0,200,200], hFig); set(hComponent, 'Units','normalized', 'Position',[0,0,1,1]); % resize component within containing figure % Set popup control's callback (in this case, display the selected file and close the popup) jhFileChooser.ActionPerformedCallback = @popupActionPerformedCallback; function popupActionPerformedCallback(jFileChooser, jEventData) fprintf('Selected file: %s\n', char(jFileChooser.getSelectedFile)); delete(hFig); end % Display the popup figure onscreen, just beneath the triggering button showFigureDialog(hToolGroup,hFig,hButton); % Wait for the modal popup figure to close before resuming GUI interactivity waitfor(hFig); end

This leads to the popup figure as shown in the screenshot above.
The popup figure initially appears directly beneath the triggering button. The figure can then be moved away from that position, by dragging its title bar or border frame.
Note how the popup is an independent heavy-weight figure window, having a border frame, title bar and a separate task-bar icon. Removing the border frame and title-bar of Matlab figures can be done using an undocumented visual illusion – this can make the popup less obtrusive, but also prevent its moving/resizing. An entirely different and probably better approach is to present a light-weight popup panel using the Toolpack framework, which I plan to discuss in the following post(s). The PopupPanel container that I discussed in another post cannot be used, because it is displayed as a sub-component of a Matlab figure, and in this case the popup is not attached to any figure (the toolstrip and ToolGroup are not Matlab figures, as explained here).
The astute reader may wonder why I bothered going to all the trouble of displaying a modal popup with a JFileChooser, when I could have simply used the built-in uigetfile or uiputfile functions in the button’s callback. The answer is that (a) this mechanism displays the popup directly beneath the triggering button using hToolGroup.showFigureDialog(), and also (b) enables complex popups (dialogs) that have no direct builtin Matlab function (for example, a file-selector with preview, or a multi-component input form).

Compatibility considerations for R2018a or older

In Matlab releases R2018a or older that do not have the hToolGroup.showFigureDialog() function, you can create it yourself in a separate showFigureDialog.m file, as follows:

function showFigureDialog(hToolGroup, hFig, hAnchor)
    %   showFigureDialog - Display a figure-based dialog below a toolstrip control.
    %
    %   Usage example:
    %       showFigureDialog(hToolGroup, hFig, hAnchor);
    %   where:
    %       "hToolGroup" must be a "matlab.ui.internal.desktop.ToolGroup" handle
    %       "hFig" must be a "figure" handle, not a "uifigure"
    %       "hAnchor" must be a "matlab.ui.internal.toolstrip.***" handle
    %hWarn = ctrlMsgUtils.SuspendWarnings('MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame'); %#ok<nasgu>
    hWarn = warning('off','MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame');
    jf = get(hFig, 'JavaFrame');
    if isempty(jf)
        error('UI figure cannot be added to "ToolGroup". Use a regular figure instead.')
    else
        screen_size = get(0,'ScreenSize');
        old_pos = get(hFig,'OuterPosition');
        dpi_ratio = com.mathworks.util.ResolutionUtils.scaleSize(100)/100;
        jAnchor = hToolGroup.ToolstripSwingService.Registry.getWidgetById(hAnchor.getId());
        pt = javaMethodEDT('getLocationOnScreen',jAnchor); % pt is anchor top left
        pt.y = pt.y + jAnchor.getVisibleRect().height;     % pt is anchor bottom left
        new_x = pt.getX()/dpi_ratio-5;                           % figure outer left
        new_y = screen_size(end)-(pt.getY/dpi_ratio+old_pos(4)); % figure outer bottom
        hFig.OuterPosition = [new_x new_y old_pos(3) old_pos(4)];
        hFig.Visible = 'on';
    end
    warning(hWarn);
end

function showFigureDialog(hToolGroup, hFig, hAnchor) % showFigureDialog - Display a figure-based dialog below a toolstrip control. % % Usage example: % showFigureDialog(hToolGroup, hFig, hAnchor); % where: % "hToolGroup" must be a "matlab.ui.internal.desktop.ToolGroup" handle % "hFig" must be a "figure" handle, not a "uifigure" % "hAnchor" must be a "matlab.ui.internal.toolstrip.***" handle %hWarn = ctrlMsgUtils.SuspendWarnings('MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame'); %#ok<nasgu> hWarn = warning('off','MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame'); jf = get(hFig, 'JavaFrame'); if isempty(jf) error('UI figure cannot be added to "ToolGroup". Use a regular figure instead.') else screen_size = get(0,'ScreenSize'); old_pos = get(hFig,'OuterPosition'); dpi_ratio = com.mathworks.util.ResolutionUtils.scaleSize(100)/100; jAnchor = hToolGroup.ToolstripSwingService.Registry.getWidgetById(hAnchor.getId()); pt = javaMethodEDT('getLocationOnScreen',jAnchor); % pt is anchor top left pt.y = pt.y + jAnchor.getVisibleRect().height; % pt is anchor bottom left new_x = pt.getX()/dpi_ratio-5; % figure outer left new_y = screen_size(end)-(pt.getY/dpi_ratio+old_pos(4)); % figure outer bottom hFig.OuterPosition = [new_x new_y old_pos(3) old_pos(4)]; hFig.Visible = 'on'; end warning(hWarn); end

Under the hood of showFigureDialog()

How does showFigureDialog() know where to place the figure, directly beneath the triggering toolstrip anchor?
The answer is really quite simple, if you look at this method’s source-code in %matlabroot%/toolbox/matlab/toolstrip/+matlab/+ui/+internal/+desktop/ToolGroup.m (around line 500, depending on the Matlab release).
The function first checks whether the input hFig handle belongs to a figure or uifigure, and issues an error message in case it’s a uifigures (only legacy figures are currently supported).
Then the function fetches the toolstrip control’s underlying Java control handle using the following code (slightly modified for clarity), as explained here:

jAnchor = hToolGroup.ToolstripSwingService.Registry.getWidgetById(hAnchor.getId());

jAnchor = hToolGroup.ToolstripSwingService.Registry.getWidgetById(hAnchor.getId());

Next, it uses the Java control’s getLocationOnScreen() to get the control’s onscreen position, accounting for monitor DPI variation that affects the X location.
The figure’s OuterPosition property is then set so that the figure’s top-left corner is exactly next to the control’s bottom-left corner.
Finally, the figure’s Visible property is set to ‘on’ to make the figure visible in its new position.
The popup figure’s location is recomputed by showFigureDialog() whenever the toolstrip control is clicked, so the popup figure is presented in the expected position even when you move or resize the tool-group window.

Toolstrip miniseries roadmap

The following post(s) will present the Toolpack framework. Non-figure (lightweight) popup toolpack panels can be created, which appear more polished/stylish than the popup figures that I presented today. The drawdown is that toolpack panels may be somewhat more complex to program than figures, and IMHO are more likely to change across Matlab releases. In addition to the benefit of popup toolpack panels, toolpack presents an alternative way for toolstrip creation and customization, enabling programmers to choose between using the toolstrip framework (that I discussed so far), and the new toolpack framework.
In a succeeding post, I’ll discuss toolstrip collapsibility, i.e. what happens when the user resizes the window, reducing the toolstrip width. Certain toolstrip controls will drop their labels, and toolstrip sections shrink into a drop-down. The priority of control/section collapsibility can be controlled, so that less-important controls will collapse before more-important ones.
In future posts, I plan to discuss docking layout, DataBrowser panel, QAB (Quick Access Bar), underlying Java controls, and adding toolstrips to figures – not necessarily in this order.
Matlab toolstrips can be a bit complex, so I plan to proceed in small steps, each post building on top of its predecessors.
If you would like me to assist you in building a custom toolstrip or GUI for your Matlab program, please let me know.

Related posts:

  1. Matlab toolstrip – part 4 (control customization) – Matlab toolstrip components (controls) can be customized in various ways, including user-defined callbacks. ...
  2. Matlab toolstrip – part 2 (ToolGroup App) – Matlab users can create custom Apps with toolstrips and docked figures. ...
  3. Matlab toolstrip – part 8 (galleries) – Matlab toolstrips can contain customizable gallery panels of items. ...
  4. Matlab toolstrip – part 5 (icons) – Icons can be specified in various ways for toolstrip controls and the app window itself. ...
  5. Matlab toolstrip – part 3 (basic customization) – Matlab toolstrips can be created and customized in a variety of ways. ...
  6. Matlab toolstrip – part 7 (selection controls) – Matlab toolstrips can contain a wide variety of selection controls: popups, combo-boxes, and galleries. ...
Figure GUI Java Toolstrip Undocumented feature
Print Print
« Previous
Next »
6 Responses
  1. karthik March 18, 2019 at 17:17 Reply

    yair, i am an ardent follower of your undocumented matlab work. i love your present posts on tool strips. Am trying to implement the last post on file chooser using push button call back. however, i receive the following error:
    Undefined variable "hToolGroup" or class "hToolGroup.showFigureDialog".
    Warning: Error occurred while evaluating listener callback.

    hToolGroup is not recognized inside the callback as it is not passed i guess. can you help me out?

    Also, I have matlab 2018a in which toolgroup.m doesnt have hToolGroup.showFigureDialog(hFig,hButton); instead it has hToolGroup.showTearOffDialog(hFig,hButton);

    • Yair Altman March 22, 2019 at 11:29 Reply

      @Karthik – you can pass hToolGroup as an extra parameter to your callback function when you set it up, using cell-array notation (details).

      I plan to discuss tear-off dialogs in my next post in this Toolstrip mini-series, when I will discuss the Toolpack framework. The General idea is that hToolGroup.showFigureDialog() accepts a figure as input parameter and then displays it, while hToolGroup.showTearOffDialog() accepts a Toolpack panel as input (not hFig as you thought) and then displays it.

      In Matlab releases R2018a or older that do not have the hToolGroup.showFigureDialog() function, you can create it yourself in a separate showFigureDialog.m file. I added a section in the main post that explains how.

  2. Arash Marashian April 17, 2019 at 19:40 Reply

    Hi,
    Dear Yair, Thank you for your information.
    I have a question in “showcaseMPCDesigner.m”, we have a function named “createDialog”, that makes a local popup.
    I want to make sth like that, so it has 10 text-fields with a label and has a callback function.
    At first, I can’t make more than 3 text-fields, and second of all, I can’t make a callback function.

    I’ll be glad if you can help me.

  3. Gebhard Stopper April 30, 2019 at 10:08 Reply

    Hi,
    I really love this mini series! (I’ve been looking for something like this for quite a while)

    I have two questions about the toolstrip:
    1) (How) Is it possible to embed e.g. a Tree control into the DataBrowser
    2) How can I modify to small toolbar in the top right corner of the ToolStrip (e.g. exchange Icons/Buttons).

    Best,
    Gebhard

  4. alain barraud October 2, 2019 at 11:52 Reply

    Hi yair,
    I have tested your miniserie. All works fine with R2019b except some built in demos (as noted by many users) which require older releases.
    You say that toolstrip can be also attached to figure and uifigure. What is the equivalent of
    hToolGroup.addTabGroup(hTabGroup) for these windows container?

    We are all impatient to read the future “part 10”.

    Best regards
    Alain

  5. Menno February 28, 2020 at 15:25 Reply

    Dear Yair,

    As an experienced Matlab user, I have been following your site for quite some time now. With your great series of articles on the Toolstrip, I managed to build a professionally looking app from scratch in an afternoon. Thanks for all the information and tips and tricks; without these it would have been so much more work! As many of your readers, I am really looking forward to Part 10(+).

Leave a Reply
HTML tags such as <b> or <i> are accepted.
Wrap code fragments inside <pre lang="matlab"> tags, like this:
<pre lang="matlab">
a = magic(3);
disp(sum(a))
</pre>
I reserve the right to edit/delete comments (read the site policies).
Not all comments will be answered. You can always email me (altmany at gmail) for private consulting.

Click here to cancel reply.

Useful links
  •  Email Yair Altman
  •  Subscribe to new posts (feed)
  •  Subscribe to new posts (reader)
  •  Subscribe to comments (feed)
 
Accelerating MATLAB Performance book
Recent Posts

Speeding-up builtin Matlab functions – part 3

Improving graphics interactivity

Interesting Matlab puzzle – analysis

Interesting Matlab puzzle

Undocumented plot marker types

Matlab toolstrip – part 9 (popup figures)

Matlab toolstrip – part 8 (galleries)

Matlab toolstrip – part 7 (selection controls)

Matlab toolstrip – part 6 (complex controls)

Matlab toolstrip – part 5 (icons)

Matlab toolstrip – part 4 (control customization)

Reverting axes controls in figure toolbar

Matlab toolstrip – part 3 (basic customization)

Matlab toolstrip – part 2 (ToolGroup App)

Matlab toolstrip – part 1

Categories
  • Desktop (45)
  • Figure window (59)
  • Guest bloggers (65)
  • GUI (165)
  • Handle graphics (84)
  • Hidden property (42)
  • Icons (15)
  • Java (174)
  • Listeners (22)
  • Memory (16)
  • Mex (13)
  • Presumed future risk (394)
    • High risk of breaking in future versions (100)
    • Low risk of breaking in future versions (160)
    • Medium risk of breaking in future versions (136)
  • Public presentation (6)
  • Semi-documented feature (10)
  • Semi-documented function (35)
  • Stock Matlab function (140)
  • Toolbox (10)
  • UI controls (52)
  • Uncategorized (13)
  • Undocumented feature (217)
  • Undocumented function (37)
Tags
ActiveX (6) AppDesigner (9) Callbacks (31) Compiler (10) Desktop (38) Donn Shull (10) Editor (8) Figure (19) FindJObj (27) GUI (141) GUIDE (8) Handle graphics (78) HG2 (34) Hidden property (51) HTML (26) Icons (9) Internal component (39) Java (178) JavaFrame (20) JIDE (19) JMI (8) Listener (17) Malcolm Lidierth (8) MCOS (11) Memory (13) Menubar (9) Mex (14) Optical illusion (11) Performance (78) Profiler (9) Pure Matlab (187) schema (7) schema.class (8) schema.prop (18) Semi-documented feature (6) Semi-documented function (33) Toolbar (14) Toolstrip (13) uicontrol (37) uifigure (8) UIInspect (12) uitools (20) Undocumented feature (187) Undocumented function (37) Undocumented property (20)
Recent Comments
  • Nicholas (6 days 22 hours ago): Hi Yair, Thanks for the reply. I am on Windows 10. I also forgot to mention that this all works wonderfully out of the editor. It only fails once compiled. So, yes, I have tried a...
  • Nicholas (6 days 22 hours ago): Hi Yair, Thanks for the reply. I am on Windows 10. I also forgot to mention that this all works wonderfully out of the editor. It only fails once compiled. So, yes, I have tried a...
  • Yair Altman (7 days 5 hours ago): Nicholas – yes, I used it in a compiled Windows app using R2022b (no update). You didn’t specify the Matlab code location that threw the error so I can’t help...
  • Nicholas (8 days 1 hour ago): Hi Yair, Have you attempted your displayWebPage utility (or the LightweightHelpPanel in general) within a compiled application? It appears to fail in apps derived from both R2022b...
  • João Neves (11 days 6 hours ago): I am on matlab 2021a, this still works: url = struct(struct(struct(struct(hF ig).Controller).PlatformHost). CEF).URL; but the html document is empty. Is there still a way to do...
  • Yair Altman (14 days 5 hours ago): Perhaps the class() function could assist you. Or maybe just wrap different access methods in a try-catch so that if one method fails you could access the data using another...
  • Jeroen Boschma (14 days 7 hours ago): Never mind, the new UI components have an HTML panel available. Works for me…
  • Alexandre (14 days 8 hours ago): Hi, Is there a way to test if data dictionnatry entry are signal, simulink parameters, variables … I need to access their value, but the access method depends on the data...
  • Nicholas (14 days 22 hours ago): In case anyone is looking for more info on the toolbar: I ran into some problems creating a toolbar with the lightweight panel. Previously, the Browser Panel had an addToolbar...
  • Jeroen Boschma (18 days 5 hours ago): I do not seem to get the scrollbars (horizontal…) working in Matlab 2020b. Snippets of init-code (all based on Yair’s snippets on this site) handles.text_explorer...
  • Yair Altman (46 days 7 hours ago): m_map is a mapping tool, not even created by MathWorks and not part of the basic Matlab system. I have no idea why you think that the customizations to the builtin bar function...
  • chengji chen (46 days 14 hours ago): Hi, I have tried the method, but it didn’t work. I plot figure by m_map toolbox, the xticklabel will add to the yticklabel at the left-down corner, so I want to move down...
  • Yair Altman (54 days 7 hours ago): @Alexander – this is correct. Matlab stopped including sqlite4java in R2021b (it was still included in 21a). You can download the open-source sqlite4java project from...
  • Alexander Eder (60 days 2 hours ago): Unfortunately Matlab stopped shipping sqlite4java starting with R2021(b?)
  • K (66 days 13 hours ago): Is there a way to programmatically manage which figure gets placed where? Let’s say I have 5 figures docked, and I split it into 2 x 1, I want to place 3 specific figures on the...
Contact us
Captcha image for Custom Contact Forms plugin. You must type the numbers shown in the image
Undocumented Matlab © 2009 - Yair Altman
This website and Octahedron Ltd. are not affiliated with The MathWorks Inc.; MATLAB® is a registered trademark of The MathWorks Inc.
Scroll to top