File Exchange

image thumbnail

GUI Layout Toolbox

version 2.3.1 (774 KB) by

Layout manager for MATLAB graphical user interfaces

4.95588
110 Ratings

847 Downloads

Updated

View License

Editor's Note: This file was selected as MATLAB Central Pick of the Week

This toolbox provides tools to create sophisticated MATLAB graphical user interfaces that resize gracefully. The classes supplied can be used in combination to produce virtually any user interface layout.
* Arrange MATLAB user interface components horizontally, vertically or in grids
* Mix fixed- and variable-size components
* Resize components interactively by dragging dividers
* Show and hide components using tabs and panels
* Show part of a large component in a scrollable panel

This toolbox was developed by David Sampson and Ben Tordoff from the [Consulting Services](http://www.mathworks.com/services/consulting/) group at MathWorks.

This version is for MATLAB release R2014b onwards. There is also a [version] (http://uk.mathworks.com/matlabcentral/fileexchange/27758-gui-layout-toolbox) for earlier releases of MATLAB.

Comments and Ratings (346)

Additional information to my previous post: I got the error with Matlab R2017b. No errors when the program is compiled with Matlab R2016b

Dear David, Thank you very much for the great work.

I have the following error when i run the compiled (executable) file:
Assertion failed: find: no active context for type 'class MathWorks::ErrorRecovery::ErrorRecoveryHandlers'

See the following for details on updating unit/package tests to work with the USM.
http://inside.mathworks.com/wiki/USM_migration_17a_list#Updating_unit_tests_to_work_with_the_USM
Function: foundation::usm::Detail<struct foundation::usm::scope::Mvm>::find, file b:\matlab\foundation\usm\management.cpp, line 559

Can you please direct me to what might be causing this error and how i can sort it out?

Thanks.

David Sampson

David Sampson (view profile)

Neelakanthu, at present, you cannot use GUI Layout Toolbox with App Designer. We are working on incorporating layout management features along the lines of GUI Layout Toolbox with the Javascript-based ("new") graphics used by App Designer, for both interactive and programmatic workflows.

Until then, I have also been working on porting GUI Layout Toolbox to work with new graphics. If there is interest in the user community then I could consider making that available. Compared to the Java-based graphics, mouse events are not yet exposed, so no draggable dividers. Also, some performance optimizations that are present in Java-based graphics are not yet implemented in Javascript-based.

Hi David Sampson ... How can use this toolbox with Appdesigner. Is it possible?

Hi David - Thank you very much. I hope I have send you a message with the information now :-)

David Sampson

David Sampson (view profile)

Kasper, we had some reports of this problem earlier, and made some changes to address it. Specifically, the issues were on Mac with Retina displays. I don't recall if there was any variation with MATLAB version.

Can you please get in touch with me directly via the "contact" button on my File Exchange profile page, with details of: OS, MATLAB version, toolbox version, and display settings.

Works very well. One question in relation to the BoxPanel title property. In the following example the upper box panel will have a title displaying "T...." and the lower will have a title displaying "Test ...". Why is the whole title not displayed, even when there is enough space for it?
f = figure, vb = uix.VBox('parent',f), uix.BoxPanel('Parent',vb,'title','Test'), uix.BoxPanel('Parent',vb,'title','Test Bla')

Sebastian

Great work! Thanks!

David Sampson

David Sampson (view profile)

Matt, are your axes with legend inside a uicontainer, as per section 2.3 "colorbars and legends" of the GUI Layout Toolbox documentation?

Matt

Matt (view profile)

Love the toolbox. Has anyone else had a problem with putting a legend on an axes while using this. I get -

Warning: Error updating Legend.

Attempt to modify the tree during an update traversal
I do not get this error when adding a legend to an axes within a figure outside of the gui.

felinsinap

felinsinap

That's an absolut nice toolbox. It is possible to implement a solution that the 'Padding' property could also allow a vector of size 1x4 to use it like [left right above below] and if the padding is scalar, all values inside the vector will be equal to that value?

David Taylor

Thanks David, I appreciate your continuing support of this toolbox. Your suggestion was one of the versions I trialled but in the end I went with assigning a uicontainer to each element of my uix.Grid objects and then assigning the axes to each uicontainer. (I believe this was suggested a few comments down). I wanted to continue to use the uix.Grid object as it offers a lot in terms of layout and expansion (i.e. if there are suddenly 10 quantities to plot instead of 6) and I really want to maximise the size of the data on the screen which can be a bit fiddly with subplots . (Hence why I looked into "subplotplus"). My code is now similar in form to this:

x = 0:0.1:10; % some data

f = figure(); % initialise figure
g = uix.Grid('Parent', f); % create uix.Grid object
u = gobjects(1, 6); % preallocate variable for uicontainers
for iG = 1 : 6 % loop through number of quantities and create an axes for each quantity
u(iG) = uicontainer('parent', g, 'Units', 'normalized', 'Position', [0 0 1 1]);
axes(u(iG))
plot(x, sin(iG.*x)) % plot data
legend(sprintf('y = sin(%ix)', iG)) % add legend
end
set(g, 'Widths', [-1 -1 -1], 'Heights', [-1 -1]); % set uix.Grid formatting

Christophe

David, thank you for your reply. I have two boxplots in a VBoxFlex object. On one of the boxplot, I have an axes, I would like to detect when the divider moved because I want to change the axes limits (XLim and YLim) according to the height of the boxplot.

Hi David,

On the topic of dividers, I would also have liked to have an event for "divider moved". The purpose is to remember the position of the dividers after they have been moved by the user, so the GUI can be re-opened with the same layout. To do that at the moment I wait for the objects to be deleted (Gui being closed) and save the widths/heights at this point.

David Sampson

David Sampson (view profile)

Chris, for simple cases, you can use subplot within a standard uipanel, and in turn, put that panel inside a GUI Layout Toolbox container. For example:

f = figure();
b = uix.HBoxFlex( 'Parent', f, 'Padding', 10, 'Spacing', 10 );
p = uipanel( 'Parent', b, 'Title', 'My Panel', ...
'Units', 'normalized', 'Position', [0.1 0.1 0.8 0.8] );
x = 0:0.1:10; % some data
a11 = subplot( 2, 2, 1, 'Parent', p );
plot( a11, x, sin( x ), 'b-' )
legend( a11, 'blue' )
a12 = subplot( 2, 2, 2, 'Parent', p );
plot( a12, x, cos( x ), 'r--' )
title( a12, 'No legend' ) % but title
a21 = subplot( 2, 2, 4, 'Parent', p );
peaks();
legend( a21, 'peaks', 'Location', 'northeast' )
a22 = subplot( 2, 2, 3, 'Parent', p );
plot( a22, x, tan( x ), 'g-.' )
legend( a22, 'green' )
c = uicontrol( 'Parent', b, 'FontSize', 50, 'String', 'Push!' );
b.Widths(2) = 300;

Let me know if that meets your needs.

David Sampson

David Sampson (view profile)

Christophe, no there is not a callback for mouse over divider, divider moving, or divider moved. It would be helpful to understand what specifically you are looking to do, and whether it is modifying or augmenting the current behavior.

Christophe

David, great toolbox. I have been using the toolbox for a while now and I would like to know if there is a callback function for the divider ? I would like to run a function when the user clicks on the divider. If there is no callback, how can I easily know if the pointer is on top of the divider ?

David, thank you for an excellent file submission. This package was recommended to me by one of your consultants Philip Rottier and I must say it is very easy to use and very well documented.

My one concern is the difficulty with adding legends to axes inside some of the uix objects. Currently, I am trying to create a 2x3 grid of axes using the uix.Grid object and would like to assign a legend to each axes, however, when I do this I end up with 12 objects in total (6 axes and 6 legends).

I had some limited success with assigning 6 uix.Panels to the uix.Grid object and then embedding the axes and legend inside a uix.HBox/uix.VBox but the formatting is not as clean as a simple MatLab axes/plot/legend sequence. My current fix is to use another FEX function "subplotplus.m" to generate my grid of subplots and assign these to a normal uitab object. Not as pretty but it will do for the meantime.

Your mention of a new object similar to the uiaxes component sounds ideal and would really compliment an already excellent toolbox. I look forward to when this capability is added.

David Sampson

David Sampson (view profile)

Eugen, the programming model for GUI Layout Toolbox is that sizes of contents are specified through properties of the parent container. Can you please provide some more information on how you want to specify contents sizes and how you expect contents positions to change when the parent resizes so that we can advise on how this could be achieved (or not) with GUI Layout Toolbox?

David Sampson

David Sampson (view profile)

Drew, no progress on supporting axes with legends as direct children of a GLT container. For layout purposes, you really need something that contains both the axes and the container.

This past week, I have been looking at getting GUI Layout Toolbox working with the web graphics system that underpins App Designer. Here there is a new component -- uiaxes -- that contains both the axes and its associated items (e.g., legend).

Hi David,
great work. I'm trying to implement this in one of my GUIs I wrote and currently it is a bit frustrating. So far I was always placing everything manually and created kind of GUI objects which are packed into a panel. These "objects" should be fixed in size and I don't want to have a scaling, but it would be great to arrange these panels automatically, so I wouldn't have to worry about exact position in the figure anymore. Is it possible to include panels with fixed size into HBox or Grid, without using the Widths and Heights property?
Thanks,
Eugen

DrewVam55

Hello David,

I have used this in a few different GUIs now and have loved it. Did you ever come up with a solution to uicontainer being needed for appropriate legend behavior?
I need legends for a GUI, but the uicontainer and associated axis/legend seem to resize poorly within my VBox, getting cut off on the top after the figure shrinks considerably as opposed to resizing the axes. I have tried making the uicontainers the direct children of my VBox as well as wrapping them in a Panel or Box. Also, my ItemHitFcn (clickToggleVisibility) for my legend in these uicontainers does not seem to work within the GUI Layout Toolbox, but I'm not sure if that's a GUI Layout Toolbox issue.

Thanks,
Andrew

David Sampson

David Sampson (view profile)

Martin, I believe that prior to R2014b, it was possible to set the BackgroundColor of a uipanel to 'none'. For example, see http://undocumentedmatlab.com/blog/transparent-uipanels. However, from R2014b, that is no longer the case. I will capture this as an enhancement request.

David

Great Toolbox, I’ve been using it for several years now (including the pre 14b release).

I have very much enjoyed controlling the layout with HBoxes, VBoxes, etc, but now I’d like to put an image as a background to the whole GUI. Unfortunately, I can’t seem to find a way to make the Hboxes / Panels transparent, so that the image in the background is visible. I know how to make uicontrols and text labels transparent (thanks to Yair’s undocumentedmatlab.com blog), but I’m struggling to make uipanels transparent. Can you think of a way how to have a GUI with background image while utilizing your great toolbox?

David Sampson

David Sampson (view profile)

Alain, regarding uitab versus uix.TabPanel, please see my reply to Tim dated 14 April 2017.

ScrollingPanel slider positions are controlled by properties VerticalOffsets and HorizontalOffsets.

Very Nice Toolbox. Have worked with version 2.2 so far and extended the uix.TabPanel so that the BackgroundColor is applied to the dividers UIControl too:

Index: TabPanel.m
===================================================================
--- TabPanel.m (revision 336)
+++ TabPanel.m (working copy)
@@ -79,7 +79,8 @@

% Create dividers
dividers = matlab.ui.control.UIControl( 'Internal', true, ...
- 'Parent', obj, 'Units', 'pixels', 'Style', 'checkbox' );
+ 'Parent', obj, 'Units', 'pixels', 'Style', 'checkbox',...
+ 'BackgroundColor', obj.BackgroundColor);

% Create listeners
backgroundColorListener = event.proplistener( obj, ...
@@ -795,6 +796,9 @@

function onBackgroundColorChange( obj, ~, ~ )

+ % propagate to dividers ui element
+ set(obj.Dividers, 'BackgroundColor', obj.BackgroundColor)
+
% Mark as dirty
obj.Dirty = true;

Alain Barraud

Hi David
Fantastic Toolbox!!! However some questions.
Using uix.BoxPanel( ) same remark as Team. It would be nice to have the solution within this toolbox without refering to uitab.
Using uix.ScrollingPanel( ) how to set properly the slider initial position (hiden property perhaps)
I have probably missed Something with uix.ScrollingPanel trying to scroll many axes with some fixed number visible at the same time on screen. See the following m file. Best regards. Alain
function TestUIEXTRA(Flag)
if nargin==0, Flag=1;end
close all
f = figure('Name', 'Scrolling sevral axes' ,'unit','norm','outerposition', [0 0 1 1]);
p = uix.ScrollingPanel( 'Parent', f );
hh=uipanel('parent',p);
hhpos=getpixelposition(hh);W=hhpos(3);H=hhpos(4);y=0;
ns=3;%I want 3 axes visibles at the same time (on screen)
n=8;%total number of axes
ax=gobjects(n,1);
%first possiblilty
if Flag
for k=1:n
ax=axes('parent',hh,'unit','pixel','outerposition',[0 y W H/ns]);y=y+H/ns;
title(num2str(k))
end
end
set( p, 'Widths', .98*W, 'Heights', n*H/ns, 'HorizontalOffsets', 0, 'VerticalOffsets', 0)
%second possiblity axes are set up after the p settings
if Flag~=1
for k=1:n
ax(k)=axes('parent',hh,'unit','pixel','outerposition',[0.025*W y .95*W H/ns]);y=y+H/ns;
title(num2str(k))
end
end
% very strange results in any case but different
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Brecht

Brecht (view profile)

confirmed David, the problem is still there without GUI layout :
fh = figure;
uipanel('Parent', fh, 'Position', [0 0 0.5 1], 'Title', 'Control');
uipanel('Parent', fh, 'Position', [0.5 0 0.5 1], 'Title', 'Depth');

David Sampson

David Sampson (view profile)

Dani, Yannick, that doesn't sound like a GUI Layout Toolbox issue per se. Can you please confirm whether you see the same effect with two uipanels side-by-side:
fh = figure;
uipanel('Parent', h_hbox, 'Position', [0 0 0.5 1], 'Title', 'Control');
uipanel('Parent', h_hbox, 'Position', [0.5 0 0.5 1], 'Title', 'Depth');

Dani

Dani (view profile)

Thanks Yannick. Works.

Dani, I had the same issue. I now use 'FontName', 'Arial' for all my GUI's.

Dani

Dani (view profile)

If I run the code below then the (top) lines surrounding the panels are not aligned properly. If I change the title of the second panel to 'CDepth' then they are, i.e. it is related to the title text. Any way to fix this?

fh = figure;
h_hbox = uix.HBox('Parent', fh);
uix.Panel('Parent', h_hbox, 'Title', 'Control');
uix.Panel('Parent', h_hbox, 'Title', 'Depth');

GianCarlo

ali kermani

Leul Belayneh

The class "uiextras" is undefined.
Perhaps Java is not running.

This text pops up while running a MATLAB code. How can it be solved?

lv

lv (view profile)

David Sampson

David Sampson (view profile)

Josh, see section 6 of the GUI Layout Toolbox documentation, "Deploying GUIs using the MATLAB Compiler".

David Sampson

David Sampson (view profile)

Grzegorz, yes you can, provided you abide by:
1. The MathWorks, Inc. software license agreement (see Help > Terms of Use)
2. The GUI Layout Toolbox license (see "View License" link above)

For more background on licensing of File Exchange submissions, see:
https://www.mathworks.com/matlabcentral/FX_transition_faq.html

Grzegorz Knor

Can I use GUI Layout Toolbox in commercial application? It is planned to be deployed as standalone executable.

Josh Spencer

Hello David,

I am using R2016b with version 2.3.1 of the GUI Layout Toolbox. Is there a work around to enable the GUI Layout Toolbox to work with the MATLAB compiler?

Thanks,
Josh

Josh Spencer

I am using R2016b with version 2.3.1 of the GUI Layout Toolbox.

David Sampson

David Sampson (view profile)

Tim, if you don't need the ability to disable tabs then you should use uitab, which was added to MATLAB in R2014b. This provides a small slider to scroll if the tab titles get long.

If you do need disabling *and* long tab titles then let me know and I can lobby further to have disabling added to MATLAB.

Grzegorz Knor

Works like a charm :) Very intuitive.

Tim Spaeder

Hi David,
first of all: This is an amazing tool, tank you very much.

I have a Problem concerning the handling of the TabPanel. I have a GUI which creates a lot of Tabs. The fallowing MWE illustrates this:

h.mainWindow = figure('Name','Testfigure');
%mainContainer that holds all content
h.mainContainer = uiextras.VBox('Parent',h.mainWindow);
%tabPanel for various pages
h.TabBar = uiextras.TabPanel(...
'Parent', h.mainContainer,...
'TabSize',-1);
%create numerous tabs
for i=1:20
pageHandle = sprintf('Page%1.0f',i);
h.(pageHandle) = uicontrol(...
'Parent',h.TabBar,...
'Style','text',...
'String',['Content of ',pageHandle]);
end

It is obvious that the 'TabName' of every Tab is being shortened and thus unreadable. Any Idea how to fix this? I want to be able to read the full 'TabName' but I do not really care about formatting.

- I was wondering if I can somehow make the TabPanel itself scrollable and set the 'TabSize' of every Tab to say 80pts.
- Alternatively I would like to Change the height of the TabBar so the 'TabName' can span two rows
- Another alternative might be to set only a specific number of Tabs visible in the TabBar depending on which Tab is active and Change the visibility whenever another tab is being selected

Can you provide a Suggestion to this Problem?

Guojin Feng

Great toolbox! Like it! It makes the writing of GUI in Matlab more efficient. Together with the Javacomponent, one can develop really good GUI. Although the App Designer provides modern GUI design and looks really cool, its capabilities are still limited currently since it starts using the new uifigure, which is not compatible with figure component. So currently, I will use the layout toolbox to design GUI in Matlab.
One issue is the starting speed can be slow if you got quite a few components in the GUI. As discussed by other users, this is caused by the many calls to the redraw function. Hope this can be solved soon.

Hi David,

Calling the "move" method of the activeX control with the "SizeChangedFcn" of its uix parent works flawlessly.

The only pain was to find the relative position of the parent uix container wrt. the figure. I end up cascading down all the ancestors, summing up the positions, until I find the figure.

David Barry

+1 vote for the ability to disable redraws until all children have been added. This would be really useful in a GUI I am currently writing where I am creating elements in a loop and it is wasted time redrawing until I have finished the loop.

David Sampson

David Sampson (view profile)

Boris, see my post dated 25 February 2016. Please reorder contents using the Contents property, not the Children property.

BorisPas

Hi,

I am currently building a Gui with this very helpful toolbox.
I have one question about inserting Boxes.
I want to insert a Box at a specific location between other already included ones. So far I achieve this by adding a new box and afterwards change the order in the Array.

e.g.: Box.Children([1 2]) = Box.Children([2 1]);

This way works as I wish, but it takes quite a long time especially when I get more Fields. In my case it can take up to several seconds just to insert a box like this.

Is there a better way to insert Boxes at a specific location in the stack?

Kind regards
Boris

BorisPas

Cortexlab

Thanks David. Perhaps one approach besides a user-accessible "RedrawMode" flag would be to provide a function that populates each element of a uix.Grid with an object of some type (like a uicontrol, or a uix.Box). This function could take care of disabling/enabling RedrawMode itself. Since changing the String and Style of the uicontrol is relatively very fast, this would at least solve the problem in my particular case, though probably not quite as general as a user-accessible version. In any case, let me know if you come up with something! Thanks.

David Sampson

David Sampson (view profile)

Nick, thanks for your benchmark code. See my comment from 23 February 2016 on disabling redraws temporarily. I think this could speed up your case by ~40%. We'll take a look.

Cortexlab

Hi - thanks for making a really wonderful toolbox! It's amazing how simple it is to create sophisticated guis.

However, we're having a problem with performance. Our gui involves a uix.Grid with about 100 uicontrols in it. It takes about 3 sec to create this grid, which isn't good enough because we have to re-create versions of it frequently when users interact with the gui. From profview it looks like the vast majority of this time is in "addChild" and especially in the "setPosition" commands that it ends up calling over 5000 times (presumably re-drawing everything each time a single child is added). Do you have any suggestions for how I can improve the speed? Below is a sort of minimal example that takes nearly as much time as our entire GUI. Thanks!

Nick

tic;
f = figure;
g = uix.Grid('Parent', f);
nR = 33;
for r = 1:nR
uicontrol('Parent', g, 'Style', 'text', 'String', sprintf('text_%d',r));
uicontrol('Parent', g, 'Style', 'pushbutton', 'String', sprintf('btn1_%d',r));
uicontrol('Parent', g, 'Style', 'pushbutton', 'String', sprintf('btn2_%d',r));
end
toc % 2.5 sec to here

ch = allchild(g);
chReorder = reshape(reshape(ch(end:-1:1), 3, nR)', nR*3,1);
g.Contents = chReorder;

g.Widths = [100, 100, 100];
g.Spacing = 1;
g.Heights = 25*ones(1, nR);

toc % 2.55 sec to here

how to install this toolbox in matlab

David Sampson

David Sampson (view profile)

Yannick, unfortunately the support for controlling the position of Active-X controls is poor. You can set the position in pixels with respect to the parent figure at the point of creation, but nothing else. Support for Java components is better.

I had a look at what it would take to synchronize the position of an Active-X control with another component, and gave up. Many ingredients exist -- getpixelposition, SizeChanged and LocationChanged events, move method -- but issues remain with keeping the control on top, forcing redraws, and handling pixel scaling.

This is a limitation in MATLAB, not GUI Layout Toolbox.

David Sampson

David Sampson (view profile)

João, see my comment on 13 Feb 2017: "We don't provide a way to specify spanning..."

Really cool stuff. It works like a charm (I haven't encountered any issues so far). Not being force to do these layouts manually is a very useful thing. Thanks a lot :)

João Ferro

Hi David, is there an easy way to effectively merge cells within a uix.Grid object (perhaps playing with the Widths and Heights properties)? Thanks, Joao

hello all,

Has any body tried to place an ActivX control in a uix components ?

It works in theory but you can only define the ActiveX control position wrt. the figure. How do you find the exact position of your uix Panel/Box inside the figure ?

Hi,

I am even downloading .mltbx file for the first time in history. Can anyone help me please how to add this .mltbx file to my Matlab and how can I use it. I have Matlab 2016a Thanks

Jan Keller

DrewVam55

Hello David,

I guess I just needed to keep reading a few more posts to find my solution...it works great! The only thing I would suggest (I made this small modification for myself) is preventing the scrolling action in onMouseWheelScrolled if the figure has MATLAB's native zoom mode enabled. If you do not, you get a combination of the the panel scrolling and figures briefly zooming in/out as the cursor passes over them.

Thanks again,
Andrew

David Sampson

David Sampson (view profile)

Andrew, I added the features to which you refer -- scroll while dragging, scroll with wheel -- in version 2.3.1 on 31 January. Let me know how you like them and if you have suggestions for further changes.

DrewVam55

Hello David,

How difficult would it be to modify the scrolling panel to actively move as you slide it, not just on mouse release?

I was hoping there would be a reasonable solution for controlling it with the mousewheel, but from your efforts that doesn't seem likely. In the meantime, making the GUI window update as you move the scroll bar would still go a long ways towards improving usability.

Thanks,
Andrew

João Ferro

Many thanks David, it's working now. Big thumbs up!

David Sampson

David Sampson (view profile)

Joao, here is an example of a Grid in a ScrollingPanel. In this case it's a fixed size grid in a variable size scrolling panel.

f = figure;
s = uix.ScrollingPanel( 'Parent', f );
g = uix.Grid( 'Parent', s, 'Padding', 10, 'Spacing', 10 );
for ii = 1:16, uicontrol( 'Parent', g, 'String', ii ); end
g.Heights = [200 200 200 200]; % 4 fixed rows
s.Heights = 850;

Related, I tried but failed to add support for variable-with-minimum sizing in version 2.3.1. This would be for the case:

g.Heights = [-1 -1 -1 -1]; % 4 variable rows
s.MinimumHeights = 500; % s.Heights = -1

Fixing this is on the list for the next release.

David Sampson

David Sampson (view profile)

Joao, on defaults:

I am suggesting, per class, a function that creates an object and set some of its properties to defaults while allowing a user to set the others.

function obj = myVBox( varargin )
obj = uix.VBox( varargin{:}, 'BackgroundColor', 'w' );
end

If you wanted a set of such functions to share the same property values then you could create a function for that.

function c = myBackgroundColor()
c = 'w';
end

If you wanted a changeable, sticky default then you could use preferences.

getpref( 'uix', 'BackgroundColor', 'w' )

João Ferro

Thanks for your reply David. In my particular application, I was looking to set the default background colour of all elements (HBox, VBox, Panel, Grid, etc) to white. Could you ellaborate on the 'factory functions' you have suggested?

On a different topic, I am also struggling to use the ScrollingPanel with something other than the axes, as shown in the documentation. What is the actual condition for the scroll bars to be shown (e.g. position(4) value of scrolling panel needs to be smaller than its child)? Would you be able to provide a couple more examples with a VBox or a Grid, for example?

David Sampson

David Sampson (view profile)

Joao, you are looking for something like set(0,'DefaultHBoxPadding',10), or if you are feeling particularly modern, set(groot(),...).

Unfortunately the MATLAB graphics defaults system only works for graphics classes that are part of MATLAB itself. In GUI Layout Toolbox version 1 (prior to R2014b), we hacked in limited functionality for our classes, but it never worked very well, and was removed in the big rewrite for version 2 (R2014b onwards).

If you always want to create objects with certain property values, I suggest that you create a set of factory functions. Preferences (as in getpref and setpref) may also have a role to play depending on what you are trying to achieve.

João Ferro

Hi David, great toolbox! Is it possible to set a default property value for any class in the uix package, e.g. set default background colour for any VBox, HBox created? I understand this can be done on the root level for any graphics objects but I'm not sure how to do this on user defined classes. Many thanks in advance.

David Sampson

David Sampson (view profile)

For questions on installing toolbox (.mltbx) files, you can contact MathWorks support. www.mathworks.com/support

There are several ways to confirm that a toolbox is installed:
* Launch the Add-On Manager
* Inspect the output of matlab.addons.toolbox.installedToolboxes
* If the toolbox includes documentation, launch the documentation browser, and check under "supplemental software"
* If the toolbox includes Contents.m, use ver, e.g., ver('layout')

M A

M A (view profile)

M A

M A (view profile)

Osama Abbas

I have MATLAB R2015a. When I try to install your toolbox, it appears that it is installed, but I can't find it !!. What is wrong ?

David Sampson

David Sampson (view profile)

Yoav, we don't provide a way to specify spanning, but you can achieve what you need by nesting instead if you set the widths and heights appropriately.

Yoav Romach

Is it possible to add an option inside a grid for an item to take multiple spots?

I have a 8x5 grid, but I want the last 4 item (bottom corner) to be a single button...

Is there any way to do it currently?

David Sampson

David Sampson (view profile)

Yannick, MATLAB uses column-major ordering, whereas western reading order is row-major. I didn't feel comfortable going with a default that was different to MATLAB, even though you are not the first to provide this feedback. We have toyed with providing a switch to control order, and also allowing specification of Contents as a matrix rather than a vector. We need to think some more about this point.

Hi David, I ended up overloading the tracking function just to have consistent results when loading up. Every little helps when running through the RunTime. Not sure why it takes so long though, I'm thinking it has something to do with the Proxy.

On another note, I always edit the Grid class because I need it to build up line by line instead of column by column. It would be nice to be able to choose when calling it.

David Sampson

David Sampson (view profile)

Matthew, minimum heights and widths for scrolling panel contents are available from version 2.3.1, released today.

f = figure();
s = uix.ScrollingPanel( 'Parent', f );
h = uix.HBox( 'Parent', s, 'Padding', 10, 'Spacing', 10 );
for ii = 1:4, uicontrol( 'Parent', h, 'String', ii ); end
s.MinimumWidths = 450;

Erik, I also added wheel-based scrolling.

f = figure();
f.Position(3:4) = 450;
movegui( f, 'center' );
p = uix.ScrollingPanel( 'Parent', f );
n = 30; h = 20; s = 5;
g = uix.Grid( 'Parent', p, 'Padding', s, 'Spacing', s );
for ii = 1:n, uicontrol( 'Parent', g, 'Style', 'text', 'String', sprintf( 'Parameter #%d:', ii ), 'Enable', 'inactive' ); end
for ii = 1:n, uicontrol( 'Parent', g, 'Style', 'edit' ); end
g.Widths = [-1 -1];
g.Heights(:) = h;
p.Heights = n*h + (n+1)*s;

Unfortunately I have discovered that the two features do not work together. Wheel-based scrolling currently only works for fixed sizes, not variables sizes with minima.

David Sampson

David Sampson (view profile)

Matthew, I agree that it would be useful to provide a way to set minimum heights and widths for scrollable panels. This doesn't conflict with the current programming model for GUI Layout Toolbox. I have captured that as an enhancement request for inclusion in an upcoming release. Thank you for the suggestion.

Afternoon David,

First off, fantastic resource. I'm having a bit of a play around with the scrolling panel and am wondering if there a solution to the following.

Say that within a gui I have a scrolling panel acting as a main wrapper. Within that I have a HBox that has flexible widths, but has a minimum width based on the minimum widths of its children. How can I force the scrolling panel to respect this when the window is resized to less than the minimum width of its children?

I would of expected a minimumWidths / minimumWidths property for the ScrollingPanel that applies to the child, but these don't exist.

Regards,

Matt

David Sampson

David Sampson (view profile)

Correction to my last message: I meant WindowScrollWheel, not WindowMouseMotion.

David Sampson

David Sampson (view profile)

Erik, I have looked into providing wheel-driven scrolling. This would entail hooking up a listener to the figure WindowMouseMotion event. The challenge is figuring out whether the pointer is over the ScrollingPanel, since that is the behavior that users expect.

Easiest is to check whether the HitObject in the event data is the ScrollingPanel. However that relies on the user turning off HitTest for everything in the container.

Another option would be to check whether HitObject is the ScrollingPanel or any of its children. Calling allchild in response to the pointer moving is going to be slow, and maintaining a cache of descendents is error prone.

Computing the absolute position of the ScrollingPanel, and comparing it to the absolute pointer position, is difficult for docked figures. You also have to worry about what is on top of what. Finally, you have to cache information to provide good performance.

In conclusion, I have parked this for now, but would like to revisit it in future.

David Sampson

David Sampson (view profile)

Yannick, I wonder why performance in your environment is significantly worse than I have seen. I expect less than 0.1 s, and typically about 0.03 s, all of which is the call to urlread.

As a reminder to others:
1. The tracking is called once per MATLAB session, the first time you create a GLT object.
2. I am trying to quantify usage to build the case for development resources.

Found out I can save 1 full second when creating my gui by turning the usage tracking off :

uix.tracking('off')

Hi,
I was wondering if it is possible to use mouse scroll wheel to scroll through the uix.ScrollingPanel?
Not sure if this is related but I'm on Mac and the only way to scroll through the scrolling panel is by grabbing the slider.
Thanks!

David Sampson

David Sampson (view profile)

DrewVam55, uix.ScrollingPanel, like other GLT panels, only shows one child at a time. Which child is controlled by the property Selection.

You can put subplots in a container (uicontainer or uipanel('Title','','BorderType','none')) and put the container in a scrolling panel.

f = figure;
s = uix.ScrollingPanel( 'Parent', f );
p = uipanel( 'Parent', s, 'BorderType', 'none' );
t = -10:0.01:10;
a1 = subplot( 4, 1, 1, 'Parent', p );
plot( a1, t, sin( t ) );
a2 = subplot( 4, 1, 2, 'Parent', p );
plot( a2, t, cos( t ) );
a3 = subplot( 4, 1, 3, 'Parent', p );
plot( a3, t, sign( t ) );
a4 = subplot( 4, 1, 4, 'Parent', p );
plot( a4, t, t );
s.Heights = 1000; % make this taller than the panel

(I expect that this response will trigger a bunch of follow-on questions to which I do not have satisfying answers!)

Any news on when this awesome toolbox will be compatible with the AppDesigner ?...

Thanks a lot

DrewVam55

Hello David,

Is there any plan to update this to be functional with subplot() ? I have been trying to come up with a good way to incorporate a GUI with several graphs (too many for one screen) and a combination of subplot and ScrollingPanel would be perfect. As of now, I believe subplots somehow get destroyed by the internals of the Panel when the add/remove child listener executes - only the current axes is carried over after the event callback, and the rest of the subplot axes disapper.

DrewVam55

David Sampson

David Sampson (view profile)

For anyone having issues with installation, here are a few tips.

Make sure you download the toolbox, not the zip file.

Once you have the .mltbx file, there are several ways to install. All should work.
1. Double click on the file outside MATLAB. The file extension should be associated with MATLAB during the installation process.
2. Double click on the file in the Current Directory view inside MATLAB.
3. matlab.addons.toolbox.installToolbox (16a and later)

GUI Layout Toolbox 2.x works with MATLAB R2104b and later.

I use Matlab R2016b and can not install this toolbox no matter what I tried.

David Sampson

David Sampson (view profile)

For the first time, GUI Layout Toolbox has reached 1000 downloads per month. Thanks everyone for your interest, support and feedback.

If you are using an older version then please download the latest version to receive enhancements and bug fixes. The toolbox is stable and we have a decent test suite that we run continuously across MATLAB versions dating back to R2014b, so updating should be no pain just gain.

If you find GUI Layout Toolbox useful then please spread the word, and please consider rating the submission on File Exchange.

Therry

Therry (view profile)

Hello David,
the tool works very well! One drawback (solved): Moving the mouse over a big figure slows down the reaction time of contextmenus sometimes up to 10 s depending on movements). After including a "drawnow" in the embedded functions "onMouseMotion" in GridFlex, HBoxFlex and VBoxFlex the reaction time is fast again. Is it possible to include this in your next issue?

David Sampson

David Sampson (view profile)

Steve, there should not be any particular issue with using context menus inside GLT containers. For example:

t = 0:0.1:10; % time
f = figure();
g = uix.Grid( 'Parent', f, 'Padding', 50, 'Spacing', 50 );
r = 3; c = 2; % rows and columns
for ii = 1:r*c
a = axes( 'Parent', g, 'ActivePositionProperty', 'Position' );
plot( a, t, rand( size( t ) ) );
end
g.Heights = repmat( -1, [r 1] );
c = uicontextmenu( 'Parent', f );
uimenu( 'Parent', c, 'Label', 'The' );
uimenu( 'Parent', c, 'Label', 'Math' );
uimenu( 'Parent', c, 'Label', 'Works' );
set( g.Contents, 'UIContextMenu', c )

The code that you posted does not run.

Steve Ratts

Excellent toolbox! Really great documentation that makes it easy to get started using it.

I did get stuck on one thing, though. I can't seem to add uicontextmenus to plots. I've tried following the general purpose guidance Mathworks provides, and of course their code works with ordinary figures, but when I try to do the same thing applying it to something I've plotted in an axes that's part of a grid I get an error message that says there is no Label property on the Menu class.

Here's an example of what I've tried. In this example all the objects I've created are in the gui structure, and the data for my gui is in the data structure. The GUI has a 2x3 grid of axes which are in the gui.axes array. Other than calls to uimenu, everything appears to work fine:

for n = 1:6
keyIndex = data.Index+n-1;
if keyIndex <= 256
p = plot(gui.axes(n), data.keys(keyIndex,:));
c = uicontextmenu;
p.UIContextMenu = c;
m1 = uimenu(c, 'Lable', 'Zoom In', 'Callback', @onZoomIn);
m2 = uimenu(c, 'Lable', 'Zoom Out', 'Callback', @onZoomOut);
m3 = uimenu(c, 'Lable', 'Reset', 'Callback', @onResetZoom);
ylim(gui.axes(n),YLim);
set(gui.axes(n), 'FontSize', 6);
XLim = get(gui.axes(n), 'XLim');
text(gui.axes(n), 0.02*XLim(2), 0.9*YLim(2), ...
sprintf('Key Byte = %d', keyIndex-1), ...
'FontSize', 6);
else
cla(gui.axes(n))
end
end

Steve Ratts

Christophe

David - Thanks for the example and the comments, I now understand better the use of this new panel.

David Barry

Thank you for uix.ScrollingPanel David and Ben. You have just upped the MATLAB App building game once again. I do hope that your development colleagues are seriously considering this capability for App Designer.

David Sampson

David Sampson (view profile)

The leading use case so far is to lay out a tall list of controls in a limited vertical space.

f = figure();
f.Position(3:4) = 450;
movegui( f, 'center' );
p = uix.ScrollingPanel( 'Parent', f );
n = 30; h = 20; s = 5;
g = uix.Grid( 'Parent', p, 'Padding', s, 'Spacing', s );
for ii = 1:n
uicontrol( 'Parent', g, 'Style', 'text', 'HorizontalAlignment', ...
'right', 'String', sprintf( 'Parameter #%d:', ii ) );
end
for ii = 1:n
uicontrol( 'Parent', g, 'Style', 'edit' );
end
g.Widths = [-1 -1];
g.Heights(:) = h;
p.Heights = n*h + (n+1)*s;

Christophe

The new scrolling panel seems to work well but I do not know if I will use it because it may only help for very particular case. If you have an example putting good use of it, I am interested to see it.
Anyway new possibilities/tools are always welcomed :)

David Sampson

David Sampson (view profile)

Putting uicontainers between the VBox and the axes appears to help, although I will still seek to understand more about why the scribe layer is removing the axes in the first place.

gui.ViewContainer1 = uicontainer( 'Parent', gui.ViewLayout );
gui.ViewAxes1 = axes('Parent', gui.ViewContainer1 );
gui.ViewContainer2 = uicontainer( 'Parent', gui.ViewLayout );
gui.ViewAxes2 = axes('Parent', gui.ViewContainer2 );

TRogers

Excellent toolbox! Thanks David

I may have found a slight bug (streamlined example below).

I have two axes displaying different images. If I click on the Data Cursor, and then click on a point in either of the images/axes, they swap positions in the GUI. Further clicks no longer swap the positions.

Any ideas? Is it something wrong in my code?

I'm using R2016a on Linux.

---- example case ----
close all; clear all;
gui = struct();

gui.Window = figure( ...
'Name', 'Image Viewer', ...
'NumberTitle', 'off', ...
'MenuBar', 'none', ...
'Toolbar', 'figure', ...
'HandleVisibility', 'off','color','w','Units','normalized','outerposition',[0,0,1,1]);

browseLayout = uiextras.HBoxFlex( 'Parent', gui.Window, 'Spacing', 3 );

gui.ViewPanel = uiextras.BoxPanel( ...
'Parent', browseLayout, ...
'Title', 'Image Viewer');

gui.ViewLayout = uiextras.VBox( 'Parent', gui.ViewPanel, ...
'Padding', 3, 'Spacing', 3 );

gui.ViewAxes1 = axes('Parent', gui.ViewLayout);
gui.ViewAxes2 = axes('Parent', gui.ViewLayout);
linkaxes([gui.ViewAxes1,gui.ViewAxes2]);

I1 = ones(700,1400);
I2 = zeros(700,1400);

imshow(I1,[],'Parent',gui.ViewAxes1)
imshow(I2,[],'Parent',gui.ViewAxes2)

David Sampson

David Sampson (view profile)

Version 2.3 of GUI Layout Toolbox is now available. Please give the new scrolling panel a try!

Amit

Amit (view profile)

David - Thanks for your help and appreciate your comments on this and agree with you to avoid addlistener against event.listener. I was unsuccessfully trying to listen to annotation deletion event followed by set(gco,'Selected''off'). Thanks so much for your solution.

David Sampson

David Sampson (view profile)

Amit, I cannot assess whether what you are trying to do is reasonable, but I can tell you how to make a component unselectable: create a listener on the property 'Selected', and configure the listener callback to set the property value back to 'off'.

addlistener( o, findprop( o, 'Selected' ), 'PostSet', @(~,e)set(e.AffectedObject,'Selected','off') )

Normally I avoid addlistener in favour of event.listener, but in this case, the source of the original event and the reacting object are the same, so it's OK.

Here's an example that creates a number of containers, one of which -- the box panel -- is not selectable.

h = uix.HBox( 'Parent', gcf, 'Padding', 10, 'Spacing', 10 );
b = uix.BoxPanel( 'Parent', h, 'Padding', 10 );
c = uicontrol( 'Parent', b, 'String', 'Click me!' );
a = axes( 'Parent', h );
[x, y, z] = peaks();
surf( a, x, y, z )
addlistener( b, findprop( b, 'Selected' ), 'PostSet', @(~,e)set(e.AffectedObject,'Selected','off') );

Amit

Amit (view profile)

David - Any comments specifically on Point 2) which is really annoying me.

Can I somehow add a listener to panel underneath so that when it get selected it triggers 'Selected' property to 'off' state?

Help on this would be appreciated.

Amit

Amit (view profile)

Hi David, Thanks for your reply. I am sorry if I did not put my question properly.

I understand GLT will set Position back on next appropriate event and that's exactly one would expect.

1) But how can I disable the panel getting selected so that user is not able to move/select them? I am setting 'HitTest' property but is there any other way to prevent user to select the panels (in the first place)?

2) The panel (containing a child axes) get automatically selected when an annotation from the axes is deleted. How can I stop this behaviour?

David Sampson

David Sampson (view profile)

Amit, it is possible to select GLT panels. It is also possible to resize them manually and temporarily, e.g., create and then set Position explicitly. However, GLT will set Position back on the next appropriate event, e.g., ancestor resize.

Related: Because GLT child sizes are effectively owned by parents, we don't have a way for child position sets to be constrained by their parent type and properties. I could build this -- parents listening to children positions, identifying sets not initiated by parents, and reacting -- but it would be a lot of pain for not much gain.

Amit

Amit (view profile)

Hi David, In addition to Zhangjun query, like you said, 2.2.2 works as expected. But deleting an annotation (using edit plot toolbar) selects the parent panel of the axes.

I also discovered that one can move around and resize the box panels using 'EditPlot' toolbar. I can set the 'HitTest' property to 'off' to stop this. Is there any other way to stop this?

I am using 'HitTest' for the time being to disable selection of the panels (using 'EditPlot' toolbar) but parent panel containing the axes still gets selected if any annotation is deleted. How can I stop this behaviour?

David Sampson

David Sampson (view profile)

Christophe, good request for default properties in the documentation. We are considering a rework of the documentation to make it look like the product documentation, but that is quite a big job.

David Sampson

David Sampson (view profile)

Zhangjun, I introduced a change in version 2.2.2 enabled data cursor mode to be used without requiring an additional uicontainer.

For example:
>> h = uix.HBox( 'Parent', gcf );
>> a = axes( 'Parent', h );
>> plot( a, 1:10, rand( [1 10] ) )
Turn on data cursor mode and click on the line. Works in 2.2.2, errors (as you report) in 2.2.1.

If you are seeing an issue with the 2.2.2 then I would appreciate it if you could contact me via my FX profile and send reproduction steps.

You can select "watch this file" above to receive update notifications.

Zhangjun Yu

Christophe, you are right. Thanks very much. This problem puzzled me several weeks. In addition, my best gain is the discovery of User_guide for GUI Layout toolbox.

Christophe

Zhangjun Yu> Check the help User_guide2_3.html. I think it is the same problem than Color and legends, you have to put the axes in a uicontainer. I did not try myself but according to the comments below, it should work and will be updated later.

Zhangjun Yu

When I use the datacursor, my axes in a HBox will shrink to its half size on the horizontal direction. Here are parts of the error messages:

Warning: Error occurred while executing the listener callback for event
ChildAdded defined for class uix.ChildObserver:
No public property Units exists for class
matlab.graphics.shape.internal.AnnotationPane.

Error in uix.HBox/redraw (line 138)
child.Units = 'pixels';

Error in uix.mixin.Container/set.Dirty (line 129)
obj.redraw() % redraw now

Error in uix.mixin.Container/addChild (line 219)
obj.Dirty = true;

Error in uix.HBox/addChild (line 167)
addChild@uix.Box( obj, child )

Error in uix.mixin.Container/onChildAdded (line 159)
obj.addChild( eventData.Child )

Error in uix.mixin.Container>@(varargin)obj.onChildAdded(varargin{:}) (line 51)
childObserver, 'ChildAdded', @obj.onChildAdded );

Error in uix.ChildObserver/addChild (line 109)
notify( obj, 'ChildAdded', uix.ChildEvent( oChild ) )

Error in uix.ChildObserver/addChild (line 116)
obj.addChild( nChild, oGrandchildren(ii) )

Error in uix.ChildObserver>@(~,e)obj.addChild(nChild,e.Child) (line 96)
@(~,e)obj.addChild(nChild,e.Child) );

Error in matlab.graphics.shape.internal.ScribeStackManager/createLayer

Error in matlab.graphics.shape.internal.ScribeStackManager/getLayer

Error in matlab.graphics.shape.internal.ScribeHost>findAnnotationPane

Error in matlab.graphics.shape.internal.ScribeHost/setPeerParent

Error in matlab.graphics.shape.internal.ScribeHost

Error in matlab.graphics.shape.internal.ScribeHost>@(s,e)nDelayedReparent()
> In uix.ChildObserver/addChild (line 109)
In uix.ChildObserver/addChild (line 116)
In uix.ChildObserver>@(~,e)obj.addChild(nChild,e.Child) (line 96)
In matlab.graphics.shape.internal.ScribeStackManager/createLayer
In matlab.graphics.shape.internal.ScribeStackManager/getLayer
In matlab.graphics.shape.internal.ScribeHost>findAnnotationPane
In matlab.graphics.shape.internal.ScribeHost/setPeerParent
In matlab.graphics.shape.internal.ScribeHost/checkPeer/nDelayedReparent
In matlab.graphics.shape.internal.ScribeHost>@(s,e)nDelayedReparent()

Zhangjun Yu

Christophe

It is an excellent toolbox. I appreciate the support, the documentation and examples.

Could you add the default value for properties in the html documentation in the future update please?

David Sampson

David Sampson (view profile)

Tobias, I think that you are right, there was at some point a property SelectionChangedCallback. I will do some digging to find out what happened. There was a lot going on in that area between GLT1 and GLT2, because of both property renaming and changes to the callback event data.

The principles to which I try to adhere are:
* GLT1 uiextras code runs with GLT2
* Minimal incompatibilities, and none undocumented, as GLT2 versions advance

Tobias

Tobias (view profile)

Thanks David for the reply. My bad, I meant "SelectionChangedCallback". I might have skipped a version, but in the 2.1.? Version I use, uix.TabPanel has a property "SelectionChangedCallback" and in the current version it is "SelectionChangedFcn". Don't want to nit-pick, the issue just came up.

David Sampson

David Sampson (view profile)

Of course the search will yield a result -- this page -- after the Google crawler's next visit!

David Sampson

David Sampson (view profile)

Tobias, no GUI Layout Toolbox TabPanel class has or had property TabSwitchCallback or TabSwitchFcn. Both have a property SelectionChangedFcn.

A Google search for TabSwitchFcn yields no results at all.

Tobias

Tobias (view profile)

Hi, I really like the toolbox a lot. But it seems to have low backward compatibility to previous versions. After a few minutes, I found several issues. Is there a list of commands/options that have changed? Like TabPanel.TabSwitchCallback -> TabPanel.TabSwitchFcn.
That would be very helpful.

Jason

Jason (view profile)

Great tool! I'm curious to know if there are any advantages to using boxes vs grids to place UI components. Is one more efficient (cpu/memory wise) than the other? I'm planning on creating a fairly complex GUI so I'm looking to design it as efficiently as possible.

David Sampson

David Sampson (view profile)

Ted, File Exchange ate my tabs, but you should get the idea.

David Sampson

David Sampson (view profile)

uibuttongroup handles the selection but not the positioning. Often the position is fixed, but you might want to put the uibuttongroup inside a GLT container.

g = uibuttongroup( 'Units', 'pixels', 'Position', [20 20 200 70], ...
'SelectionChangedFcn', @onClicked );
c(1) = uicontrol( 'Parent', g, 'Style', 'radiobutton', 'String', 'Tom', ...
'Units', 'pixels', 'Position', [5 45 190 20] );
c(2) = uicontrol( 'Parent', g, 'Style', 'radiobutton', 'String', 'Dick', ...
'Units', 'pixels', 'Position', [5 25 190 20] );
c(3) = uicontrol( 'Parent', g, 'Style', 'radiobutton', 'String', 'Harry', ...
'Units', 'pixels', 'Position', [5 5 190 20] );

function onClicked( source, ~ )
% do something useful
end

uix.VButtonBox etc. handles the positioning but not the selection. However, it is not difficult to add the selection.

p = uipanel( 'Units', 'pixels', 'Position', [0 0 200 70] );
g = uix.VButtonBox( 'Parent', p, 'Padding', 5, 'ButtonSize', [200 20], ...
'HorizontalAlignment', 'left' );
c(1) = uicontrol( 'Parent', g, 'Style', 'radiobutton', 'String', 'Tom', ...
'Value', 1, 'Callback', @onClicked );
c(2) = uicontrol( 'Parent', g, 'Style', 'radiobutton', 'String', 'Dick', ...
'Value', 0, 'Callback', @onClicked );
c(3) = uicontrol( 'Parent', g, 'Style', 'radiobutton', 'String', 'Harry', ...
'Value', 0, 'Callback', @onClicked );

function onClicked( source, ~ )
source.Value = 1; % select this
set( c(c~=source), 'Value', 0 ) % unselect others
% do something useful
end

Ted Diehl

I cannot seem to get the uix.VButtonBox (or HButtonBox) to work with radiobuttons, in the sense of having the buttons linked like what occurs when using uibuttongroup. When I use the uix approach, the buttons act independently. If I place a uibuttongroup (with radiobuttons in it) inside a uicontainer which is then in a uix entity, I get the buttons to be linked, but their motion inside the uibuttongroup has the same old scaling problems with window resizing. Running 2016a.
Does Gui Layout Toolbox work with radiobuttons and if so, can someone post a simple example. All the "button" examples in the toolbox are simple unlinked (independent) pushbuttons, none that I found show linked radiobuttons. - Thanks!

Bryant

Bryant (view profile)

Tom Wright

kp

kp (view profile)

Please disregard my prior message. It was due to some issue in my MATLAB path.

kp

kp (view profile)

I am having a problem with both 2.1.2 and 2.2.2 under 2016a, but not 2015b. I get this error message in MATLAB:
No public property Units exists for class matlab.graphics.primitive.canvas.JavaCanvas.

As far as I remember, my code used to work under 2.1.2 in 2016a before. Could it be due to updating Java?

I think I may have found a small bug - I couldn't find anything about this in these comments yet.

This concerns the 'Title' on a uix.BoxPanel, and I can demonstrate this bug using the included demoBrowser.m.

On my 13" MacBookPro with retina display, the titles are cut off early with "...". They are: "Select a de..." and "Viewing: L...". No amount of resizing fixes this, and there is plenty of room to display the whole title.

Running the same code on a Windows desktop with a non-retina display shows the full titles correctly.

Thanks.

David Sampson

David Sampson (view profile)

Sucheta, I don't think that this error relates to GUI Layout Toolbox. Could you please submit a technical support request including MATLAB version details and simple reproduction steps?

I am getting the following error while running GUI script file.

"Error using matlab.ui.container.Panel/set
There is no widthlimits property on the Panel class."

David Sampson

David Sampson (view profile)

In version 2.2.2, I have added extremely basic usage tracking to GUI Layout Toolbox. Once per MATLAB session, GUI Layout Toolbox reports toolbox version, MATLAB version, and operating system. No personally identifiable information is transmitted. Tracking is optional -- you will be prompted -- but I encourage you to participate to help us to understand GUI Layout Toolbox usage and plan for ongoing development in this area.

David Sampson

David Sampson (view profile)

Version 2.2.2 of GUI Layout Toolbox is now available. This minor release includes:
* support for axes with data cursors within all container types
* improvements to pointer management for flex containers

David Sampson

David Sampson (view profile)

Grzegorz, currently, GUI Layout Toolbox does not support case insensitive or partial matches on property names or enumerated string property values. I will consider relaxing this.

David Sampson

David Sampson (view profile)

Arti, you need to use the appropriate version(s) of GUI Layout Toolbox for your MATLAB version(s). Version 2.x on this page is for R2014b and later. Version 1.x is for R2014a and earlier. This is mentioned on the BEM acoustics toolbox download page, www.bemacoustics.com/download.

Arti Verma

I am having issue while running a BEMacoustics toolbox which runs using this toolbox.
Here is the error message

Error using uiextras.Container (line 61)
Trying to run using double-handle MATLAB graphics against the new graphics system.
Please re-install.

Would be great if some one could guide me how to fix this issue.

Seth Kenner

Thanks David,

It works well. I was trying to be similar to the way the deploytool panels work where they minimize/maximize wherever you click in the title bar because it feels more user friendly.

I had an issue with case sensivity:
uiextras.HBox('parent', someHandle) adds the HBox to the figure children, not someHandle, without warning/error.

It took me a while to get to:
uiextras.HBox('Parent', someHandle) which works fine.

David Sampson

David Sampson (view profile)

Abbey, a change will be included in the upcoming release so that you don't need to put axes in a container just because you want to use data cursors. You will still need to for legends and colorbars, though.

David Sampson

David Sampson (view profile)

Seth, yes it's possible to implement this behavior.

I initiated the release process earlier in the week, so this change will not be included in the next version.

If you want to make changes locally then:
* Set TitleText Callback in set.MinimizeFcn
* Manage the Enable property of TitleText depending on whether or not MinimizeFcn is empty
* Detach and reattach TitleText in redrawButtons to ensure that it is not selected after clicking

Another question is whether people find the behavior that you propose to be intuitive.

Seth Kenner

Is there an easy way to add the minimizeFcn callback to the TitleText of a BoxPanel as well? This would make it easier to minimize and maximize a panel because the minimize button can be small and hard to hit at times.

This Toolbox is great. Just a note: the documentation mentions using uicontainer for legends and colorbars to be displayed correctly on plots; this seems to also be necessary when using datacursormode.

Juan Henao

Excuse my lack of knowledge, I've developed some quite complex guis using the guide tool but then I saw this and wow, it has awesome features. To the point: Is there any graphic version of this toolbox, like in guide, or do I have to learn the code?.
Thanks for your awesome work, keep going!.

David Sampson

David Sampson (view profile)

Bryant, yes, but how and when are things that we (MathWorks) are working on.

Bryant

Bryant (view profile)

Will there be a version compatible with the new App Designer UI objects/graphics?

Excellent!

I've been using GUI Layouts for a few years now and find it a great tool. Quick question: Can I configure the compiled application to run as a Windows System-Tray background process? Any help appreciated.

Christian

In some of our code we have overloaded the redraw() method of some containers to return the current "Sizes" property of the container. Since updating our code to >R2014b, this leads to enormous amounts of output to the command line whenever such an element is redrawn. I traced this back to two lines in uix.mixin.Container (lines 129 and 149), where the redraw() method is called without a semicolon to suppress output, clearly because no output is expected.

Assuming this does not break anything else, would it be possible to simply add semicolons to the end of those lines to suppress output?

David Sampson

David Sampson (view profile)

Carsten, there is a discussion of uix and uiextras in the documentation, section 2.2 "Compatibility with version 1".

If you are writing new code that only has to work in 14b and later then use uix. Otherwise use uiextras.

Carsten

Can anyone explain when to use uix and uiextras resp.?

And what is the difference?

David Sampson

David Sampson (view profile)

In response to reports of installation issues, I did a quick test. I downloaded 2.2.1 from File Exchange and installed successfully in both 15b and 16a. My setup is win64 with local add-ons directory. I installed by double clicking on the mltbx file in the current folder view in the MATLAB desktop.

Ardalan

I noticed that sometimes, if I have a VBox inside a uipanel, Matlab crashes when closing the figure. I could reproduce the crash also by manually deleting the specific culprit VBox.

I could get rid of the problem by using uix.Panel instead of uipanel. I this a known problem or otherwise what was the reason to repalce uipanel with uiextras/uix.Panel?

At the moment I still have the problem of Matlab crashing. I traced the problem by deleting all child objects of my figure one-by-one. The crash occurs when deleting the very last child object, which is again a VBox having the Figure itself as its parent.

The crash manifests as an "access violation" in an "<unknown-module>". I'm using version 2.2.1 on R2014b.

Philipp

Hi David,

I tried to use the GUI Layout Toolbox in combination the uicomponent from Yair Altman and have an issue with that combination.
The following code works, which is still putting the uicomponent into a uipanel:

hf1 = figure;
hvb1 = uix.VBox('Parent',hf1);
hp1 = uipanel('Parent', hvb1);
hjl1 = uicomponent('Style','JLabel', {'no data'}, ...
'HorizontalAlignment', javax.swing.SwingConstants.CENTER, ...
'VerticalAlignment', javax.swing.SwingConstants.CENTER, ...
'Background', javax.swing.plaf.ColorUIResource(1,0,0));
set(hjl1, 'Parent',hp1, 'Units','normalized', 'Position',[0 0 1 1]);

But when I try to use the uicomponent directly with the vbox I have to resize the figure window to get the correct display:

hf2 = figure;
hvb2 = uix.VBox('Parent',hf2);
hjl2 = uicomponent('Parent',hvb2, 'Style','JLabel', {'no data'}, ...
'HorizontalAlignment', javax.swing.SwingConstants.CENTER, ...
'VerticalAlignment', javax.swing.SwingConstants.CENTER, ...
'Background', javax.swing.plaf.ColorUIResource(1,0,0));

Is there a way to get the correct behavior without having to put the uicomponent into an additional panel?

Markus

Markus (view profile)

Sorry, but I think the mltbx file doesn't work under 2015b and 2016a. I double click the file "GUI Layout Toolbox 2.2.1.mltbx" and the installation sign come on top. I push the button "Install" and agree the terms. After than nothing happens...

Does anybody have the same problem?

Yair Altman

Yair Altman (view profile)

I only saw @Tanmay's comment below and @David's suggestion now. I've just uploaded a fixed version of UICOMPONENT that accepts HG2 (inc. uiextras) containers as parents, in addition to all the previously-acceptable parent types.

Ahmad Gazar

I downloaded the mltbx file, double clicked it, still no sign of installation. I typed ver layout and I received this error "Warning: No properly formatted Contents.m file was found for 'layout'." Please help, I am using matlab R2015a for ubuntu.

David Sampson

David Sampson (view profile)

Please ensure that you download the mltbx file rather than the zip file.

To install the toolbox, double-click on it in the Current Folder view.

To check whether the toolbox is installed, type "ver layout" at the command prompt, or launch the Add-on Manager.

Ahmad Gazar

I am trying to install the toolbox on matlab r2015a, but no indication of the toolbox being installed. please help.

David Sampson

David Sampson (view profile)

Late last year there were some reports of pointer state getting messed over flex containers. The issue was the handling of transitions between adjacent dividers in different containers. There is a fix in version 2.2.1, just released.

If you are interested in how pointer changes are now coordinated, take a look at uix.PointerManager.

It worked, David. Now that line spends 0.06s intead of 0.28s. Thanks a lot.

David Sampson

David Sampson (view profile)

Leonardo, back to your question on performance. I'd like to remind everyone to reorder layout contents using property Contents, not property Children.

There is a discussion of the difference in the GLT documentation, but here is the brief version. Children is the vertical stacking order and is defined by MATLAB, and is irrelevant to most GLT use cases. Contents is the layout order and is defined by GLT.

If you reorder via Children, MATLAB detaches them all in turn (one redraw each), then reattaches them all in turn (one redraw each). If the children are GLT containers then each step is likely to *also* resize and therefore redraw each child too. If you are careful then you might get everything in the right layout order. Finally all this detaching and reattaching will erase your sizes, so you will have to reset those too (another redraw).

In contrast, when you reorder via Contents, you get a single redraw, and GLT permutes the sizes for you automatically.

>> b = uix.HBox( 'Parent', figure, 'Padding', 2, 'Spacing', 2 );
>> for ii = 1:30, uicontrol( 'Parent', b ); end % 30 redraws
>> b.Widths = -rand( size( b.Contents ) ); % 1 redraw
>> [~, i] = sort( rand( size( b.Contents ) ) );
>> b.Contents = b.Contents(i); % 1 redraw
>> b.Children = b.Children(i); % 60 redraws, and Widths are all -1

David Sampson

David Sampson (view profile)

Cell spanning is not supported at this time because I feel that it overcomplicates the API. You will have to stick with nested containers.

I think it won't work, David, because each row has a different number of columns. Is there any way to do it?

David Sampson

David Sampson (view profile)

Leonardo, I will consider this for a future release. The following changes would be made to uix.mixin.Container:
* Define a property RedrawMode to control whether or not to redraw
* In set.Dirty, add a condition to redraw only if RedrawMode is 'on'
* In set.RedrawMode, when setting to 'on', redraw if dirty (see onFigureChanged)

I see that you are using a VBox full of HBoxes. Would a Grid work for you?

Thanks for your answer, David.

Is it possible to disable these redraws?

This is the code line that is taking more time, 0.28s:

vbox10.Children = [edit_description_hbox edit_manager_hbox edit_brokerage_hbox ... edit_strategy_group_hbox ... edit_total_value_day_trade_hbox ... edit_quantity_price_hbox ...
edit_account_hbox edit_client_hbox edit_liquidity_date_hbox edit_deal_time_hbox edit_deal_date_hbox];

David Sampson

David Sampson (view profile)

Leonardo, I think that you mean that you reorder Contents, not Children, although the two are closely related.

There is some scope for performance improvement. In your example, GLT recomputes the HBox contents sizes twice each -- once when the new item is added at the default size, and once when the new item is resized to its final size -- whereas it could be possible to compute the sizes just once. This could be achieved by having the option to temporarily disable redraws, although you would have to remember to turn them back on. Another solution would be to have a configurable default size for new items.

Note that the graphics system won't actually repaint everything twice when you change the properties in quick succession. That is generally more expensive than computing the sizes.

Out of interest, how many GLT containers do you have at each level, and how long is a redraw taking?

Hi, David,

I'm trying to make a very dinamic GUI, so i'm frequently inserting or taking out some components of a vbox. For example, many times I want to insert a hbox into a vbox when the user press a button. When I set the Parent of the hbox the vbox, the hbox is inserted as the last child, but I want it to be the third one, for example. So I use the Children property of the vbox and change the order of its components.

I realized that this process is a little slow, consuming almost 20% of the total execution time of my function. Do you have any faster way to do it or do you intend to improve the performance of this process?

Thanks and congratulations on this amazing toolbox.

David Sampson

David Sampson (view profile)

Henri, you have uncovered a subtle bug. If the first change to ForegroundColor is to black then that change does nothing.

I will include a fix in the next release. After the first two lines of the BoxPanel constructor, please add:
obj.ForegroundColor = foregroundColor;

Henri

Henri (view profile)

Many thanks for your support. The problem was, that I always tried to set the ForegroundColor property to black [0, 0, 0]. However the textcolor remained white. Today I tried [0.1, 0.1, 0.1] instead and it worked fine, even if it is rather grey than black course.

David Sampson

David Sampson (view profile)

Henri, there is a property ForegroundColor. ForegroundColor changes the title text color. BackgroundColor controls the title background color. HighlightColor and ShadowColor control the border colors.

Henri

Henri (view profile)

Hello David, thank you very much for this great toolbox!

Can you please give me hint, how to change the ForegroundColor of the title of a BoxPanel? Since version 2014b I can still set the property "TitleColor", which changes the background color of the TitleBox but not the "ForegroundColor" anymore, which used to change the textcolor of the title.

Henri

Henri (view profile)

David Sampson

David Sampson (view profile)

Alex, I am still working on the confused-pointer fix. This will be included in the next release, probably in February.

Alex Perrone

David, just updated to newest release (12 Jan 2016). I found that one mouse cursor issue, adjusting a tab "below" it, no longer occurs. However, the release did not correct the problem of mouse cursor getting "confused" about which expansion arrow to display on adjacent flex containers, and subsequently getting stuck as an expansion arrow. Was it meant to correct this? Thank you so much for this toolbox.

David, thank you very much for your help! It works perfectly now :)

Laurent

David Sampson

David Sampson (view profile)

Ignore the third and fourth lines of code in my previous post.

David Sampson

David Sampson (view profile)

Darya, take a look at the button box classes, HButtonBox and VButtonBox. These allow you to specify the width and height of their children and to align the children vertically and horizontally. One common use is a row of buttons at the bottom of a dialog.

In your case, put the buttons whose size you want to control explicitly into a button box each.

f = figure();
g = uix.Grid( 'Parent', f, 'Padding', 10, 'Spacing', 10 );
n = 4;
for ii = 1:10, s{ii} = deblank( evalc( 'why' ) ); end
b = uix.HButtonBox( 'Parent', g, 'ButtonSize', [100 20] );
uicontrol( 'Parent', b, 'String', 'MATLAB' );
uicontrol( 'Parent', g, 'Style', 'text', 'HorizontalAlignment', ...
'right', 'String', 'Indiana Jones:' );
uicontrol( 'Parent', g, 'Style', 'text', 'HorizontalAlignment', ...
'right', 'String', 'Three Colors:' );
b = uix.HButtonBox( 'Parent', g, 'ButtonSize', [100 20] );
uicontrol( 'Parent', b, 'String', 'Simulink' );
uicontrol( 'Parent', g, 'Style', 'listbox', 'String', ...
{'Raiders of the Lost Ark','Temple of Doom','Last Crusade'} );
uicontrol( 'Parent', g, 'Style', 'listbox', 'String', ...
{'Blue','White','Red'} );
g.Widths = [-1;-1];
g.Heights(1) = 20;

Alex Perrone

Darya, couldn't you make additional panels, like to have a button that is not so wide, you can have 3 panels in an HBox: left, middle, right. Then you can make the middle a fixed (smaller) size and put the button in there. Only problem is (I believe) only one of the three can fill up the rest of the size using -1 on the widths, so it'd be better to have two panels and have the button either on the left or right, instead of centered.

Hello David,

Thank you for your fast response. Now it's clear to me what's happening.

For the purpose of my program (which is used to post-process some data), I have a lot of components on a grid: checkboxes, textboxes and simply text - their size depends on their own content or the width of the grid columns: e.g. I have text label on the left and a corresponding textbox on the right in my grid.

Then I want to add a button and have it centered in a panel above the grid (panel and grid have the same VBox parent, e.g. width of the panel = width of all the grid columns combined). But then I don't really want to have such a wide button (because my grid is quite wide) and I can't find a way to fix it.

David Sampson

David Sampson (view profile)

Darya, the GUI Layout Toolbox containers take control of setting the Position of their contents. So for a grid, the contents will fill the cells. Perhaps you could explain why in your specific case you need to override some of the sizes.

Hello,

I am programming a GUI using GUI layout toolbox and default Matlab components. I noticed if I use uicontrol Pushbutton or popup on a parent of a class uix.Grid or uix.Panel and set the size of Pushbutton or popup components not to be equal to the width of a Grid column or Panel (by specifying a Position property manually for these components by changing the width and height only), then when running my program it still resets to the sizes of a Grid and Panel components. If I insert a "keyboard" into the code and start debugging my code gradually, the sizes of PushButton and popup are specified correctly based on their own Position property and don't change when GUI window program runs till the end.

I am not very experienced in GUI programming in Matlab. I tried to sort the problem on my own and I don't seem to understand the source of such behaviour.

Can it be related to GUI layout toolbox components definition, that I am not aware of?

David Sampson

David Sampson (view profile)

Alex, sorry I misunderstood your bug report because I didn't scroll down beyond the code to the screenshot. Mea culpa. The issue arises because I was checking whether the pointer is above any divider but not whether the divider is on top. Version 2.2, released yesterday, employs a new technique for detecting when the pointer is over a divider, and fixes the issue.

Alex Perrone

David, wow, that is a nifty way to keep flex containers in sync, didn't know you could listen for changes there. However, I do not care about keeping them in sync. The problem is that you can mysteriously change a flex border on one tab from *another* tab. One shouldn't be able to do that. However, it may be interaction with Gui Layout Toolbox and uitab, the latter of which I use for reasons given in my post dated 24 Jun 2015. I sent you a screen capture to your email demonstrating the problem. Please do whatever you want with the video (e.g. posting somewhere public, this site and gists do not allow posting videos, that's why I did screenshot on the gist).

David Sampson

David Sampson (view profile)

Alex, if I understand you correctly, you have flex containers on multiple tabs and you want to keep them in sync.

Currently there is not an event on the flex containers to notify of changes to the contents sizes. As a workaround, you can react to size changes of the flex container contents. For example:

f = figure();
p = uix.TabPanel( 'Parent', f );
h1 = uix.HBoxFlex( 'Parent', p, 'Padding', 10, 'Spacing', 10 );
b1 = uicontrol( 'Parent', h1, 'String', '1' );
uicontrol( 'Parent', h1, 'String', '2' );
h2 = uix.HBoxFlex( 'Parent', p, 'Padding', 10, 'Spacing', 10 );
b2 = uicontrol( 'Parent', h2, 'String', '3' );
uicontrol( 'Parent', h2, 'String', '4' );
addprop( h1, 'ContentsSizeChangedListener' );
h1.ContentsSizeChangedListener = event.listener( h1.Contents, ...
'SizeChanged', @(~,~)set(h2,'Widths',h1.Widths) );
addprop( h2, 'ContentsSizeChangedListener' );
h2.ContentsSizeChangedListener = event.listener( h2.Contents, ...
'SizeChanged', @(~,~)set(h2,'Widths',h1.Widths) );

Alex Perrone

In similar vein to previous post about mouse expansion arrow, although looks like a separate problem: When there is an adjustable border on a tab, you can adjust this from another tab. Am I setting up the tabs incorrectly, or ... ? Please see here for code and explanation:
https://gist.github.com/alexperrone/2970592e19e3479ecba6

Alex Perrone

David, Indeed the problem falls into:
* pointer confused by transition between adjacent flex containers
When I hover near the border of an HBoxFlex and VBoxFlex, that's where the mouse cursor gets stuck as an arrow. If I change one to NOT be flex, there is no conflict of the arrow directions apparently and it doesn't get stuck. I have reproducible code and a video capture that I can send directly to you.

David Sampson

David Sampson (view profile)

Alex, I have had a few issues reported in this area:
* pointer wrong in docked figure window - fix to be released soon
* pointer wrong over Java component in flex container (sporadic) - under investigation
* pointer confused by transition between adjacent flex containers - just identified

It would be helpful to know if the problems that you are seeing fall into any of the buckets above, and also whether they are pointer path dependent or speed dependent.

Alex Perrone

Whenever I hover the mouse over the adjustible border in a uix.HBoxFlex, the mouse cursor changes to the expansion arrow and stays as an arrow everywhere throughout the GUI and never returns back to the normal mouse cursor. Any ideas?

As many others, the GUI is currently quite complex, will attempt minimal reproducible example if not an easy fix or something to check. Using R2014b with June 2015 version of Gui Layout Toolbox. Thank you!

Minor improvement suggestion - would be nice if it was possible to set width of each tab separately, in case you have to mix tabs with short and long titles.

Thanks, David. Yes, you're correct with [1 1 parentPixelPos(3:4)].

I'm setting postition in pixels, rather than normalized units, to provide extra padding to content. E.g. if you try setting javacomponent with [0,0,1,1] normalized position as a child of uipanel with some title, you will notice that it is displayed on top of the title, hiding it completely. After pixel position is set, I revert the units to normalized, so resizing works pretty well. Yes, the padding size changes slightly when you resize, but that's hardly noticeable.

I'm guessing the right way would be indeed to hook up SizeChangedFcn callback as you suggest.

I do have to use Position as I use my own layout manager quite extensively, to fine-tune uicontrol layout inside panels created with uix toolbox. I will look at adding SizeChangedFcn to it. For now I've implemented a workaround that, when adding a child (uix.VBox or similar) to a TabPanel tab, switches briefly to that tab and switches back. That seems to solve the issue for me:

% panel is the parent that we just added a child (such as uix.VBox) to
if isa(panel.Parent, 'uix.TabPanel') % Workaround for the position calculation issue in GUI Layout toolbox
tabPanel = panel.Parent;
lastSelection = tabPanel.Selection;

[~, ind] = ismember(panel, tabPanel.Contents); % Note: Contents, unlike Children, has correct ordering
tabPanel.Selection = ind; % Temporarily select the tab. From now on position should be determined correctly

tabPanel.Selection = lastSelection; % Restore selection
end

David Sampson

David Sampson (view profile)

Alexander, you touch on a number of interesting issues that I would like to address.

First, a minor point. In your code, you don't want to be setting the Position of your Java component in its container to be the Position of its container in its Parent. You probably meant javacomponent(jPanel,[1 1 parentPixelPos(3:4)],hSecondPanel). Anyway, more interestingly...

javacomponent(name,position,parent) sets the Parent and *then* sets the Position. Since the GLT containers lay out when the content is added, the subsequent set to Position clobbers the GLT Position. Indeed, we suggest you don't set Position of GLT container content yourself, but by using javacomponent, you might do so inadvertently.

Instead, you can create the Java component unparented, javacomponent(name,[0 0 1 1],[]), and then set its Parent as a second step.

It is true that we make no guarantees about the Position of unselected contents in GLT panels. Therefore there is no guarantee that getpixelposition on unselected content will return the same result after selection. Anyway it is most likely that you want your Java component to be a sensible size not just initially, but anytime its Parent resizes. For this, either put it in a GLT container (noting the points above) or hook up your own layout function using the Parent container's SizeChangedFcn.

In summary, I would replace the last 5 lines of your code with something like:
[jPanel, cPanel] = javacomponent( 'javax.swing.JPanel', [0 0 1 1], [] );
jPanel.setBorder( javax.swing.BorderFactory.createLineBorder( java.awt.Color.blue ) );
set( cPanel, 'Parent', hSecondPanel, 'Units', 'normalized', 'Position', [0 0 1 1] )

Finally, to contact me directly, it's firstname.lastname@mathworks.co.uk.

To be clear, it's not just about @getpixelposition. You'll face the same issue if you try to get position using any other method, e.g. simply: parent.Position. Apparently the only workaround that would cover all the cases is to define pre- and post-set listeners on Position property...

So in short, you cannot rely on @getpixelposition results unless that tab is currently selected. A workaround I can think of, would be traversing all ancestors before calling @getpixelposition to find all parent tab panels, select respective tab in each of them, and revert selection afterwards. This is very ugly and will cause lots of flickering in UI.

Hi David,

My issue (tab returning incorrect pixel position) is not related to how I set the position - both ways (through javacomponent and its uicontainer peer) work fine. The problem is in determining the correct position. Please find a very simplistic snippet reproducing the problem (sorry, not sure what you mean by 'File Exchange' contact form - are you referring to the 'Contact us' form to contact Mathworks?)

The snippet is below. Run the first set of commands, then switch to the second tab, then run remaining two commands. You'll see a neat blue border spanning the whole content of the tab.

And to reproduce the issue - run all the commands first, and then switch the tab. You will not see any border. Then check what parentPixelPos vector has - this is the problem.

hFig = figure();
hTabPanel = uix.TabPanel('Parent', hFig);
uicontainer('Parent', hTabPanel);
hSecondPanel = uicontainer('Parent', hTabPanel);
jPanel = javax.swing.JPanel;
jPanel.setBorder(javax.swing.BorderFactory.createLineBorder(java.awt.Color.blue));

parentPixelPos = getpixelposition(hSecondPanel);
javacomponent(jPanel, parentPixelPos, hSecondPanel);

David Sampson

David Sampson (view profile)

Daniel, can you please contact me directly with full reproduction steps?

I don't use multiple monitors myself, so there may be parts of the toolbox which do not handle this well. I'd be happy to work on this, and I'd be interested in whether other users have had any issues with multiple monitors.

I am planning a release this month. The specific code that you refer to (uix.LocationObserver) has been removed. Nevertheless I would like to have your reproduction steps so that we can add a test to our test suite.

Daniel Lyddy

I set up some side-by-side windows in a single figure using this toolbox, and when I instantiate any new figure, it is docked by default. If I then undock the figure, send some plots to either window, and execute a "drawnow" command, I get the following java error:

Warning: Error occurred while executing callback:
Error using uix.LocationObserver/update/getFigurePixelPosition (line 239)
Java exception occurred:
java.awt.IllegalComponentStateException: component must be showing on the screen to
determine its location

at java.awt.Component.getLocationOnScreen_NoTreeLock(Unknown Source)

at java.awt.Component.getLocationOnScreen(Unknown Source)

Error in uix.LocationObserver/update (line 197)
pixel = getFigurePixelPosition( ...

Error in uix.LocationObserver/onSizeChanged (line 305)
obj.update( source )

Error in uix.LocationObserver>@(varargin)obj.onSizeChanged(varargin{:}) (line 123)
cbSizeChanged = @obj.onSizeChanged;

I am not a Java programmer. What sense should I make of this error message?

Note that undocking the figure usually causes it to appear on my right monitor; I have two. The MATLAB GUI is running on my left monitor. I am running R2014b on Windows 7 Enterprise, Service Pack 1.

Here is what I get when I type "opengl info" on the MATLAB command line:

>> opengl info
Version: '4.4.0'
Vendor: 'NVIDIA Corporation'
Renderer: 'Quadro K2100M/PCIe/SSE2'
MaxTextureSize: 16384
Visual: 'Visual 0x07, (RGBA 32 bits (8 8 8 8), Z depth ...'
Software: 'false'
SupportsGraphicsSmoothing: 1
SupportsDepthPeelTransparency: 1
SupportsAlignVertexCenters: 1
Extensions: {293x1 cell}
MaxFrameBufferSize: 16384

David Sampson

David Sampson (view profile)

Alexander, a couple of comments.

"You need pixel position to use javacomponent." Actually, you don't. Instead, position by setting Parent, Units and Position of the uicontainer peer (second output argument of javacomponent). The Java widget position on screen is automatically synchronized with that of its peer container. Or just set Parent to a GUI Layout Toolbox container and let it manage its children's Units and Position.

>> t = uix.TabPanel( 'Parent', gcf, 'Padding', 10 );
>> [s, c] = javacomponent( 'javax.swing.JSpinner' );
>> c.Parent = t;

If you would like to send me reproduction steps for the case where position is different before and after selecting a tab, please do so via the File Exchange contact form, and I would be happy to provide further feedback.

I am facing a different problem now. I need to get pixel position of uix objects (you need pixel position to use @javacomponent, and in general if you want full control over how your elements are laid out inside). I'm also using uix.TabPanel. Problem is that position is not determined correctly until you switch to the tab, in which control is, at least once (!). Even drawnow does not help.

For example, this is the position I get before I switch the tab (wrong):

K>> get(parent, 'Position')
ans =
1 1 1192 795

And this is the position I get right after I switch the tab (correct):

K>> get(parent, 'Position')
ans =
1 747 1192 30

Clearly vertical position is all wrong. So I have to programmatically flick through all tabs before I can continue rendering the layout, otherwise all my controls are not even visible because they have completely wrong positions. v1 of the toolbox did not have such an issue.

David, I would be fine with either approach. For now I've hacked uix.Container (basically using similar code as in uix.Empty + extra onParentColorChanged call to initialize), but applying DefaultUicontainerBackgroundColor probably makes more sense than inheriting from parent.

David Sampson

David Sampson (view profile)

Alexander, the MATLAB graphics defaults system cannot be extended to non-builtin classes, so we cannot support set(0,'DefaultHboxBackgroundColor').

However, we could decide to apply DefaultUicontainerBackgroundColor and/or DefaultUipanelBackgroundColor to new uix subtypes. What do people think?

I don't think that inferring (uix) container defaults from figure defaults is appropriate when there is a mechanism for setting (plain) container defaults.

David Sampson

David Sampson (view profile)

Alexander, on the uix.Empty background color initialization, you are right: I need to call onParentColorChanged, although this should be guarded with if ~isempty(obj.Parent).

Actually, even uix.Empty has a problem. It sets the listener which handles subsequent background color changes, but it does not initialize the background properly when created. Makes sense to add onParentColorChanged(obj) call at the end to do this. But more importantly, all other uix components should do this as well.

I presume you are aware of this problem, since uix.Empty has explicit code to handle it: event listeners and corresponding onParentChanged / onParentColorChanged callbacks, which set uicontainer background to match parent. Why is it not done for any other uix objects, e.g. in uix.mixin.Container?

Firstly, thank you for the great toolbox!

I have a problem with default background color. I recently upgraded to R2015b, and also running Matlab on Windows 2008 Server. Apparently this combination somehow results in Matlab initializing all figures with a weird pink-ish background ([0.94,0.94,0.94]), while all other UI components are dark gray. I can deal with that simply by setting:

set(0,'DefaultFigureColor', [214,211,206]/255);

And that works for all figures I create. However uix objects are inherited directly from matlab.ui.container.internal.UIContainer, and this results in the same pink-ish background. So I have to set background for literally each new uix object I create. Is there a way to make it respect the global background color I set?

Thanks David, I made the suggestion to the author. I am facing an issue with uix.Grid. I am plotting 12 pie charts, and there is too much empty space in each grid, even though I set spacing to zero. Can you suggest a solution?

Thanks

Adam

Adam (view profile)

Tanmay -> I usually embed uicomponents into a parent uipanel with no title or border and then parent that to the layout and then the layout will handle the panel fine.

e.g.

hSliderPanel = uipanel(...)
hSlider = uicomponent( 'Style', 'JSlider',...);
set( hSlider, 'Parent', hSliderPanel, 'Units', 'normalized', 'Position', [0 0 1 1];

I don't want to go into too much detail since this is somewhat outside of the realms of commenting on this specific toolbox, but that is the type of setup I use. I haven't worked with filechooser, but I assume you should be able to do something similar with it.

With regard to things being parented to non-figures, I actually just suppressed that warning because parenting by a panel does work, even straight up I think, but not with layouts, hence the above workaround for this.

David Sampson

David Sampson (view profile)

Tanmay, looking into the uicomponent code further, I see:
1. The doc says that only figures are supported as Parents, but the code tries to support uicontainers, uipanels, uitabs.
2. Checking for valid Parent is by string comparison on class name, rather than by isa. That is why it rejects GLT containers, which are uicontainer subclasses.

Please ask the author to add support for HG2 uicontainer subclasses by checking isa(hParent,'matlab.ui.container.Container'). This is an undocumented class, but that should make it more not less attractive to the author!

David Sampson

David Sampson (view profile)

Tanmay, I am not familiar with uicomponent, but I just downloaded it to run your reproduction steps. I see a warning that setting Parent of a uicomponent to a container rather than a figure is not supported:

Warning: Non-figure parent was specified - using the parent's figure as the component's parent

Adam - yes. How do you use it? set Widths in HBox does not recognize UIComponent. This doesnt work -

ImagePanel = uix.Panel('Parent', InfoTabPanel, 'Background', [1 1 1], 'Padding', 10);
ImageBox = uix.HBox('Parent', ImagePanel);
uix.Empty('Parent', ImageBox, 'Background', [1 1 1]);
uicontrol( 'Style','text','Parent',ImageBox,'String', 'GSR');
uicomponent('style','filechooser','Parent', ImageBox);
uix.Empty('Parent', ImageBox, 'Background', [1 1 1]);
set(ImageBox, 'Widths', [20 50 20 200], 'Spacing', 5 )

Because set Widths does not recognize UIComponent

Adam

Adam (view profile)

David -> I will try to put together a simple example that doesn't include all the dependencies my production code has.

Tanmay -> Do you mean Yair Altman's uicomponent file exchange submission? If so then I use that in conjuction with this toolbox quite often to embed java sliders.

uicomponent is really just an expansion of uicontrol so it shouldn't be in any way incompatible with this toolbox, though there are some pitfalls with combining java components with layouts that need to be avoided.

David Sampson

David Sampson (view profile)

Adam, can you please contact me directly with simple reproduction steps so that we can investigate.

Thanks David, I am having issue with TabPanel dividers, but it is not a real problem for me. I could not find display settings. One thing that would make this toolbox even more powerful is if you can use it in combination with UICOMPONENT toolbox. Is there any way?

Adam

Adam (view profile)

An excellent toolbox that I tend to use more often than GUIDE now for a new UI.

However, I do seem to be having a recurring problem with the right-hand edge of panels not rendering in a lot of circumstances. This seems to be only when I use the -1 variable size for the panel. e.g. my current UI has 3 panels alongside each other with -1 widths all sat inside a layout. If I set the figure width to certain values it renders fine, but with most widths the right hand edge of my panels (plus panels inside these 3) does not render.

This appears to be fixable if I make the panels a fixed size rather than variable though this is quite a restriction.

Is anyone else having this problem or know what might be causing it?

David Sampson

David Sampson (view profile)

Tanmay, I expect that this issue related to using Windows display settings other than 100%. (Check in Control Panel > Appearance and Personalization > Display.) Can you please confirm?

There were some changes in MATLAB in R2015b related to supporting high-DPI displays.
http://uk.mathworks.com/help/matlab/creating_guis/dpi-aware-behavior-in-matlab.html

As a result, I need to make some changes to BoxPanel and TabPanel, and hope to do so in the coming weeks. Your change will stop the error but you may notice that your TabPanel dividers don't look quite right.

Found the solution:
Change line 916 from
jData = repmat( jMask(5,:), [tabDivider.Position(4) 1] );
to
jData = repmat( jMask(5,:), [round(tabDivider.Position(4)) 1] );

Error using repmat
Replication factors must be a row vector of integers or integer scalars.

Error in uix.TabPanel/redrawTabs (line 916)
jData = repmat( jMask(5,:), [tabDivider.Position(4) 1] );

Error in uix.TabPanel/redraw (line 673)
obj.redrawTabs()

Error in uix.mixin.Container/set.Dirty (line 144)
obj.redraw() % redraw now

Error in uix.TabPanel/set.TabTitles (line 563)
obj.Dirty = true;

Error in FieldMaster (line 134)
FieldTab.TabTitles = {'Cutter', 'Bit', 'Run', 'Dull'};

This does not work for R2015b. I am getting error using repmat for some reason.

jvc

jvc (view profile)

Johannes - I think the problem you are describing is due to a known MATLAB issue. For a description of the problem see the bug report at:

https://www.mathworks.com/support/bugreports/1293244

The short form fix which worked for me (assuming you are compiling for windows) is to add this line to your code and recompile:

javax.swing.UIManager.setLookAndFeel('com.sun.java.swing.plaf.windows.WindowsLookAndFeel')

Johannes

Hi, another issue came up while creating an executable. All the buttons miss their borders. The text is displayed and I can also click on them but the button itself is invisible. Am I doing something wrong here?

Johannes

David, thank you very much! That solved my problem.

David Sampson

David Sampson (view profile)

Johannes, please take a look section 2.3 "colorbars and legends" of the GUI Layout Toolbox documentation. Please group your illustrations with their axes inside a uicontainer.

Johannes

I encountered some problems with legends in uix. I updated my software from Matlab 2014a to 2015b and therefore used uix instead of uicontrols. After some modifications it looks as beautiful as ever. However, it is not possible to display legends in a correct way. I used exactly the same code but the legend is not shown in the right plot even though the correct axes handle is provided. Instead it is shown as a separate HBox below my plots in the corresponding panel of my GUI. Any idea, what might go wrong here? Thank you for your help!

rodan sastras

hi how do I use this to edit my GUI .fig files?

Vinh Dang

Can I create a panel containing a uitabgroup with many uitabs?

David Sampson

David Sampson (view profile)

Alex, please review the release notes, which give a brief summary of which capabilities were added in which release.
http://www.mathworks.com/help/matlab/release-notes.html

There have been various new features and performance improvements including a new "MATLAB Execution Engine" in R2015b.

For GUI Layout Toolbox (v2), you can access all features from any release from R2014b.

Alex Perrone

I'm using the current version of toolbox with Matlab 2014b. As far as this toolbox is concerned, is there any compelling benefit to upgrading to Matlab 2015a or 2015b? e.g. speed improvements that would affect Gui Layout Toolbox in newer Matlab versions, or additional features.

David Sampson

David Sampson (view profile)

Amy, your question is a graphics question rather than a GUI Layout Toolbox question. plot is convenient but it has side effects including clearing the axes ButtonDownFcn. A couple of suggestions:
1. Write a lower level callback function that doesn't use plot
2. Use the axes event Hit rather than the axes callback ButtonDownCallback

Here's an example of #1:
>> a = axes();
>> l = plot( a, 0:10, rand( 1, 11 ) );
>> a.ButtonDownFcn = @(~,~)set(l,'YData',rand(1,11));

I am trying to implement a VBox with a fixed height child (a) followed by two proportional children (b, c). For the fixed height child (a) I would like the height to be set by the maximum height required by any of children of (a). I have written a function that descends through the children and keeps track the required height via child.Extent. The only problem I have is that for the life of me I can not find a way to determine how much height a Panel will add (title + border) on top of its contents BEFORE it is rendered. I know how to use hgconvertunits to calculate this after the panel has been rendered, but not before. Any ideas?

Amy Brisben

Hello, I am enjoying overhauling our GUI using your toolbox. One question, though: is it possible to update axes without deleting the axes object and re-creating it? (That is the method in demoBrowser.m and in the comments listed below). The problem that I have is, the axis has a 'ButtonDownFcn' that I want to be able to re-use, so I don't see why I should delete the object. The code example is:

%declare object
handles.dp= uix.BoxPanel( 'Tag', 'dataPlot', 'Title', 'Data Plot', 'Parent', handles.gui.leftDataBox);
handles.plotp= uipanel('Parent',handles.dp);
handles.Data_plot = axes('Parent',handles.dp,'ButtonDownFcn',@Data_plot_ButtonDownFcn,...);

... %(create data) ; this displays correctly the first time but not subsequent times.

subplot(handles.Data_plot);
plot(data, 'LineWidth', line_thickness);

I've tried to replace the "subplot" command with the line below (based on comments I've read here), but that didn't help.

set(gcf,'CurrentAxes',handles.Data_plot);

Thank you in advance, Amy

David Sampson

David Sampson (view profile)

Collin, h(1:n) = uix.HBox(...) creates a single HBox and a 1-by-n array of handles h with each element pointing to that same HBox. If you want to create multiple boxes then you need to do so in a loop.

Collin

Collin (view profile)

Having difficulties with arrays of uix objects.
What I want to do;

cnt = 40;
v = uix.VBox('Parent',figure);
h(1:cnt) = uix.HBox('Parent',v);
labels(1:cnt) = uicontrol('Style','edit',.....);
values(1:cnt) = uicontrol('Style','edit',....);

for i = 1:cnt
set(labels(i),'Parent',h(i), set other properties)
set(values(i),'Parent',h(i), set other properties)
end

The contents/ children property of the VBox only has a single HBox object.
Setting the parent property of the Hboxes inside the loop does not seem to
work, while setting everthing by brute force inside the loop does. Are
there empty objects I could be pre-allocating?

Collin

Luke Plausin

Luke Plausin (view profile)

Sid

Sid (view profile)

Regarding the error with the HButtonGroup Objects in the post-2014b world:

A shortcut I ended up using was to simply create a bunch of checkboxes on a VBox/HBox setup, and then control the appearance and functionality using a separate callback. Please see below:

function tabpanelMods()

close all
h = figure();

mainPanel_selectDurationPanel_VBox = uix.HBox(...
'Parent', h,...
'BackgroundColor' ,[0.9375 0.9375 0.9375],...
'Padding', 5,...
'Spacing', 5);


cb(1) = uicontrol(...
'Style','CheckBox',...
'Parent',mainPanel_selectDurationPanel_VBox,...
'String','Day',...
'Callback',{@bselection,h});

cb(2) = uicontrol(...
'Style','CheckBox',...
'Parent',mainPanel_selectDurationPanel_VBox,...
'String','Week',...
'Callback',{@bselection,h});

cb(3) = uicontrol(...
'Style','CheckBox',...
'Parent',mainPanel_selectDurationPanel_VBox,...
'String','Month',...
'Callback',{@bselection,h});

cb(4) = uicontrol(...
'Style','CheckBox',...
'Parent',mainPanel_selectDurationPanel_VBox,...
'String','6 Month',...
'Callback',{@bselection,h});

cb(5) = uicontrol(...
'Style','CheckBox',...
'Parent',mainPanel_selectDurationPanel_VBox,...
'String','1 Year',...
'Callback',{@bselection,h});


cb(6) = uicontrol(...
'Style','CheckBox',...
'Parent',mainPanel_selectDurationPanel_VBox,...
'String','All!!!',...
'Callback',{@bselection,h});


function bselection(source,callbackdata, h)

cb_name = source.String

setappdata(h,'DurationName',cb_name)

switch cb_name
case 'Day'
cb(1).Value = 1;
cb(2).Value = 0;
cb(3).Value = 0;
cb(4).Value = 0;
cb(5).Value = 0;
cb(6).Value = 0;

case 'Week'
cb(1).Value = 0;
cb(2).Value = 1;
cb(3).Value = 0;
cb(4).Value = 0;
cb(5).Value = 0;
cb(6).Value = 0;

case 'Month'
cb(1).Value = 0;
cb(2).Value = 0;
cb(3).Value = 1;
cb(4).Value = 0;
cb(5).Value = 0;
cb(6).Value = 0;

case '6 Month'
cb(1).Value = 0;
cb(2).Value = 0;
cb(3).Value = 0;
cb(4).Value = 1;
cb(5).Value = 0;
cb(6).Value = 0;

case '1 Year'
cb(1).Value = 0;
cb(2).Value = 0;
cb(3).Value = 0;
cb(4).Value = 0;
cb(5).Value = 1;
cb(6).Value = 0;


case 'All!!!'
cb(1).Value = 0;
cb(2).Value = 0;
cb(3).Value = 0;
cb(4).Value = 0;
cb(5).Value = 0;
cb(6).Value = 1;
end

% You can hopefully use the setappdata capability to set up additional information to be
% accessed by other functions. Use getappdata(h,'DurationName') in a different function to
% get the value of duration, which was originally set for example.
end
end

It is very much a poor man's brute force solution, but it works. As is mentioned in the example, simply use setappdata/getappdata functionality to extract selection changes.

HTH.

jvc

jvc (view profile)

For quite a while I have been encountering an error which I cannot get rid of and wonder if anybody else has an insight. The error is associated with having a gui layout figure which contains as one of the elements a table (created via uitable. All works correctly until I have the gui running and leave it 'idling' for some period of time. The time required for the error to appear is unpredictble but ranges from ~30 mins to a couple of hours. The error streams a couple of pages of messages of which I have copied only the first few lines below. It is also not clear that aside from the error anything else that bad actually happens as a result of this error - the gui continues to function although the contents of the table will usually be empty and need to be refreshed after the error occurs. I usually restart on general principles but do not know for sure that this is needed. For what it is worth, I have very similar gui's created in Guide which have never shown this behavior. I am currently running Win7, R2014B but the error has been around at least as far back as 2013B. Any suggestions would be welcome.

Error message (first 8 lines of ~70)

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at com.sun.java.swing.plaf.windows.WindowsTableHeaderUI$XPDefaultRenderer.paint(Unknown Source)
at javax.swing.CellRendererPane.paintComponent(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
at javax.swing.plaf.ComponentUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)

David Sampson

David Sampson (view profile)

Bei Liu, the help browser freezing is a known MATLAB issue that has been addressed for R2015b.

bei liu

Great toolbox!
One problem: every time I want to review the help file in Matlab, Matlab will be dead. I'm not sure whether it's just my problem. I'm using R2015a

Thank you for this great toolbox!

I would like to be able to set the maximum height and maximum width of the Grid, VBoxFlex and HBoxFlex. Is it possible to add properties MaximumHeights and MaximumWidth to do it (or is there another way to do it ?).

David Barry

Fantastic

David Sampson

David Sampson (view profile)

Eric, HG2 prior to R2014b is not supported. For use prior to R2014b, download GUI Layout Toolbox version 1; the link is in the submission description above.

David Sampson

David Sampson (view profile)

Carsten, the doc browser hang is a known MATLAB issue that is being addressed for the R2015b release.

jtrunnels

Works beautifully.

One minor bug: uix.BoxPanel does not work in the 2015b prerelease with non-standard DPI settings.

Hi kp

thanks for the quick relay/hint. But it doesnt work.

Even more worse: when I start the doc command from within the Command Window and type tabpanel I see a lot of entries. Selecting the first one crashes Matlab (R2015a)! Matlab doesnt show any response and must be shut down using the task manager.

After relaunching Matlab I get the message:

Warning: MATLAB Toolbox Path Cache is out of date and is not being used.
Type 'help toolbox_path_cache' for more info

A inspection shows that 'Enable toolbox path cache' is still selecting.

Again, after relaunching Matlab I observe the same behaviour.

Has anyone an idea how to overcome this issue
Thanks in advance

kp

kp (view profile)

I had a similar issue with my code. I believe the name has changed to SelectionChangedFcn in the latest version of the toolbox. You may have a mismatch between the example file and the toolbox.

applying: tabpanelexample

I always get the error message:
Error using uix.TabPanel/set
There is no SelectionChangeCallback property on the TabPanel class.

Error in tabpanelexample (line 36)
set( tabpanel, 'SelectionChangeCallback', @(a,b) set( panellist, 'Value', b.NewValue ) );

what's wrong (I'm using Matlab R2015a 32bit)?

applying: tabpanelexample

I always get the error message:
Error using uix.TabPanel/set
There is no SelectionChangeCallback property on the TabPanel class.

Error in tabpanelexample (line 36)
set( tabpanel, 'SelectionChangeCallback', @(a,b) set( panellist, 'Value', b.NewValue ) );

what's wrong?

Eric

Eric (view profile)

Ok, I realize I'm being difficult working in the version grey zone, but I'm running in 2014a in hg2 mode. I get errors with the 2014a version (p17) doing this (which I expected) and am having trouble installing the 2014b+ version (2.1.2)because I haven't found a way to install a toolbox in 2014a. Any suggestions? Anyone tried this. Waiting for 2015b to upgrade.

David Sampson

David Sampson (view profile)

>> help uix.TabPanel

"From R2014b, MATLAB provides uitabgroup and uitab as standard components. Consider using uitabgroup and uitab for new code if these meet your requirements."

This will not suit if your code has to run pre-R2014b or if you need to be able to disable tabs.

David Sampson

David Sampson (view profile)

For those reporting problems with TabPanel in standalone applications, can you please contact me directly with simple reproduction steps so that we can investigate.

Carsten

One way to replace crashing TabPanel-code:

% Using uitabgroup and uitab (no crash in standalone):

TabNames = {'M1', 'U2', 'R3', 'K4', 'P5'};

tabAnalyte = uitabgroup(hbox, 'Tag', 'tabAnalyte', 'SelectionChangedFcn', @(src,evnt)onTabAnalyteSelection(src,evnt, gui.Window));
for i = 1:numel(TabNames)
htab(i) = uitab('Parent', tabAnalyte, 'Title', TabNames{i});
end

% in "onTabAnalyteSelection"
Tab = src.SelectedTab.Title;
switch Tab ... end

% Using uiextras.TabPanel and uipanel (CRASHES in standalone):

TabNames = {'M1', 'U2', 'R3', 'K4', 'P5'};

tabAnalyte = uiextras.TabPanel('Parent',hbox,'Tag','tabAnalyte','Callback',@(src,evnt)onTabAnalyteSelection(src,evnt, gui.Window));
for i = 1:numel(TabNames)
htab(i) = uipanel('Parent', tabAnalyte, 'BorderType','none');
end
tabAnalyte.TabNames = TabNames;
tabAnalyte.TabSize = 120;

% in "onTabAnalyteSelection"
Tab = src.TabTitles{evnt.SelectedChild};
switch Tab ... end

@Alex, I didn't know that TabPanel was failing in compiled application so I guess I got lucky. I'm using 2014b and the main reason to use uitab was to make the code as supported as possible and not overusing the GUILayout components

Mauritz

TabPanel also fails for me in compiled applications - works fine from code.

Alex Perrone

@Sergio, very good to know. So basically, you used uitab instead of TabPanel everywhere? Is there some reason you went with uitab as opposed to TabPanel? I.e. do you know that TabPanel is the thing that fails in compiled applications?

@Carsten, @Yannick, I extensively use this toolbox with Matlab newly supported uitab in compiled applications and they work without a problem.
PD: Include Yair Altman's tips here to customize those uitabs: http://undocumentedmatlab.com/blog/uitab-colors-icons-images

Yannick

@Carsten: I have reported the same issue with deployed GUI's, but since uitab are now officially supported in 2014b you can just use that until a fix... (soon I hope ?)

Carsten

@Alex Perrone: When I run a stand-alone GUI it always crashes when I change to (some) tabs.

See the Mathworks citation in my post 22 Jun 2015 below.

I'm now considering MatPi ...

Alex Perrone

For a standalone GUI with many components (several tabs, many nested Panels/HBox's/VBox's, several plot figures, a table, etc.), changing each tab is very *slow*. Any tips to improve the speed of changing tabs?

Dani

Dani (view profile)

I seem to remember that in previous versions the divider marks used to show up in Flex objects only when relative sizes were specified. Now they always show up. How do I specify that some of the children of Flex object have a fixed size?

Carsten

An important note to users of the GUI Layout Toolbox:

There's "a bug in how callbacks in combination with Java components (as used by the GUI Layout Toolbox) interact in standalone applications. There are no direct workarounds for this issue in your current MATLAB version (R2015a) other than not making use of the graphical components of the GUI Layout Toolbox. The issue should be resolved in the upcoming R2015b release of which a prerelease version is already available for download."

David Sampson

David Sampson (view profile)

Tianhan, thanks for the bug report, it will be fixed in the next release.

Tianhan

@David Sampson, Bug report.
There is a minor bug (typo) in the uix.BoxPanel class. According to the help doc and example, it has a property named 'IsMinimized', however it is actually named as 'Minimized'. Thus when running the 'minimizeexample.m', error occurs, indicating no appropriate method, property, or field 'IsMinimized' for class 'uix.BoxPanel'.

Jason

Jason (view profile)

I've created GUIs using the toolbox built before 2014b, if I install this newer version of the toolbox and upgrade Matlab to 2015a, will I need to go through the gui creating code and update calls to the toolbox or should I be ok?

David Sampson

David Sampson (view profile)

The R2015b MathWorks prerelease is now available. Our tests indicate that there is an issue with TabPanels. We are investigating.

David Sampson

David Sampson (view profile)

Version 2.1.2 contains a few minor bug fixes.

Tianhan

I am just finding something that could match QT to let me do project prototyping directly within MATLAB. Thanks!

Igor

Igor (view profile)

Wow, it's very nice that GUI layout is alive!

I'd like to report the following minor issue (or.. is it "by design"?). In the following code, invisible VButtonBox got visible when additional BoxPanel in created:

===================================

hfigure = figure( );

b1 = uix.VBoxFlex( 'Parent', hfigure );
b11 = uix.BoxPanel('Parent',b1,'Title','BoxPanel1');
b111 = uix.VButtonBox('Parent',b11,'Visible','off');
b1111 = uicontrol('Parent',b111,'Style','checkbox','String','invisible checkbox');

b12 = uiextras.BoxPanel('Parent',b1,'Title','By creating this, we also make b1111 visible');

===================================

David Sampson

David Sampson (view profile)

jvc, investigations into supporting saving and loading of GUI Layout Toolbox containers are ongoing. However, the normal workflow is to write code that creates the GUI and run that each time.

jvc

jvc (view profile)

Apologies for multiple postings - I am having difficulties submitting this comment...

I have encountered a serious error when reloading figures saved using the code snippet shown below:

hfig = figure;
vb = uix.HBox('Parent',hfig);
ctr = uicontainer('Parent',vb);

When the resulting figure from this code is saved to disk and then reloaded it results in an immediate hard crash of MATLAB (R2014B, 32 bit or 64 bit, GUI Layout v2.1, Win7).

Has anybody else encountered this problem or even better know how to fix it?

Ian

Ian (view profile)

The changelog for 2.1.1 (from the release notes)

Added context menus on uix.TabPanel tab labels (G1245669)
Fixed G1164656 "cannot set relative tab widths"
Fixed G1019441 "property RowSizes of uiextras.GridFlex sets heights not widths"
Fixed G1165274 "missing properties RowSizes, MinimumRowSizes, ColumnSizes, MinimumColumnSizes of uiextras.Grid, uiextras.GridFlex"
Fixed G1218142 "contents are lost when reordering via property Children"
Protected against G1136196 "segv when setting child visibility from 'off' to 'on' in response to being reparented
Minor fixes to documentation

Noise

Noise (view profile)

Carsten

Is it true that the GUI Layout Toolbox doesn't support radiobuttons and togglebuttons!?

I have downloaded the "uiextras.HButtonGroup" but when I run the example:

f = figure;
vb = uiextras.VBox('Parent',f);
bgH = uiextras.HButtonGroup('Parent',vb,'Buttons',{'1','2','3'},'Spacing',50,'Padding',10,'SelectedChild',1,'SelectionChangeFcn',@onSelectionChange);

I get the error message:

"Error using uiextras.ButtonGroup/set.SelectedChild (line 84)
The selected child value 1 exceeds the number of controlled children: 0"

Can anybody help?

Richard

@Tom
If you change

ax = axes('parent',cp);
to
ax = axes('parent',uicontainer('Parent',cp));

This might fix your problem.

It appears that when you specify a Parent for an axes within the GUI Layout Toolbox it must be within a uicontainer to function correctly.

Carsten

Is there an easy way to create tables with the GUI Layout Toolbox?

And can anyone post some examples?

Alex Chapin

Did anyone address Carsten's question from January 7th? I'm having a similar issue.

Sergei P.

An absolute pleasure to work with this toolbox after using GUIDE.

Adam Filion

Adam Filion (view profile)

Jonathan

Jonathan (view profile)

This toolbox is excellent. The documentation via "doc uiextras" a little scarce, a very good introduction (I would say a must-read) can be found in the previous version of the toolbox in "layoutHelp/User guide.html".

Ian

Ian (view profile)

Anyone who is having crashes in 2014b loading figures, beware uix objects can be the cause of this, make sure you remove any uix objects before saving. A fix is apparently in the works.

Bryant

Bryant (view profile)

Bug in uiextras.GridFlex set.RowSizes accessor. It sets Widths instead of Heights.

Tom

Tom (view profile)

As I said before, great submission.

I'm coming across strange behaviour with legends and uix. See the following example code which will reproduce the issue. Basically, axis within a uix will disappear when issuing the legend command.

% 2014b - The legend resets the axes and the axes and legend not visible.
f = figure;
cp = uix.Panel('parent',f);
ax = axes('parent',cp);
axes(ax)
plot(1:10,1:10);
legend('this is legend')

% 2014b - The legend and axes appears fine.
f = figure;
cp = uipanel('parent',f);
ax = axes('parent',cp);
axes(ax)
plot(1:10,1:10);
legend('this is legend')

jjs

jjs (view profile)

Great toolbox!

There seems to be a typo in tabpanelexample.m, line 36:
SelectionChangeCallback needs to be SelectionChangedCallback.

Adam Wyatt

Top notch! I use this all the time and congrats on the rapid migration to R2014b!

Documentation issues:
IsDocked / IsMinimized --> Docked / Minimized - need to change on the advanced manoeuvres section too.

Calling convention for DockFcn / MinimizeFcn is not clear - i.e. does it follow the same as other callbacks (i.e. requires two parameters: hObject & callbackdata for function handle calling)?

Getting the documentation is annoying - for example typing doc uix just brings up the class help, not the very well made documentation, so I have to load up the index.html file which is a little inconvenient.

Mauritz

Ryan

Ryan (view profile)

Documentation for TabPanel sizes says:
TabPanel.TabSize
but is actually:
TabPanel.TabWidth

Gary

Gary (view profile)

I tried to run the example "guideApp" which comes along with this toolbox (R2014b).
However I always get an error messages like this:

Error using uiextras.Container (line 66)
Trying to run using double-handle MATLAB graphics against the new graphics system. Please re-install.

Error in uiextras.Grid (line 66)
obj@uiextras.Container( varargin{:} );

Error in uiextras.GridFlex (line 58)
obj@uiextras.Grid( varargin{:} );

Error in guideApp>guideApp_OpeningFcn (line 64)
g = uiextras.GridFlex( 'Parent', handles.uipanel1, ...

Error in gui_mainfcn (line 220)
feval(gui_State.gui_OpeningFcn, gui_hFigure, [], guidata(gui_hFigure), varargin{:});

Error in guideApp (line 44)
gui_mainfcn(gui_State, varargin{:});

Using the same GUI toolbox (R2014b) but for the matlab release R2014a it works fine.

What do I wrong? What means re-install?

Carsten

Jamie

Jamie (view profile)

Stephane, I experienced something similar, not quite the same thing but I think it's related, and the fix was using a regular uipanel.

I tried your example with a regular uipanel instead of BoxPanel and it doesn't reset itself when resizing. I can't say if this is a bug in BoxPanel or not but either way using a uipanel could be a workaround if it must not reset itself when resizing.

You can also insert a uipanel between the BoxPanel and the Grid to prevent resetting of children, like so:

fig = figure(42); clf;
bp = uiextras.BoxPanel('Parent', fig, 'Title', 'toto');
uip = uipanel('Parent', bp, 'BorderWidth', 0);
g = uiextras.Grid('Parent', uip, 'Visible', 'off');
uicontrol('Parent', g);
uicontrol('Parent', g);

Heather

edit: I did a bit more testing, and I replicate the bug as follows: 1 figure with a TabPanel. The TabPanel has 2 tabs; the first has a uitable, the second has 2 axes. (With just 1 axes, nothing crashes.)

Heather

I have a GUI using tabs that works fine when called from the Matlab command line. However, once I compile it, trying to change tabs crashes the program. Is this a known bug? It may not be due to the toolbox, but I thought I'd check.

Citizen Insane

Another small issue when migrating from R2013b to R2014b. HG2 implies a lot of changes, of course :). Anyway, this toolbox is truly a must have to design appealing/modern interfaces!

% This works with V1 (in R2013b)
fig = figure(42); clf;
bp = uiextras.BoxPanel('Parent', fig, 'Title', 'toto');
g = uiextras.Grid('Parent', bp, 'Visible', 'off');
uicontrol('Parent', g);
uicontrol('Parent', g);

% With V2.1 - Rev 1011 (in R2014b)
% The visibility is 'off' until the figure is resized (visibility suddenly changes to 'on')
fig = figure(42);
clf;
bp = uix.BoxPanel('Parent', fig, 'Title', 'toto');
g = uix.Grid('Parent', bp, 'Visible', 'off');
uicontrol('Parent', g);
uicontrol('Parent', g);

Romain

Romain (view profile)

First, thank you for this excellent toolbox

I just want to submit a bug using +uix.VButtonBox and +uix.HButtonBox:
It is documented that there is an "Enable" property, but setting this property I have the following issue : "There is no Enable property on the VButtonBox class".
Any idea about this issue ?
Thanks in advanced !

Citizen Insane

There are a few issues for backward compatibility when still using +uiextras. For instance 'set' commands for 'ColumnSizes/RowSizes' are no longer recognized and one must use 'Widths/Heights' from +uix. Same for 'BorderType', one must use 'none' as 'None' is no longer working. Else from that this is an excellent toolbox.

Amro

Amro (view profile)

This is seriously one of the best submissions on File Exchange!

I've been browsing the code, and I can see that it's finally possible in R2014b to subclass MATLAB uicontrols (uix.Container in v2 inherits from matlab.ui.container.internal.UIContainer, instead of being a wrapper as in v1)!

However whenever I try this with my own classes, I get an error that "Class 'MyControl' is not an allowed subclass of class 'matlab.ui.container.internal.UIContainer'."... Are your classes hardcoded in MATLAB as allowed subclasses, but no one else??

zxc

zxc (view profile)

Jamie

Jamie (view profile)

Thank you for the feedback, I think this may help folks in understanding the distinction between uipanel and uiextras.Panel, in particular not setting the position of GLT containers. In cases where manual positioning is desired, use a regular uipanel. Below is an example, related to the difficulty I was having and demonstrating the position clobbering that David is referring to:

w = figure(75);
g1 = uiextras.GridFlex('Parent', w);

c11 = uiextras.Panel('Parent', g1, 'BackgroundColor', [0.95, 0.95, 0.95]);
c12 = uiextras.Panel('Parent', g1, 'BackgroundColor', [0.95, 0.95, 0.95]);
c21 = uiextras.Panel('Parent', g1, 'BackgroundColor', [0.95, 0.95, 0.95]);
c22 = uipanel('Parent', g1, 'BackgroundColor', [0.95, 0.95, 0.95]);

set(g1,'RowSizes',[-1 -1],'ColumnSizes',[-1 -1]);

x = 0:pi/100:2*pi;
y = sin(x);

a1 = axes('Parent', c11, 'Units', 'Normalized', 'Position', [.25, .25, .5, .5]);
plot(x, y);

a2 = axes('Parent', c22, 'Units', 'Normalized', 'Position', [.25, .25, .5, .5]);
plot(x, y);

Beatriz

I apologize, since I believe my question indicates what a novice I am to Matlab.

I continue to get this error message when trying to use ay commands in matlab window using spm 8:

No method 'delete' with matching signature found for class 'matlab.ui.control.UIControl'.

Error using waitfor
Error while evaluating UIControl Callback

Any guidance would be greatly appreciated

Carsten

Thank you, David.

It solved my problem:

if use_extra
vbox = uiextras.VBoxFlex('Parent', window, 'Spacing', 3);
hp1 = uipanel('Parent',vbox);
axes1 = axes( 'Parent', hp1);
hp2 = uipanel('Parent',vbox);
axes2 = axes( 'Parent', hp2);
set( vbox, 'Sizes', [-5 -4] );
else
axes1 = subplot(211);
axes2 = subplot(212);
end

David Sampson

David Sampson (view profile)

Carsten, there are issues with handling illustrations (legend, colorbar) and rotate3d with the new graphics system. The challenge is identifying graphics objects that should be ignored for layout purposes. We are making progress but there are some small changes that are also required in MATLAB itself. Until then, the workaround is to place axes with illustrations and 3D-rotating axes in a uicontainer (or uipanel with decorations turned off), as described in the GUI Layout Toolbox documentation.

David Sampson

David Sampson (view profile)

Jamie, you shouldn't be setting the Position of GLT container contents directly. Any changes that you make will be clobbered by the toolbox code. If you feel that there are differences in layout behavior between v1 and v2 then please contact us directly and we will investigate.

David Sampson

David Sampson (view profile)

Thanks to Gary and Jamie for spotting some minor bugs. The fixes have been implemented and will be included in the next release.

Gary

Gary (view profile)

Looks like there's a tiny error in the dockexample demo - there is no .IsDocked property/method for the panel, the correct property/method is .Docked

Yannick

Hi David,

How would you copy uix objects into new figures ?

I tried "copyobj" but the children/contents do not behave well in the copied objects.

Is there an easy trick ?

Thanks!

Kim

Kim (view profile)

There is a difference between the TabPanel in this version and the older version. The vertical alignment of TabTitles are on the top now. Is it possible to align them in the centre of the tab like the old version?

Jamie

Jamie (view profile)

Sorry for the spam, it appears there is an error with mapping ColumnSizes and RowSizes to Widths and Heights. It appears they are backwards and ColumnSizes does not work. The example in the documentation exhibits this problem:

f = figure();
g = uiextras.GridFlex( 'Parent', f, 'Spacing', 5 );
uicontrol( 'Parent', g, 'Background', 'r' )
uicontrol( 'Parent', g, 'Background', 'b' )
uicontrol( 'Parent', g, 'Background', 'g' )
uiextras.Empty( 'Parent', g )
uicontrol( 'Parent', g, 'Background', 'c' )
uicontrol( 'Parent', g, 'Background', 'y' )
set( g, 'ColumnSizes', [-1 100 -2], 'RowSizes', [-1 -2] );
% works with the following:
% set( g, 'Widths', [-1 100 -2], 'Heights', [-1 -2] );

Jamie

Jamie (view profile)

Nevermind my previous comment, this behavior is common between v1 and v2. In particular:
figure();
panel1 = uiextras.Panel();
a1 = axes('Parent', panel1, 'Tag', 'p1');
set(a1, 'Units', 'normalized');
set(a1, 'Position', [ 0.06 0.13 0.9 0.75 ]);

What I am struggling with is how to preserve normalized position across resize events?

There are some layout differences in v2 which I am trying to correct by specifying the position explicitly.

Ralph Coleman

Reply to Markus: Here is an example showing the use of uitabgroup within the layout, and also uitree (that may well become an "official" uicontrol one day):
% Create figure in centre of screen
scr_size = get(0,'ScreenSize');
Fig_h = figure('MenuBar','none','Name','Main GUI figure',...
'OuterPosition',[scr_size(1:2)+50 scr_size(3:4)-100],'Tag','GUI_Fig');

% Create tree control nodes including the root
node1 = uitreenode('v0', 'BMW', 'BMW', [], false);
node2 = uitreenode('v0', 'Audi', 'Audi', [], false);
node3 = uitreenode('v0', 'VW', 'VW', [], false);
root = uitreenode('v0','German cars','German cars',[],false);
root.add(node1);
root.add(node2);
root.add(node3);

% Create the tree control
[~,treecontainer] = uitree('v0','Parent',Fig_h,'Root',root);

% Arrange the main interface
vertLayout = uix.VBoxFlex('Parent',Fig_h,'Spacing',5);
horzLayout = uix.HBoxFlex('Parent',vertLayout,'Spacing',5);
messagePanel = uix.BoxPanel('Parent',vertLayout,'Title','Messages');
treePanel = uix.BoxPanel('Parent',horzLayout,'Title','Object browser');
viewPanel = uix.BoxPanel('Parent',horzLayout,'Title','Viewing');
viewContainer = uicontainer('Parent',viewPanel);

% Adjust the main layout
uicontrol('Parent',messagePanel,'Style','edit','Backgroundcolor','w', ...
'Tag','Messages','Max',1000,'HorizontalAlignment','left','String','Message 1');
set(treecontainer,'Parent',treePanel);
set(vertLayout,'Heights',[-4 -1]);
set(horzLayout,'Widths',[-1 -1]);
tabgp = uitabgroup(viewContainer);
tab1 = uitab(tabgp,'Title','View 1');
tab2 = uitab(tabgp,'Title','View 2');

This is a great toolbox for GUI design!

Jamie

Jamie (view profile)

I have a complex GUI built for version 1 of this toolbox and under the new version it is having a problem.

I have traced it down to what appears to be an issue with units. The units in the axes are set to be normalized, but when the GUI is resized (or rendered for the first time when a hidden tab is selected) the units are converted to pixels and the sizes are wrong.

I am not sure if it is relevant, but the old version used
uiextras.set(gui.window, 'DefaultPanelUnits','normalized');
which now shows a warning.

If it is helpful, I can probably construct a simplified example showing this behavior.

Markus

Markus (view profile)

Great Toolbox, but i have some starting issues. Is there an example where i can use the 2014b uitab with this? Or should i just just the tab panel from this toolbox?

Jia-Jung

David Sampson

David Sampson (view profile)

Jonathan, good catch, I will implement support for negative (relative) TabWidth as soon as possible.

Jonathan

This is an excellent little package, unfortunately in the 2014b I can no longer set my TabPanel TabWidth property to -1, but have to use a positive scalar meaning it no longer scales as I drag my window. Is there an easy work around for this?

Tom

Tom (view profile)

Thanks for clarifying this David - I can code round it no problem. I suspect your workaround will be fine in most cases.

David Sampson

David Sampson (view profile)

Tom, we have removed the enable/disable functionality at this stage due to challenges with the implementation, although we are open to working on it some more. Property 'Enable' is included in the uiextras package to support legacy code, although it no longer has any effect. The demo 'enableexample' should have been removed and will be from the next release.

I encourage anyone with enable/disable use cases to get in touch. Specifically, I am interested in cases where more than set( findall( c, 'Type', 'uicontrol' ), 'Enable', v ) is needed.

Tom

Tom (view profile)

Great submission guys. Just getting up to speed with 14b, and your version 2.1. I'm spotting some problems with Enable, in that it is not cascading down to children from Panels and Boxes. In fact if I run the demo enableexample.m on R2014b Im getting the following error

>> enableexample
Error using uix.BoxPanel/set
There is no Enable property on the BoxPanel class.
Error in enableexample (line 27)
set( panel, 'Enable', 'off' );

which suggests Enable not implemented....

David Sampson

David Sampson (view profile)

David, the version of the published mltbx file (1.0) is incorrect although the version of the submitted mltbx file (2.1) was correct. We are investigating. There is no impact on functionality although we would like to have this issue resolved before we release the next update.

David Sampson

David Sampson (view profile)

David, your question is addressed in the subsection "Contents property" in the section "compatibility considerations" of the GUI Layout Toolbox release notes:

The contents of version 1 objects were accessible via the property Children. The contents of version 2 objects are accessible via the property Contents. Version 2 objects also provide a property Children, but this controls the vertical stacking order rather than the layout order. Legacy code that accesses Children will run without error, but will not achieve the desired change in layout order, and should be modified to access Contents instead.

An upcoming release of version 1 will include support for code that references contents via Contents. That way, code modified to work in version 2 will also work in version 1.

The background to this change is as follows. Version 1 objects were wrappers for built-in graphics objects, and presented contents in layout order via the property Children. Version 2 objects extend built-in graphics objects, and as such, inherit properties, methods and events. One such property is Children which is used to control the top-to-bottom stacking order. MATLAB stacking rules, e.g. controls are always on top of axes, mean that some reasonable layout orders may be invalid stacking orders, so a new property for layout order is required.

David Sampson

David Sampson (view profile)

Benoit, we conducted a review of the v1 API and decided that there were a few things that we would change if we had our time again: names, shapes, etc. The result is v2 uix, with uiextras provided for compatibility. Our recommendations are:
* use uix for new code that only has to work from 14b onwards
* use uiextras for old code or for new code that has to work against both v1 prior to 14b and v2 from 14b onwards

David Barry

David, Ben,

It appears that you have reversed the order of children in this release compared to pre R2014b release. I have only tested it on a VBox but they are definitely in the reverse order. Shoot me down for bad practice but I have some legacy code which relies on the order so as you can imagine I am somewhat annoyed.

The following simple example demonstrates the issue. The order returned is button1, button2 in version 1 of GLT but is button2, button1 in version 2 of GLT. I assume there is a genuine reason for the reversal?

v = uiextras.VBox;
b1 = uicontrol('Parent', v, 'String', 'Button1');
b2 = uicontrol('Parent', v, 'String', 'Button2');
for ii = 1:numel(v.Children)
disp(get(v.Children(ii), 'String'));
end

Bryant

Bryant (view profile)

Thanks for being so quick on this!

David Barry

David, Ben,

The version information included in the toolbox package reports this as being Version 1.0 rather than 2.x

Thank you David,

My work around was to use an HBox, the uicontainer is more elegant and easier to implement though.

backward compatibility looks really good so far. Is there any advantage in updating old code from uiextras. to uix. ?

David Sampson

David Sampson (view profile)

At present, it is difficult to support laying out axes in two cases:
(1) axes with illustrations (legends, colorbars)
(2) 3D rotating axes

The workaround is to place such axes within a uicontainer within the GUI Layout Toolbox container (c1 and c2 in the code below):

f = figure();
b = uix.HBox( 'Parent', f );
c1 = uicontainer( 'Parent', b );
a1 = axes( 'Parent', c1 );
[x, y, z] = peaks( 15 );
surf( a1, x, y, z )
c2 = uicontainer( 'Parent', b );
a2 = axes( 'Parent', c2 );
surf( a2, y, x, z )
rotate3d( f, 'on' )

We are working with our colleagues in development to remove the need for the intermediate container.

Although this issue is mentioned in the documentation, we will highlight known limitations more prominently in a forthcoming release.

David, Ben,
thank you very much for sharing your hard work.

a 3d figure plotted within a panel diseappears when activating rotate3d:

f=figure;
axPanel = uiextras.Panel('Parent', f);
hAxes = axes('Parent', axPanel);
[X,Y] = meshgrid(-2:.2:2, -2:.2:2);
Z = X .* exp(-X.^2 - Y.^2);
surf(X,Y,Z)
rotate3d on

this works fine under v1 in 2013b

Dani

Dani (view profile)

In v1 the uiextras objects seem to inherit the default background color of uipanels, which can be set by e.g.
set(0, 'DefaultUipanelBackgroundColor', 'r')
How do I achieve the same in v2?

Ben Tordoff

Ben Tordoff (view profile)

Hi Ian, thanks for spotting that - I've fixed it for the next update. The doc is still a bit in-progress but if you spot other errors let us know (you can contact us directly if you don't want to post everything you find publicly).

Ian

Ian (view profile)

Hi, just a reminder that several properties have changed if you want to switch your uiextras to uix, but the documentation is not yet up-to-date (i.e. TabPanel>TabSize property etc.), so check the class files themselves for the property names.

Updates

2.3.1

* Specify minimum width and height of contents in uix.ScrollingPanel
* Update contents position while dragging uix.ScrollingPanel scrollbox
* Scroll uix.ScrollingPanel using mouse wheel

2.3

* Added scrolling panel
* Expand and collapse box panel by clicking on title
* Fixed G1493103 "Error on construction behavior is inconstistent with builtin objects"

2.2.2

* Fixed G1175938 "Cannot use data cursor mode with GUI Layout Toolbox containers"
* Fixed G1367337 "Update flex container pointer on mouse press event"
* Fixed G1380756 "Space behind TabPanel tabs should match parent color"

2.2.1

Bug fixes

2.2

* Improved box panel title bar appearance
* Changed selection behavior of uix.TabGroup to match that of uitabgroup when the selected tab is removed
* Bug fixes (see release notes)

2.1.2

Bug fixes

2.1.1

Removed HTML tags from description since File Exchange does not render markup. No changes to the submission itself.

2.1.1

Version 2.1.1 fixes several bugs in version 2.1.

MATLAB Release
MATLAB 9.1 (R2016b)

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video

Win prizes and improve your MATLAB skills

Play today