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 3 (basic customization)

December 16, 2018 21 Comments

In the previous post I showed how we can create custom Matlab apps. In such apps, the toolstrip is very often an important part. Today I continue my miniseries on toolstrips. Toolstrips can be a bit complex so I’m trying to proceed slowly, with each post in the miniseries building on the previous posts. So I encourage you to review the earlier posts in the miniseries (part1, part2) before reading this post.
A Matlab toolstrip is composed of a hierarchy of user-interface objects as follows (all objects are classes within the matlab.ui.internal.toolstrip package):

Anatomy of a Matlab app with toolstrip
Anatomy of a Matlab app with toolstrip

  • TabGroup
    • Tab
      • Section
        • Column
          • Component
          • Component
          • …
        • Column
        • …
      • Section
      • …
    • Tab
    • …
  • TabGroup
  • …

In this post I explain how we can create a custom toolstrip that contains tabs, sections, and basic controls that interact with the user and the docked figures. The following posts will show more advanced customizations and more complex controls, as well as showing alternative ways of creating the toolstrip.

1. Creating a bare toolstrip and new tabs

We start with a new ToolGroup that has a bare toolstrip and a docked figure (for details and explanations refer to the previous post):

% Create a new ToolGroup ("app") with a hidden DataBrowser
hToolGroup = matlab.ui.internal.desktop.ToolGroup('Toolstrip example on UndocumentedMatlab.com');
hToolGroup.disableDataBrowser();
hToolGroup.open();  % this may be postponed further down for improved performance
% Store toolgroup reference handle so that app will stay in memory
jToolGroup = hToolGroup.Peer;
internal.setJavaCustomData(jToolGroup, hToolGroup);
% Create two figures and dock them into the ToolGroup
hFig1 = figure('Name','3D');  surf(peaks);
hToolGroup.addFigure(hFig1);

% Create a new ToolGroup ("app") with a hidden DataBrowser hToolGroup = matlab.ui.internal.desktop.ToolGroup('Toolstrip example on UndocumentedMatlab.com'); hToolGroup.disableDataBrowser(); hToolGroup.open(); % this may be postponed further down for improved performance % Store toolgroup reference handle so that app will stay in memory jToolGroup = hToolGroup.Peer; internal.setJavaCustomData(jToolGroup, hToolGroup); % Create two figures and dock them into the ToolGroup hFig1 = figure('Name','3D'); surf(peaks); hToolGroup.addFigure(hFig1);

We now create a new TabGroup and and it to our ToolGroup:

import matlab.ui.internal.toolstrip.*  % for convenience below
hTabGroup = TabGroup();
hToolGroup.addTabGroup(hTabGroup);

import matlab.ui.internal.toolstrip.* % for convenience below hTabGroup = TabGroup(); hToolGroup.addTabGroup(hTabGroup);

We can add a new Tab to the TabGroup using either of two methods:

  1. Create a new Tab object and then use TabGroup.add(hTab,index) to add it to a parent TabGroup. The index argument is optional – if specified the section is inserted at that index location; if not, it is added at the end of the tab-group. Sample usage:
    hTab = Tab('Data');
    hTabGroup.add(hTab);  % add to tab as the last section
    hTabGroup.add(hTab,3);  % add to tab as the 3rd section

    hTab = Tab('Data'); hTabGroup.add(hTab); % add to tab as the last section hTabGroup.add(hTab,3); % add to tab as the 3rd section

  2. Call TabGroup.addTab(title). This creates a new tab with the specified title (default: ”) and adds it at the end of the tab-group. The new tab’s handle is returned by the function. Sample usage:
    hTabGroup.addTab('Data');  % add to tab-group as the last tab

    hTabGroup.addTab('Data'); % add to tab-group as the last tab

This creates an empty “Data” tab in our app toolstrip. Note that the tab title is capitalized (“DATA”), despite the fact that we set its Title property to 'Data'. Also note that while the tab’s Title property can be updated after the tab is created, in practice the tab title does not seem to change.

New (empty) toolstrip tab

Lastly, note that a “VIEW” tab is automatically added to our toolstrip. As explained in the previous post, we can remove it using hToolGroup.hideViewTab; (refer to the previous post for details).

2. Adding sections to a toolstrip tab

Each toolstrip Tab is composed of Sections, that holds the actual components. We cannot add components directly to a Tab: they have to be contained within a Section. A toolstrip Tab can only contain Sections as direct children.
We can add a new section to a Tab using either of two methods, in a similar way to the that way we added a new tab above:

  1. Create a new Section object and then use Tab.add(hSection,index) to add it to a parent Tab. The index argument is optional – if specified the section is inserted at that index location; if not, it is added at the end of the tab. Sample usage:
    hSection = Section('Section title');
    hTab.add(hSection);  % add to tab as the last section
    hTab.add(hSection,3);  % add to tab as the 3rd section

    hSection = Section('Section title'); hTab.add(hSection); % add to tab as the last section hTab.add(hSection,3); % add to tab as the 3rd section

  2. Call Tab.addSection(title). This creates a new section with the specified title (default: ”) and adds it at the end of the tab. The new section’s handle is returned by the function. Sample usage:
    hTab.addSection('Section title');  % add to tab as the last section

    hTab.addSection('Section title'); % add to tab as the last section

Note that the help section for Tab.addSection() indicates that it’s possible to specify 2 string input args (presumably Title and Tag), but this is in fact wrong and causes a run-time error, since Section constructor only accepts a single argument (Title), at least as of R2018b.
The Section‘s Title property can be set both in the constructor, as well as updated later. In addition, we can also set the Tag and CollapsePriority properties after the section object is created (these properties cannot be set in the constructor call):

hSection.Title = 'New title';    % can also be set in constructor call
hSection.Tag = 'section #1';     % cannot be set in constructor call
hSection.CollapsePriority = 10;  % cannot be set in constructor call

hSection.Title = 'New title'; % can also be set in constructor call hSection.Tag = 'section #1'; % cannot be set in constructor call hSection.CollapsePriority = 10; % cannot be set in constructor call

The CollapsePriority property is responsible for controlling the order in which sections and their internal components collapse into a drop-down when the window is resized to a smaller width.
Like tabs, section titles also appear capitalized. However, unlike the section titles can indeed be modified in run-time.

3. Adding columns to a tab section

Each Section in a toolstrip Tab is composed of Columns, and each Column can contain 1-3 Components. This is a very effective layout for toolstrip controls that answers the vast majority of use-cases. In some special cases we might need more flexibility with the component layout within a Tab – I will explain this in a future post. But for now let’s stick to the standard Tab-Section-Column-Component framework.
We can add columns to a section using (guess what?) either of two methods, as above:

  1. Create a new Column object and then use Section.add(hColumn,index) to add it to a parent Section. The index argument is optional – if specified the column is inserted at that index location; if not, it is added at the end of the section. Sample usage:
    hColumn = Column('HorizontalAlignment','center', 'Width',150);
    hSection.add(hColumn);  % add to section as the last column
    hSection.add(hColumn,3);  % add to section as the 3rd column

    hColumn = Column('HorizontalAlignment','center', 'Width',150); hSection.add(hColumn); % add to section as the last column hSection.add(hColumn,3); % add to section as the 3rd column

  2. Call Tab.addSection(title). This creates a new section with the specified title (default: ”) and adds it at the end of the tab. The new section’s handle is returned by the function. Sample usage:
    hSection.addColumn('HorizontalAlignment','center', 'Width',150);  % add to section as the last column

    hSection.addColumn('HorizontalAlignment','center', 'Width',150); % add to section as the last column

We can set the Column‘s HorizontalAlignment and Width properties only in the constructor call, not later via direct assignments. In contrast, the Tag property cannot be set in the constructor, only via direct assignment:

hColumn.HorizontalAlignment = 'right';  % error: can only be set via constructor call: Column('HorizontalAlignment','right', ...)
hColumn.Width = 150;                    % error: can only be set via constructor call: Column('Width',150, ...)
hColumn.Tag = 'column #2';              % ok: cannot be set via the constructor call!

hColumn.HorizontalAlignment = 'right'; % error: can only be set via constructor call: Column('HorizontalAlignment','right', ...) hColumn.Width = 150; % error: can only be set via constructor call: Column('Width',150, ...) hColumn.Tag = 'column #2'; % ok: cannot be set via the constructor call!

This is indeed confusing and non-intuitive. Perhaps this is part of the reason that the toolstrip API is still not considered stable enough for a general documented release.

4. Adding controls to a section column

Each section column contains 1 or more Components. These can be push/toggle/split/radio buttons, checkboxes, drop-downs, sliders, spinners, lists etc. Take a look at matlabroot%/toolbox/matlab/toolstrip/+matlab/+ui/+internal/+toolstrip/ for a full list of available controls. I’ll discuss a few basic controls in this post, and more complex ones in future posts.
As above, there are two methods for adding components to a section column, but they have different purposes:

  1. Column.addEmptyControl() adds a filler space in the next position of the column. This is used to display the colorbar control at the center of the column in the usage snippet below.
  2. Create a new Component object and then use Column.add(hComponent, index) to add it to a parent Column. The index argument is optional – if specified the component is inserted at that index location; if not, it is added at the end of the column. Sample usage:
    hButton = Button('Click me!');
    hColumn.add(hButton);  % add to column as the last component
    hColumn.add(hButton,3);  % add to column as the 3rd component

    hButton = Button('Click me!'); hColumn.add(hButton); % add to column as the last component hColumn.add(hButton,3); % add to column as the 3rd component

Component objects (matlab.ui.internal.toolstrip.base.Component, which all usable toolstrip controls inherit) have several common properties. Leaving aside the more complex components for now, most usable controls include the following properties:

  • Text – text label, displayed next to the control icon (pity that MathWorks didn’t call this property String or Label, in line with uicontrols/menu-items)
  • Description – tooltip, displayed when hovering the mouse over the control (pity that MathWorks didn’t call this property Tooltip in line with uicontrols/menu-items)
  • Tag – a string, as all other Matlab HG objects. Controls are searchable by their Tag via their container’s find(tag) and findAll(tag) methods (again, I don’t quite understand why not use findobj and findall as with the rest of Matlab HG…).
  • Enabled – a logical value (true/false), true by default
  • Icon – the icon used next to the Text label. We can use the Icon constructor (that expects the full path of a PNG/JPG file), or one of its static icons (e.g. Icon.REFRESH_16). Icons will be discussed in detail in the following post; in the meantime you can see various usage examples below.

Each control also has one or more callbacks that can be specified, as settable properties and/or as events that can be listened-to using the addlistener function. This too will be discussed in detail in the next post, but in the meantime you can see various usage examples below.
Columns can have 1-3 components:

  • If only 1 component is specified, it is allocated the full column height, effectively creating a large control, with the Icon on top (typically a 24×24 icon) and the Text label beneath.
  • If 2 or 3 components are specified, then smaller controls are displayed, with the Text label to the right of the Icon (typically 16×16), and the controls evenly spaced within the column.
  • If you try to add more than 3 components to a Column, you’ll get a run-time error.

5. Usage example

Here is a short usage example showing the above concepts. The code is not pretty by any means – I intentionally wanted to display multiple different ways of adding components, specifying properties and callbacks etc. It is meant merely as an educational tool, and is not close to being ready for production code. So please don’t complain about the known fact that the code is ugly, non-robust, and in general exhibits bad programming practices. The complete runnable code can be downloaded here.
The following code snippets assume that you have already ran the code in paragraph 1 above:

Push-buttons section (3 columns)
Toolstrip example (basic controls)
Toolstrip example (basic controls)
section1 = hTab.addSection('Push buttons');
column1a = section1.addColumn();
icon = Icon.REFRESH_24; % built-in: see Icon.showStandardIcons()
button = Button('Refresh all',icon);
button.Description = 'Refresh the charted data - all axes';
button.ButtonPushedFcn = @refreshAllData;
column1a.add(button);
function refreshAllData(hAction,hEventData)
    hAxes = gca;
    hChildren = hAxes.Children;
    for idx = 1 : numel(hChildren)
        hChild = hChildren(idx);
        hChild.XData = -hChild.XData;
        hChild.YData = -hChild.YData;
        hChild.ZData = -hChild.ZData;
    end
end
column1b = section1.addColumn();
addRefresh2Button('X','Y');
addRefresh2Button('Y','Z');
function addRefresh2Button(type1, type2)
    import matlab.ui.internal.toolstrip.*
    hButton = Button(['Refresh ' type1 ',' type2], Icon.RESTORE_16);
    hButton.Description = ['Refresh the charted data - ' type1 ',' type2 ' axes'];
    hButton.ButtonPushedFcn = {@refres2AxisData, type1, type2};
    column1b.add(hButton);
    function refres2AxisData(~,~,type1,type2)
        hAxes = gca;
        hChildren = hAxes.Children;
        for idx = 1 : numel(hChildren)
            hChild = hChildren(idx);
            hChild.([type1 'Data']) = -hChild.([type1 'Data']);
            hChild.([type2 'Data']) = -hChild.([type2 'Data']);
        end
    end
end
column1c = section1.addColumn();
addRefresh1Button('X');
addRefresh1Button('Y');
addRefresh1Button('Z');
function addRefresh1Button(type)
    import matlab.ui.internal.toolstrip.*
    hButton = Button(['Refresh ' type], Icon.REDO_16);
    hButton.Description = ['Refresh the charted data - ' type ' axes'];
    addlistener(hButton, 'ButtonPushed', @refres1AxisData);  % {} not supported!
    column1c.add(hButton);
    function refres1AxisData(h,e)
        hAxes = gca;
        hChildren = hAxes.Children;
        for idx = 1 : numel(hChildren)
            hChild = hChildren(idx);
            hChild.([type 'Data']) = -hChild.([type 'Data']);
        end
    end
end

section1 = hTab.addSection('Push buttons'); column1a = section1.addColumn(); icon = Icon.REFRESH_24; % built-in: see Icon.showStandardIcons() button = Button('Refresh all',icon); button.Description = 'Refresh the charted data - all axes'; button.ButtonPushedFcn = @refreshAllData; column1a.add(button); function refreshAllData(hAction,hEventData) hAxes = gca; hChildren = hAxes.Children; for idx = 1 : numel(hChildren) hChild = hChildren(idx); hChild.XData = -hChild.XData; hChild.YData = -hChild.YData; hChild.ZData = -hChild.ZData; end end column1b = section1.addColumn(); addRefresh2Button('X','Y'); addRefresh2Button('Y','Z'); function addRefresh2Button(type1, type2) import matlab.ui.internal.toolstrip.* hButton = Button(['Refresh ' type1 ',' type2], Icon.RESTORE_16); hButton.Description = ['Refresh the charted data - ' type1 ',' type2 ' axes']; hButton.ButtonPushedFcn = {@refres2AxisData, type1, type2}; column1b.add(hButton); function refres2AxisData(~,~,type1,type2) hAxes = gca; hChildren = hAxes.Children; for idx = 1 : numel(hChildren) hChild = hChildren(idx); hChild.([type1 'Data']) = -hChild.([type1 'Data']); hChild.([type2 'Data']) = -hChild.([type2 'Data']); end end end column1c = section1.addColumn(); addRefresh1Button('X'); addRefresh1Button('Y'); addRefresh1Button('Z'); function addRefresh1Button(type) import matlab.ui.internal.toolstrip.* hButton = Button(['Refresh ' type], Icon.REDO_16); hButton.Description = ['Refresh the charted data - ' type ' axes']; addlistener(hButton, 'ButtonPushed', @refres1AxisData); % {} not supported! column1c.add(hButton); function refres1AxisData(h,e) hAxes = gca; hChildren = hAxes.Children; for idx = 1 : numel(hChildren) hChild = hChildren(idx); hChild.([type 'Data']) = -hChild.([type 'Data']); end end end

Toggle buttons section (2 columns)
section2 = hTab.addSection('Toggle buttons');
section2.CollapsePriority = 2;
column1 = Column();
section2.add(column1);
%icon = Icon.LEGEND_24;
icon = Icon(fullfile(matlabroot,'toolbox','shared','controllib','general','resources','toolstrip_icons','Legend_24.png')); % PNG/JPG image file (not GIF!)
button = ToggleButton('Legend',icon);
button.Description = 'Toggle legend display';
addlistener(button, 'ValueChanged', @(h,e)legend('toggle'));
column1.add(button);
column2 = section2.addColumn();
imagefile = fullfile(matlabroot,'toolbox','matlab','icons','tool_colorbar.png');
jIcon = javax.swing.ImageIcon(imagefile); % Java ImageIcon from file (inc. GIF)
%jIcon = javax.swing.ImageIcon(jIcon.getImage.getScaledInstance(24,24,jIcon.getImage.SCALE_SMOOTH))  % Resize icon to 24x24
icon = Icon(jIcon);
button = ToggleButton('Colorbar',icon);
button.Description = 'Toggle colorbar display';
button.ValueChangedFcn = @toggleColorbar;
column2.addEmptyControl();
column2.add(button);
column2.addEmptyControl();
function toggleColorbar(hAction,hEventData)
    if hAction.Selected
        colorbar;
    else
        colorbar('off');
    end
end

section2 = hTab.addSection('Toggle buttons'); section2.CollapsePriority = 2; column1 = Column(); section2.add(column1); %icon = Icon.LEGEND_24; icon = Icon(fullfile(matlabroot,'toolbox','shared','controllib','general','resources','toolstrip_icons','Legend_24.png')); % PNG/JPG image file (not GIF!) button = ToggleButton('Legend',icon); button.Description = 'Toggle legend display'; addlistener(button, 'ValueChanged', @(h,e)legend('toggle')); column1.add(button); column2 = section2.addColumn(); imagefile = fullfile(matlabroot,'toolbox','matlab','icons','tool_colorbar.png'); jIcon = javax.swing.ImageIcon(imagefile); % Java ImageIcon from file (inc. GIF) %jIcon = javax.swing.ImageIcon(jIcon.getImage.getScaledInstance(24,24,jIcon.getImage.SCALE_SMOOTH)) % Resize icon to 24x24 icon = Icon(jIcon); button = ToggleButton('Colorbar',icon); button.Description = 'Toggle colorbar display'; button.ValueChangedFcn = @toggleColorbar; column2.addEmptyControl(); column2.add(button); column2.addEmptyControl(); function toggleColorbar(hAction,hEventData) if hAction.Selected colorbar; else colorbar('off'); end end

Checkboxes section (1 column 150px-wide), placed after the push-buttons section
section3 = Section('Checkboxes');
section3.CollapsePriority = 1;
hTab.add(section3, 2);
column3 = section3.addColumn('HorizontalAlignment','left', 'Width',150);
button = CheckBox('Axes borders', true);
button.ValueChangedFcn = @toggleAxes;
button.Description = 'Axes borders';
column3.add(button);
function toggleAxes(hAction,hEventData)
    if hAction.Selected
        set(gca,'Visible','on');
    else
        set(gca,'Visible','off');
    end
end
button = CheckBox('Log scaling', false);
button.addlistener('ValueChanged',@toggleLogY);
button.Description = 'Log scaling';
column3.add(button);
function toggleLogY(hCheckbox,hEventData)
    if hCheckbox.Value, type = 'log'; else, type = 'linear'; end
    set(gca, 'XScale',type, 'YScale',type, 'ZScale',type);
end
button = CheckBox('Inverted Y', false);
button.addlistener('ValueChanged',@toggleInvY);
button.Description = 'Invert Y axis';
column3.add(button);
function toggleInvY(hCheckbox,~)
    if hCheckbox.Value, type = 'reverse'; else, type = 'normal'; end
    set(gca, 'YDir',type);
end

section3 = Section('Checkboxes'); section3.CollapsePriority = 1; hTab.add(section3, 2); column3 = section3.addColumn('HorizontalAlignment','left', 'Width',150); button = CheckBox('Axes borders', true); button.ValueChangedFcn = @toggleAxes; button.Description = 'Axes borders'; column3.add(button); function toggleAxes(hAction,hEventData) if hAction.Selected set(gca,'Visible','on'); else set(gca,'Visible','off'); end end button = CheckBox('Log scaling', false); button.addlistener('ValueChanged',@toggleLogY); button.Description = 'Log scaling'; column3.add(button); function toggleLogY(hCheckbox,hEventData) if hCheckbox.Value, type = 'log'; else, type = 'linear'; end set(gca, 'XScale',type, 'YScale',type, 'ZScale',type); end button = CheckBox('Inverted Y', false); button.addlistener('ValueChanged',@toggleInvY); button.Description = 'Invert Y axis'; column3.add(button); function toggleInvY(hCheckbox,~) if hCheckbox.Value, type = 'reverse'; else, type = 'normal'; end set(gca, 'YDir',type); end

Summary

Creating a custom app toolstrip requires careful planning of the tabs, sections, controls and their layout, as well as preparation of the icons, labels and callbacks. Once you start playing with the toolstrip API, you’ll see that it’s quite easy to understand and to use. I think MathWorks did a good job in general with this API, and it’s a pity that they did not make it public or official long ago (the MCOS API discussed above existed since 2014-2015; earlier versions existed at least as far back as 2011). Comparing the changes made in the API between R2018a and R2018b shows quite minor differences, which may possibly means that the API is now considered stable, and therefore that it might well be made public in some near-term future. Still, note that this API may well change in future releases (for example, naming of the control properties that I mentioned above). It works well in R2018b, as well as in the past several Matlab releases, but this could well change in the future, so beware.
In the following posts I will discuss advanced control customizations (icons, callbacks, collapsibility etc.), complex controls (drop-downs, pop-ups, lists, button groups, items gallery etc.) and low-level toolstrip creation and customization. As I said above, Matlab toolstrips are quite an extensive subject and so I plan to proceed slowly, with each post building on its predecessors. Stay tuned!
In the meantime, 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 8 (galleries) – Matlab toolstrips can contain customizable gallery panels of items. ...
  3. Matlab toolstrip – part 5 (icons) – Icons can be specified in various ways for toolstrip controls and the app window itself. ...
  4. Matlab toolstrip – part 6 (complex controls) – Multiple types of customizable controls can be added to Matlab toolstrips...
  5. Matlab toolstrip – part 7 (selection controls) – Matlab toolstrips can contain a wide variety of selection controls: popups, combo-boxes, and galleries. ...
  6. Matlab toolstrip – part 9 (popup figures) – Custom popup figures can be attached to Matlab GUI toolstrip controls. ...
Figure GUI Toolstrip Undocumented feature
Print Print
« Previous
Next »
21 Responses
  1. CWC December 17, 2018 at 04:23 Reply

    Is it possible to change the background color of the toolstrip?
    The gradient metal color has lower contrast (black on dark gray) than the traditional menu bar,
    It is more difficult for me to read the text.

  2. Ramiro Massol December 18, 2018 at 12:24 Reply

    hi Yair,
    first of all, thanks a lot for all the detailed and useful info you wrote about toolstrips. Are you planning to explain how to add and customize toolstrips for figures created with GUIDE?

    best
    Ramiro

    • Yair Altman December 18, 2018 at 13:11 Reply

      I plan to discuss this in a future post

      • Ramiro Massol December 18, 2018 at 16:21

        great. By the way, I tried the code you posted in section 2 of the toolstrips and noticed an error while trying to create a section (“% “Section” cannot be added to “Tab” after toolstrip is rendered.”). This happens all the time when i tried to add a section regardless of the 2 methods you described above. What’s causing this behavior? best

      • Yair Altman December 18, 2018 at 16:56

        As the error says, you can’t update a toolstrip after it has been rendered (shown). Simply move the hToolGroup.open() command to the end of your script/function.

      • Ramiro Massol December 18, 2018 at 19:13

        hi Yair, I tried that before but i’ve got a weird toolgroup that changed the name and showed no toolstrip at all and was docked to the command window too. I can send you the picture of it if you want. If i open the toolgroup at the start everything looks fine but i can’t add a section.
        best

      • Yair Altman December 18, 2018 at 19:24

        Ramiro – I’m sorry, but I only do private consulting projects as (well) private consulting projects…
        Try to display the tool-group at other places within your code, before the end.

      • Ramiro Massol December 18, 2018 at 20:17

        hi Yair,
        i was just trying to reproduce the code you freely publish on your site to test the features of the toolstrip. I guess other readers of your blog will encounter the same issue and I thought you should be aware of it. I’ve already tried opening the toolgroup at other instances with the same effect.

      • Yair Altman December 18, 2018 at 21:21

        I added a downloadable file that can be run as-is, at the top of the Usage Examples section.

      • Ramiro Massol December 20, 2018 at 21:10

        hi Yair, thanks for the file you uploaded to the usage examples section.
        Happy New Year! best

  3. chen wang January 14, 2019 at 17:20 Reply

    hi Yair,
    thx so much for this post.
    i have a question: is it possible to manully set an openiong Position or Size for this toolgroup?
    i have tried all day and i can not find any Container, which has the ‘position’ properties or something alike.

    best regards

    • Yair Altman January 14, 2019 at 17:43 Reply

      @Chen – I will discuss positioning and layout in a future post, but for now you can adapt the following script. Note that the positioning uses Java-based coordinates, which is (0,0) at the top-left corner of the screen, and increases downward and to the right, and the position is for the tool-group’s top-left corner. So, position (100,200,800,600) means a 800×600 window whose top-left corner is 100 pixels to the right, and 200 pixels below, the screen’s top-left corner.

      % Alternative #1:
      hToolGroup = matlab.ui.internal.desktop.ToolGroup();
      hToolGroup.setPosition(100, 200, 800, 600);  % x,y,width,height
       
      % Alternative #2:
      jToolGroup = hToolGroup.Peer;
      jPosition = com.mathworks.widgets.desk.DTLocation.createExternal(uint16(100),uint16(200),uint16(800),uint16(600));
      jToolGroup.setPosition(jPosition);

      % Alternative #1: hToolGroup = matlab.ui.internal.desktop.ToolGroup(); hToolGroup.setPosition(100, 200, 800, 600); % x,y,width,height % Alternative #2: jToolGroup = hToolGroup.Peer; jPosition = com.mathworks.widgets.desk.DTLocation.createExternal(uint16(100),uint16(200),uint16(800),uint16(600)); jToolGroup.setPosition(jPosition);

      • Chen Wang January 15, 2019 at 09:59

        Hi Yair,
        thx for your answer 🙂
        i have tried with your suggestion:

        hTG = matlab.ui.internal.desktop.ToolGroup('A Test');
        hTG.open();
        hTG.disableDataBrowser();
        jTG = hTG.Peer;
        jPos = com.mathworks.widgets.desk.DTLocation.createExternal(uint16(100), uint16(200), uint16(300), uint16(400));
        jTG.setPosition(jPos);

        hTG = matlab.ui.internal.desktop.ToolGroup('A Test'); hTG.open(); hTG.disableDataBrowser(); jTG = hTG.Peer; jPos = com.mathworks.widgets.desk.DTLocation.createExternal(uint16(100), uint16(200), uint16(300), uint16(400)); jTG.setPosition(jPos);

        but i got error:

        Undefined function or variable 'setPosition'.

        Undefined function or variable 'setPosition'.

        PS: i’m using Matlab 2016b.

      • Yair Altman January 15, 2019 at 10:30

        @Chen – 16b is a relatively old release (19a is 5 releases ahead). It is quite possible that the setPosition method was added in one of these later releases. I have not investigated this but it’s possible that there may have been an alternative method in 16b (e.g. setLocation or whatever). You can run methodview(hTG) to check the possibilities, or upgrade to a later Matlab release.

      • Chen Wang January 15, 2019 at 17:12

        Thx a lot.
        i think, it is probably impossible in 16b to set an opening size. i haven’t found any available function 🙁
        but this is not that bad, in 16b the most new futures of toolgroup still work and till now they are enough for me.

        Thx u again for ur post 🙂

      • Collin Pecora January 16, 2019 at 02:50

        Chen

        I don’t believe the R2016b version has any methods to set position

        You can do it through the desktop:

        jDesktop = com.mathworks.mlservices.MatlabDesktopServices.getDesktop;
        jPos = com.mathworks.widgets.desk.DTLocation.createExternal(uint16(100), uint16(200), uint16(300), uint16(400));
        jDesktop.setGroupLocation('A Test', jPos);

        jDesktop = com.mathworks.mlservices.MatlabDesktopServices.getDesktop; jPos = com.mathworks.widgets.desk.DTLocation.createExternal(uint16(100), uint16(200), uint16(300), uint16(400)); jDesktop.setGroupLocation('A Test', jPos);

        Collin

      • Chen Wang January 16, 2019 at 10:57

        Thx so much, Collin.
        This works 😀

  4. Arash Marashian March 27, 2019 at 00:04 Reply

    Hi, I have a question, can I use something like “handles”, that we have in GUI?

    • Yair Altman March 27, 2019 at 00:14 Reply

      @Arash – the “handles” that you refer to is a simple Matlab struct that contains the GUI handles in separate fields. You can easily create it in your code by assigning each created GUI object (tab, section, column, button etc.) a separate field in the struct, and in the end saving this struct somewhere. You cannot use guidata or guihandles because they only work with figures (not apps), but you can store the handles struct elsewhere e.g. in a global variable, or attached to one of the figures that you dock into your app.

  5. Endri K. April 10, 2019 at 00:36 Reply

    Hi Yair,

    Thank you for all your great posts. They’re all extremely helpful. Could you please help me with an issue I’m facing? I’ve built an application with a ToolGroup and when using the Matlab Application Compiler, in the compiled standalone version, I cannot get hToolGroup.addFigure to dock a new figure in the existing ToolGroup window. I have tried a number of approaches and have been unsuccessful. For this application I am currently using Matlab 2017b.

    Thank you,
    Endri

    • Yair Altman June 16, 2019 at 18:26 Reply

      Unfortunately, docking figures into ToolGroups is for some unknown reason (apparently deliberately) prevented by the Matlab Compiler. I am not aware of any workaround for this, at the moment.

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 8 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 3 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