Code covered by the BSD License  

Highlights from
GUI Layout Toolbox

4.89011

4.9 | 113 ratings Rate this file 334 Downloads (last 30 days) File Size: 646 KB File ID: #27758
image thumbnail

GUI Layout Toolbox

by

 

27 May 2010 (Updated )

Layout management objects for MATLAB GUIs

Editor's Notes:

This file was selected as MATLAB Central Pick of the Week

| Watch this File

File Information
Description

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
   * Ability to mix fixed size and variable size elements
   * Dynamic resizing of elements by dragging dividers
   * Use panels and tabs for switching interface pages

Documentation is included and is integrated into the MATLAB Help Browser. It can also be viewed as a stand-alone web-page.

These layouts are designed to be extensible. A good example of how to do this is Matt Whitaker's ButtonGroups:
http://www.mathworks.com/matlabcentral/fileexchange/31902

This toolbox was developed by Ben Tordoff and David Sampson from the Consulting group at MathWorks.

Acknowledgements

This file inspired Overlay Table, 3 D Slicer, Image M, Button Group Objects, Flow Cytometry Gui For Matlab, Dynamical System Viewer, Volumetric Data Explorer, and A Gui For Plate Reader Growth Curve Analyses.

MATLAB release MATLAB 7.10 (R2010a)
Tags for This File   Please login to tag files.
Please login to add a comment or rating.
Comments and Ratings (295)
16 Aug 2014 Igor

I've just spotted one more cosmetic issue in "04 Mar 2014" version: Lines 35,36,37 in "dockexample.m" seem to be unnecessary - they just duplicate lines 16,19,22.

11 Aug 2014 Dan K

William,
If, like me, you use the command line to do your compilations, see the hint that Andreas gave me on 30 May 2014 for how to include it in the command line.
Dan

10 Aug 2014 David Sampson

William, the error message indicates that you did not include the relevant image file(s) in the deployed application. The GUI Layout Toolbox documentation includes an explanation of how to do this.

08 Aug 2014 william

Hi, Dan

Thanks for your help. I did as you suggested. The error appears when ruuning the depoled *.exe is as follows:
"
D:\code\??? Error using ==> imread at 374
File
"C:\Users\DPY\AppData\Local\Temp\DPY\mcrCache7.15\Quadru1\toolbox\guilayout-v1p17\+uiextras\Resources\tab_NoEdge_Selected.png"
does not exist.

Error in ==> TabPanel>iLoadIcon at 429

Error in ==> TabPanel>TabPanel.reloadImages at 393

Error in ==>TabPanel>TabPanel.TabPanel at 70

Error in ==>QuadrupoleMachining>createInterfae at 190

Error in ==> QuadrupoleMachining at 4

MATLAB:imread:fileOpen
"

Do you know the possible reason for such error?

Thanks very much.
william

01 Aug 2014 Seth Kenner  
22 Jul 2014 Bara

Thanks for this toolbox!

Several members have mentioned issues integrating their existing GUIDE layouts with this tool. I found a workaround that did the trick for me.

I was not able to re-parent an existing object (panel or table) into this layout. However, you can create a new GUIDE panel within, for example, an HBox and you can re-parent each item from your existing panel to this new one, then delete your old panel.

Example:

new_HBox = uiextras.HBox;

new_GUIDE_panel = uipanel('Parent',new_HBox,'BorderType','none');

children = get(old_GUIDE_panel,'Children');

set(children,'Parent',new_GUIDE_panel)

delete(old_GUIDE_panel)

As long as your original and new panels are equal size, all the objects will be positioned as expected in the newly created panel.

22 Jul 2014 Dan K

William, This suggestion isn't specific to the GLT, but if you open a command window and launch the executable from there you will be able to see what error is being thrown that takes down the program.

21 Jul 2014 william

Hello,
I am using the Layout Toolbox. It is really great tool.

I encounter a problem when delpoying the developed GUI into a *.exe file using the MATLAB deploytool function. The developed GUI can be converted into *.exe file, but when starting *.exe file, it appears quickly and closed by windows immediately. I have tried the demoBrowser.m example, the same error appears. BTW, I'm using it on 32-bit Windows 7 OS.

Any idea on the reason for this?

Thanks
william

10 Jul 2014 Dom

Hello,
I am using the Matlab Layout Toolbox too, nice tool, congrats :).
One thing i am interested in is, to cut my application down, if i created a figure with this toolbox and a uipanel and in the uipanel i want to create an axes so it should looks like this:

...
figure_handle = figure('Position',[(screensize(3)-1100)/2 (screensize(4)-600)/2-20 ...
1100 600],'NumberTitle','off','Name','Test1','ResizeFcn',@ResizeFcnCB, 'HandleVisibility','off','CloseRequestFcn',@CloseRequestFcnCB,'Renderer','OpenGL','PaperPositionMode','auto');

handle_uipanel = uipanel('Parent',figure_handle);
handle_axes = axes('Parent',handle_uipanel);

So then there is an axes, but without a box, i know the command box on and i tried to set it on with:

box(handle_axes,'on')

but then i only can see two lins on top and on the right of the axes. But i want to see a whole box, lines on the top, bottom, right and left.

If i create a figure and plot something into without using the Toolbox it works.
Any idea?
Thanks
Dom

07 Jul 2014 David Sampson

There have been some discussion on this forum recently about GUI Layout Toolbox and R2014b, as there will be significant changes to MATLAB graphics in that release.
* The current public release of GUI Layout Toolbox is not compatible with R2014b.
* We will release an R2014b-compatible version of GUI Layout Toolbox on MATLAB Central at the time of product general release.
* A beta version for R2014b is currently being tested. If you need access during the R2014b prerelease period then please contact Ben and me by email with a brief description of your requirement.

24 Jun 2014 Ian

@jvc: I can't speak for Ben & David, but there is code in GLT taking the new HG2 graphics system into account (just not yet fixing the bugs with it), so I'm pretty sure they do intend to update. Of course some official news from Ben or David would be very welcome indeed!!!

20 Jun 2014 jvc

I am joining the list of those who are asking whether this toolbox will be updated for compatibility with the new 2014b graphics system. I have made extensive use of the toolbox for my routine data processing tools - rebuilding these without GUI Layout would be a huge job.

Even if the answer is that the author does not plan to update toolbox it would be valuable to know this for planning purposes.

20 Jun 2014 David

Thank you for your Toolbox!

I would like to compile my application with the compiler (R2013b) but there is a problem with .p files. Is it possible to send us the equivalent files with the .m extention? The 2 files are in the "Patch" directory. Thanks!

18 Jun 2014 Nicolas Jaccard

Sven: at first I also thought that updating the "handle.listener" to addlistener() calls would do the trick. However, it seems to be much more complicated than that. With GUI elements now being objects, it seems that the whole architecture of the toolbox has to be re-worked. I was hoping for it to be a quick fix but it looks like we will have to wait for Ben to give us an update on their plans.

17 Jun 2014 @bmtran

I agree that this toolbox should be updated to support R2014b. I'm willing to help in any way as well.

17 Jun 2014 Nicolas Jaccard

I join both Sven and Ian in asking whether the toolbox will be updated to be compatible with 2014b. I have used it extensively and having to not update MATLAB in order to continue would be a shame. I am happy to help any way I can to make it happen!

17 Jun 2014 Sven

Yep, agreed with Ian. I have quite a few interfaces that I'd like to check for 2014b compliance, but they're all wrapped inside uiextras containers which currently error with the 2014b pre-release. I believe the main issue is the 7 instances of "handle.listener" which need to be updated to addlistener() calls inside Container.m.

17 Jun 2014 Ian

It would be really helpful if this could be updated to work with the new prerelease and we could test our GUIs before an official release!

30 May 2014 Andreas

Dan K

I use the compiler option -a followed by the path to the Resources directory.

E.g.: -a GUILayout\+uiextras\Resources

30 May 2014 Dan K

I don't know if this is true of anybody else, but with the current version 1.14, I can't compile a GUI that uses a tabpanel. It fails because it can't find the png's in the Resources directory, and because it's a package I can't use -I to include that directory. Any suggestions?

11 Apr 2014 Brian  
03 Apr 2014 Mikael

Great job, thanks
The only thing I'm missing is the posibility to define an an area with contents that do not rescale.
Let's say I design a VBox with two fields. One of the fields contain another VBox with table rows in each field. This VBox could contain up to a hundred rows so I want them to have a minimum size and a scroll slider to be added automatically if the total size of the second VBox becomes too large for the first VBox. I guess the MinimumSize property should fix this but it does not seem to work (or perhaps I am using it the wrong way)

03 Apr 2014 Alejandro Castellanos

Great Toolbox! I love how easy developing a GUI can be using this FREE toolbox!

25 Mar 2014 Harry

Many thanks on my behalf as well. Well documented toolbox and easy to use. One thing though: in a panel subplots are overwritten (last one showed only). A solution to this?

25 Mar 2014 Harry  
21 Mar 2014 Hannu K

Thanks for the great toolbox!

I use parallel toolbox with my gui when I open matlabpool within the gui and use parfor I get the following warnings:

Warning: com.mathworks.hg.peer.HG1FigurePeer@36300ca7 is not serializable
Warning: Could not deserialize object: java.io.InvalidClassException:
com.mathworks.hg.peer.FigureFrameProxy$FigureFrame;
com.mathworks.hg.peer.FigureFrameProxy$FigureFrame; no valid constructor/n

Warning: The following error was caught while executing 'uiextras.Container'
class destructor:
Operands to the || and && operators must be convertible to logical scalar
values.
> In remoteParallelFunction at 49

Should I be worried or can I just suppress these warnings? Everything seems to be working just fine though.

08 Mar 2014 David  
03 Mar 2014 Dani

I would like to associate my uiextras.Panel with a window that displays some help text. I struggle to find a way how this can be done. I guess I could add this as a child to the panel, but since all panels look differently it is difficult to come up with a homogeneous way of doing this.

The simplest would be to add a callback to the title of the panel or, perhaps more elegant, add a button with a question mark all the way to the right of the top of the panel, i.e. on the opposite side of the title text, that has a callback to the help window. Is any of this possible?

27 Feb 2014 Thanakorn  
27 Feb 2014 Thanakorn

Sorry, I can't find a 10 stars button so you will just have to get JUST 5. Well done and thank you :)

27 Feb 2014 Nicolas Jaccard

I have just started using this toolbox and I finally can build good-looking and functional MATLAB GUIs. Thanks for all that work.

16 Feb 2014 Martin

When I try to load from file a struct which has uiextras fields, I get warning messages because the Delete fcn is called where obj.UIContainer returns empty. I think you need to first check whether obj has this field.

04 Feb 2014 Ben Tordoff

Hi Emmanuel, when you run "install" (either from inside MATLAB or outside) it tries to update MATLAB's path. That requires write-permission to the location where MATLAB is installed. If you don't have permissions to update MATLAB's path, the best thing to do is just run "install" from within MATLAB before using the toolbox. If you want the toolbox to always be available, add this call to your personal startup.m.

I know this is a bit of a pain, but I don't think there's any way around it.

Ben

01 Feb 2014 Emmanuel Flores

When I tried to run install.bat, a dialog box appeared saying "Failed to save path, you will need to re-install when MATLAB is restarted". How can I resolve this? Or how should I use this? Sorry for the stupid question. Just stating to use Matlab. Thanks!

31 Jan 2014 Martin

Seems to be a set of useful tools.

How about spelling hierarchy correctly?

27 Jan 2014 Ian

Ben, do you plan to support HG2 *before* it is formally released, as currently I want to ensure my GUIs all work with the upcoming HG2 before a formal release, but I cannot test anything that uses GUI layout toolbox (all my other GUIs work with HG2)...

24 Jan 2014 Jose Raya

Amazing work!

24 Jan 2014 Jan

Oh my ...

I'm a little bit dumb sometimes.

Nevermind, the callback does work.

20 Jan 2014 Jan

Thanks for this useful toolbox!

I've got a problem using the TabPanel. I know that there is the possibility to add a SelectionChange Callback. I added one:
set(tabPanel, 'Callback', @test);

function test(varargin)
disp('test');
end %fcn

Then I get the following error:
No method 'disp' with matching signature found for class 'uiextras.TabPanel'.

How can I put up an own callback function? (I want another panel to be changed, when the tab is changed).

Regards and thanks again,
Jan

07 Jan 2014 Adam Wyatt

With reference to my "bug" mentioned earlier regarding application deployment. The solution is to simply manually add the resource files to the list of required files during compilation.

With regards to the warnings generated by the dependency walker - I have not yet found any effects from this, and sp it can probably be ignored (i.e. I have not observed it to require any functions not found by the dependency checker).

Great work - keep up the updates.

07 Jan 2014 @bmtran

This is a fantastic example of what MATLAB software can be, and it has given me a model to strive for in my own work. I use this constantly. It's extremely flexible and reliable, and the code inspires me to fully utilize MATLAB's built-in object-oriented constructs.

22 Nov 2013 Igor

Hi Sih,
Have you read "readme.txt" file in "patch" folder, where p-file you've mentioned is located?
It mostly explains why they are there.

It looks like these files are fixed versions of core matlab functions, so developers won't release source code for them. Just hope that those issues would be removed some time.

21 Nov 2013 Sih Ying Wu

It's easy to use, however, I've been facing same problem while trying to compile this GUI into standalone application.

When attempting to compile some of your code, warnings are given relative to the P-files missing their associated M-Files.

Here is one example :

Warning: Requirements cannot analyze P-code unless the user provides a corresponding M-code along with the P-code in the
same folder. The dependencies of D:\Codes\MATLAB\GUILayout-v1p14\Patch\getpixelposition.p may not be included in the
completion because its corresponding M-code cannot be found by REQUIREMENTS.

I was wondering if there's any workaround, or if you can release the m-code. Since the main reason to write a gui is to distribute it through standalone projects. Thanks for helping in advance.

14 Nov 2013 Adam Wyatt

There is a small "bug" that makes this package incompatible with the Matlab "Application compiler" app for redistributing compiled stand alone applications.

A work around is the following:

The problem lies with the image locations being hard-linked to the location of the package from the use of "fileparts". I replaced these lines with a test for "isdeployed", for example lines 424/5 of uiextras.TabPanel (iLoadIcon function) to:
if ~isdeployed
this_dir = fileparts( mfilename( 'fullpath' ) );
icon_dir = fullfile( this_dir, 'Resources' );
else
this_dir = '.';
icon_dir = '.';
end

I then simply include the resource files in the list of additional files in the app.

14 Nov 2013 Adam Wyatt  
12 Nov 2013 Ian Phillips

Great way to plot graphs in different tabs. Highly recommended.

Note: There is a small bug with graphs from different tabs being plotted on top of each other. This can be fixed using uipanel for each graph (instead of uicontainer). See comments below from @eff and @Brett 22nd Aug 2013.

04 Nov 2013 Sébastien Durand

When attempting to compile some of your code, warnings are given relative to the P-files missing their associated M-Files.

Can you fix this!

Here is one example :

Warning: Requirements cannot analyze P-code unless the user provides a corresponding M-code along with the P-code in the
same folder. The dependencies of D:\Travail\Codes\MATLAB\GUILayout-v1p14\Patch\getpixelposition.p may not be included in the
completion because its corresponding M-code cannot be found by REQUIREMENTS.

29 Oct 2013 Jackson Richards

Great tool!

Just a question on sizing...

Is there an 'auto' / intelligent way of sizing a parent wherein all the children have a fixed pixel size? ie. A VBox within a figure with 2 panels of 100 pixel height. Is there any way to automatically set the figure height to 2*100+2*padding+1*spacing?

Cheers

24 Oct 2013 Timothy  
18 Oct 2013 Roger GALLOU

Manipulation indicated by Sven corrects the problem.
Sorry for the previous rating GUILayout Toolbox. It was a mishandling on my part. GUILayout Toolbox is a really good contribution.

17 Oct 2013 Sven

@Roger and any others who suddenly had MATLAB freezing on startup when they upgraded to 2013b: The problem you've been experiencing has now been fixed. You'll need to follow the instructions in bug report 968648 (http://www.mathworks.com/support/bugreports and search for 968648).

Roger, I agree that this was a horribly frustrating bug but I don't think that it was GUI Layout Toolbox's problem - more likely a MATLAB startup error.

04 Oct 2013 Roger GALLOU  
04 Oct 2013 Roger GALLOU

Hello,

There is a problem of incompatibility between the version 1.13 of the tremendous contribution GUILayoutToolbox and R2013b version of Matlab.
We set the default file installGuiLayoutToolbox our StartUp. Unfortunately, it also blocks our MatLab R2013b. After analysis, we commented on the toolbox <type> online </ type -> info.xml in the file directory layoutHelp GUILayoutToolbox. Perhaps there-he has an explanation through the Toolbox we have: Signal Processing, Mapping Toolbox, Image Processing.
If this message can help others, so much the better ...

02 Oct 2013 Ben Tordoff

Those hitting problems with appdata, please update to the latest version. As per the release notes, this should already be fixed. If you find cases where it still doesn't work, let me know.

Ben

27 Sep 2013 Andreas  
21 Sep 2013 Dan

Hi Ben, Hi David. Thanks for sharing this very useful tool.

I enconuntered a problem with the mousepointerhandler class (Linux, R2011a):
If I register a new pointer for an axes object within a figure which has units set to normalized, the axes position is not identified correctly. I could resolve the issue by changing the reference figure handle from 0 to figh in line 120 in the mousepointerhandler classdef.

19 Sep 2013 Yannick

Hi,

Just repeating myself at that point but I see it has not been fixed in the latest update...

In order not to have the childs of collapsed box panels show up on the rest of your GUI, you need to change lines 368 to 371 of Container.m to :

if position(3)<=0 || position(4)<=0
% Not enough space, so move offscreen instead
position = [-10000 -10000 10 10];
end

13 Sep 2013 Ben Tordoff

Thanks Igor, I've fixed that for the next version.

12 Sep 2013 Igor

Very nice tool, thanks.

I've spotted a tiny error in docs on page
Function%20reference2_6.html
Images/bigicon_HButtonBox.png image is used instead of
Images/bigicon_VButtonBox.png

09 Sep 2013 Heinrich

For all who have the same problem here
is a quick and dirty solution: (if ok?)

====================================
function userDataReturn = uiextrasUserData( uiextrasObj , userData )
% gets/ sets userData to uiextras-Objects

userDataReturn = [];

% find all Objects under root
allObjs = findobj( 0 );

% Iterieren und nach dem Objekt suchen, dessen "Conainter"-appdata
% dem übergebenen Objekt entspricht
for curObj = allObjs'

try
ad = getappdata( curObj , 'Container' );

if uiextrasObj == ad

if nargin < 2
userDataReturn = get( curObj , 'UserData' );
return
else
set( curObj , 'UserData' , userData )
return
end%-if

end%-if

catch % no catch
end

end%-for

end%fcn
=======================================

09 Sep 2013 Heinrich

I hardly miss UserData or AppData,
Sometimes this the only place where
you can store Data in the best practice
of oo-Programming.

But excellent work at all!

28 Aug 2013 Sven

Aha! Yep, Patrik hit the phantom error I was getting. uiextras.TabPanel was the object not working in 2013b pre-release.

27 Aug 2013 Ozan Oguz

Hi again,

I have a GUI made using this tool.
There are some controls and a loglog plot...

To be able to print the plot, I copy it to a new figure, with its legend.

If I don't touch the GUI, printing function seems to work fine, however, if I slide the divider (between the plot area and controls area), legend do not copy correctly, such that legend becomes huge in size and mispositioned on the screen.

The problem seems to be mixing of position values of the legend after beforementioned GUI change. See below:

I use this code:
getpixelposition(axis_on_the_main_screen(1),true)

Before the GUI change, values are:

legend_position =
897.8333 570.5000 116.0000 23.3333

Same values after GUI change:

legend_position =
23 18 993 575

23 Aug 2013 Ozan Oguz

Hi,

I have a GUI made using your tool.
I am also using export_fig tool for printing plots.

After sending "print" command, GUI changes: uiextras.Empty objects disappear and legend becomes uneditable.

I just wanted to inform.

22 Aug 2013 Brett

@eff
I have used several axes in different tabs within layouts. I needed the ability to do plotyy type plotting as well. My workaround is to place all axes inside a uipanel. This way the uipanel acts as a container for the axes. This also allows the panel to have multiple overlapping children without the uitab's layout separating them into its layout.

22 Aug 2013 Eff

Hi folks annoyed by TabPanel issues,

I have reported the problem with different axes that are displayed on top of other axes within different tabs of a TabPanel in July 2012, Alexander reproduced the problem in January 2013 and in May Collin has reported similar issues.

After I have encountered the problem first I figured out that that changing the DefaultRenderer to painters resolved the issue (set(0,'DefaultFigureRenderer','painters')). If you have a similar problem, could you please confirm that this works for you, too? As I am creating 3d plots this is not an option for me, so after Ben's hint I can confirm that resizing the figure resolves the issue, thus I have written a callback function that automatically resizes the figure after a tab change. Not a nice way but up to now it was a sufficient workaround. However, this option does not work an my MAC computer, as Matlab for MAC (R2013a) crashes non-deterministically when resizing a figure (I had similar issues with closing figures on R2012b on MAC).

Here is a little bit of code to reprocude the problem (works for me on MAC R2012b, MAC R2013a and Linux R2012):

set(0,'DefaultFigureRenderer','OpenGL');
mainGrid = uiextras.Grid( 'Parent', figure('Renderer', 'OpenGL'));
tabPanel = uiextras.TabPanel( 'Parent', mainGrid, 'Padding', 5);

% first tab
firstHBox = uiextras.HBox( 'Parent', tabPanel);
firstVBox = uiextras.VBox('Parent', firstHBox);
uicontrol('style', 'pushbutton', 'String', 'b1', 'parent', firstVBox);
axes('parent', firstVBox);
hold on;
plot(1:100);
text(10,10, 'text of first tab');
drawnow;

set(firstVBox, 'Sizes', [-1 -4]);

% second tab
secondHBox = uiextras.HBox( 'Parent', tabPanel, ...
'Padding', 5);
secondVBox = uiextras.VBox('Parent', secondHBox);
axes('parent', secondVBox);
hold on;
plot(100:-1:1);
text(50,50, 'text of second tab');
drawnow;
uicontrol('style', 'pushbutton', 'String', 'b2', 'parent', secondVBox);

set(secondVBox, 'Sizes', [-4 -1]);

Can you reproduce this problem http://img41.imageshack.us/img41/9826/selection006a.png ? Are there any alternative workarounds rather than resizing the figure?

20 Aug 2013 Patrik Andersson  
20 Aug 2013 Patrik Andersson

The following lines

h1 = uiextras.TabPanel('Parent',figure);
h2 = uiextras.VBox('Parent',h1);
set(h1,'Enable','on');

work fine in R2013a but produce an error in the R2013b prerelease:

Error using isappdata
The uiextras.VBox object does not support application data."
...

12 Aug 2013 Sven

Ha, I can't seem to reproduce the error I was getting :)
It was on my first look at 2013b so suspect it was either a gremlin that ran away on reboot, or a totally separate error that I just blamed on the new beta ;)
If it turns up again I'll email the conditions.

12 Aug 2013 David Sampson

Sven, there is no plan to deprecate getappdata and setappdata. If you are seeing problems in the R2013b prerelease, please share reproduction steps, either directly with Ben and me, or on this forum.

06 Aug 2013 Sven

@Ben,
Just a heads up that the 2013b pre-release has discontinued getappdata/setappdata methods, which results in some crashing uiextras components. Do you have plans to store figure callbacks elsewhere?

31 Jul 2013 jamie mazer

Hate to follow up to my own post, but for the record, this doesn't appear to be a subplot issue -- this version that uses uiExtras.Grid does something similar. It's tweaked a bit to really emphasize the proble (nothing's ever plotted in the right hand grid box, but it still accumulates all the plot points:

clist = 'rgbmy';
tabpanel = uiextras.TabPanel('Parent', gcf);
for n=1:4
uip = uiextras.Grid('Parent', tabpanel);
axes('Parent',uip);
x = 1:2; y = x+n;
set(plot(x, y, '-o'), 'markerfacecolor', clist(n));
yrange(0,10);
axes('Parent',uip);
end
tabpanel.SelectedChild = 1;

On the up side, I guess I could include a dummy plot to suck up all the error's leaving the n-1 subplots correct :-)

31 Jul 2013 jamie mazer

Quick question -- is it ok to mix uiextras and subplot? At first it looks kosher, but here's a short code frag that breaks things:

tabpanel = uiextras.TabPanel('Parent', gcf);
for n=1:4
uip = uipanel('Parent', tabpanel);
subplot(1,1,1, 'Parent', uip)
x = 1:2; y = rand(size(x));
plot(x, y, '-o');
end
tabpanel.SelectedChild = 1;

This makes some tabs, each with one plot. 1st tab accumulates all 4 plots, 2nd second tab last 3, etc. I suspect the answer is: don't mix subplot and uiextras, but there's not explicit about that in the docs. Switching to subplots to grids would mean a lot of recoding, so I figured it would be good to know if this is a bug or feature before I decide if it's worth it (FYI - this doesn't happen with hist!).

30 Jul 2013 Marc

@sven & Ben: thats funny, i Run into exactly the same Question today (also because of your icon and thinking about subplot) with my current Project. I can only encourage you to Try and reimplement the "span multiple Grid " Issue. I think it can be Handy for a Lot of practical GUI Applications Or Layouts. Anyway Thanks for your Great work in Thuns toolbox!

30 Jul 2013 Sven

@Ben: Thanks for the clarification. The ability to span multiple grid entries would be quite useful. The syntax to define it on the other hand... I agree - messy. I've never quite felt comfortable with the Grid.Children usage (like rearranging children into a specific order different to columns-first-left-to-right). I'd welcome a revisit and would be happy to give feedback.

30 Jul 2013 Sven

@Beat:

I think that you've hit a missing functionality with Container.getpixelposition. It hasn't yet got a recursive implementation (whereas regular MATLAB ui components do, and some java components call the recursive version). You can possibly get by by replacing that function with what I've got below but I've still had an issue or two. Ben, David - does this seem reasonable?

function pos = getpixelposition( obj, recursive )
%getpixelposition get the absolute pixel position
%
% POS = GETPIXELPOSITION(C) gets the absolute position of the container C
% within its parent window. The returned position is in pixels.
pos = getpixelposition( obj.UIContainer );

if nargin<2
recursive = false;
end
if recursive && ~ishghandle(obj.Parent,'figure')
parentPos = getpixelposition(obj.Parent, recursive);
pos = pos + [parentPos(1) parentPos(2) 0 0] - [1 1 0 0];
end
end % getpixelposition

30 Jul 2013 Beat Birkhofer

If I try to place a JScrollPane via javacomponent() in a panel created with this Tbx, I get an 'Invalid parent specification' error. I can place a uipanel in a panel e.g. created via uiextras.Panel(), but then I loose the convenient auto-resize features (for the uipanel). Is there a more elegant solution to add java components?

Beat

30 Jul 2013 Ben Tordoff

Hi Sven. I am impressed at your attention to detail!

We used to allow "merging" of grid elements in a previous iteration of this tool. However the API for it was terrible. We have never been back to try and come up with a good API, but maybe we should?

Ben

29 Jul 2013 Sven

Ben, David,

The "icon" for uiextras.Grid makes it look like you can define a grid, and have one axis span multiple entries on that grid. I don't think, however, that this is actually possible.

An analogy would be calls to subplot like below:

figure, subplot(2,2,[1 3]), peaks
subplot(2,2,2), peaks
subplot(2,2,4), peaks

So, is it possible to make a grid like the following:

figure, G = uiextras.Grid('Parent',gcf);
B13 = uicontrol('Parent', G, 'String','Button Spanning [1 3]');
B2 = uicontrol('Parent', G, 'String','Button in spot 2');
B4 = uicontrol('Parent', G, 'String','Button in spot 4');
set(G,'RowSizes',[-1 -1])

... and then actually make the first button span two rows?

29 Jul 2013 Alizee

Hi Ben, David,

Thank you very much for your GUI Layout Toolbox, this is a beautiful tool.
It works perfectly with programmable GUIs but I am struggling to make it work with my GUIDE GUIs: I have a few GUIDE generated windows with several panels inside each of them. I would like to use your tool so that these panels resize themselves elegantly but I do not want to re-define programmatically all my handles inside these panels. Could you add an example in the documentation on how to do this?

Thank you very much,
Alizee

12 Jun 2013 Adam Filion

Is there any way to have the title bar for a panel have more than one line? I have a component that is say 30 wide, but the title I'd like to include needs more space than that and it's getting cut off. Any suggestions? Thanks.

10 Jun 2013 David Sampson

We will release support for HG2 in due course.

05 Jun 2013 Josh Spencer

Great tool,

Thanks

22 May 2013 Kronos

Very slick and easy to work with. It's very well documented so anyone can pick this up in a heartbeat. However, if you have HG2 enabled, this will not work. Any plan in the future of this support?

http://undocumentedmatlab.com/blog/hg2-update/

21 May 2013 Yannick

Hi Ben, David,

I am having issues with the latest release and changing the limits of axes with patches objects in them.

if you do :
f=figure
b=uiextras.VBox('Parent', f)
a1=axes('Parent',b)
a2=axes('Parent',b)
contourf(peaks)
set(a2, 'YLim', [10 30])

You will see the contours coming out of the axes onto the neighbouring elements.

Is there a way to get the axes to update itself correctly ?

Many thanks,
Yannick

19 May 2013 Colin

Hi Ben,

I have been trying to make use of TabPanels for visualising a dataset. I can create and plot to several tabs each containing a flexible grid of axes:

TP=uiextras.TabPanel('Parent',figure)
for p = 1:Ntabs;
GF=uiextras.GridFlex('Parent',TP)
for q = 1:Naxes
axh(p,q)=axes('Parent',GF);
end;end

...
plot(axh(p,q),...)

Unfortunately if I make the figure reasonably large on the screen when I change tabs the axes on the old tab are not fully hidden and obscure the axes on the new tab (basically it looks a mess). If I slightly resize the figure window then the view updates and the axes are displayed correctly. Normally the first few times I change tab things work correctly.

I am using GUIlayout v1p13 on R2013a on win7.

Any help including a work-around would be greatly appreciated (executing refresh(gcf) doesn't help)!

Regards,

Colin

29 Apr 2013 Yannick

Ben,

I actually had to change line 334 of Container.m to "position = [-10000 -10000 100 100];".

It seems 10/10 width/height was crashing the wiggle axes functions by giving <0 size to the axes contained in my box panels.

29 Apr 2013 Ben Tordoff

Hi Yannick. This is easy enough to do. I'll make sure it's in the next update. If you would like to test it before then, email me using the author link above and I'll send you a patch.

29 Apr 2013 Yannick

Thanks Ben, I like to remove both borders for a more minimalist look. When I don't need the extra functionality I replace the BoxPanel by a VBox with two elements which allows me to have no borders.

26 Apr 2013 Ben Tordoff

Hi Yannick, thanks for that fix – I'll make sure it's updated in the next version.

There isn't a definitive list of the default properties, I'm afraid. PanelBox will take notice of the default title colour, but that's about all.

Which border was it you wanted to remove, the one around the title, the one around the contents, or both?

24 Apr 2013 Yannick

I found a line was missing for the background color of the dock buttons in BoxPanel.m :

Adding the following at line 251 fixes it:

if isfield( obj.HGWidgets_, 'DockButton') set( obj.HGWidgets_.DockButton,'BackgroundColor', value );
end

24 Apr 2013 Yannick

Hi, is there a list of the default properties you can set ?

DefaultBoxPanelShadowColor does not seem to work for me ?

Is there also a way to remove the border of the BoxPanel's ?

Cheers,
Yannick

19 Apr 2013 Adam Filion

For anyone interested, I was able to solve the problem I described below using the FEX submission ScreenCapture by Yair Altman. For whatever reason, this worked where MATLAB's built-in GETFRAME did not.

07 Apr 2013 Guo  
06 Apr 2013 Guo  
05 Apr 2013 Anton Semechko

love this toolbox!!!

01 Apr 2013 Xha

To clarify my previous comment I'm looking to use the --

"Use panels and tabs for switching interface pages" with old matlab guis

01 Apr 2013 Xha

Anyone know or can help me? I'm wondering if there is a relatively straightforward way to combine the 'pane' functionality of this gui, (using tabs at the top corresponding to each pane), can be combined with the regular matlab GUIDE usage, so I can have multiple panes, in a relatively simple way. I'm looking to retrofit some of my old GUIs without having to recreate them completely using guilayout.

01 Apr 2013 Dani

A (long) while ago I commented here and complained that the different uicontrols, more specifically their text, are not vertically aligned. Using Yairs findjobj one can actually align them by directly operating with the underlying java object. Before I forget again how to do it I provide here the updated example:

figure
DUP = get(0, 'DefaultUicontrolPosition');
uicontrol('Style', 'popupmenu', 'String', {'Yes', 'No'}, 'Value', 1, 'Position', DUP);
hu = uicontrol('Style', 'text', 'String', 'Test', 'Position', [5+DUP(1)+DUP(3), DUP(2:4)], 'HorizontalAlignment', 'left');
[a,b] = findjobj(hu);
a.setVerticalAlignment(javax.swing.SwingConstants.CENTER);

28 Mar 2013 Michael Quinn  
25 Mar 2013 Adam Filion

Hi Ben,

Many thanks for the awesome toolbox, it's a real time saver and gets rid of a lot of my OCD behavior getting everything to look right.

I have one question for you. I'm creating a GUI for animating higher dimensional data. I'd like to have an option for the user to record the figure during animation to a file like avi or gif. However, the toolbox components don't seem to play nice with MATLAB's GETFRAME. Sometimes what it captures doesn't show updated data, other times components are blacked out, and other times it captures what's behind the GUI. In any case, I never get what I expect.

I haven't run into anything like this with GETFRAME before. Is this a known issue with the toolbox? Do you have any recommendations? Thanks.

19 Mar 2013 Ben Tordoff

Hi Dani, this is related to the legend problems we have already fixed. I have a fix for this too, but it isn't quite ready for release yet. Watch this space...

18 Mar 2013 Dani

I have a problem with uiextras.Panel. If I execute the code below then the colorbar is in the wrong position, lying over the axes. This can be cured by uncommenting the pause statement or replacing uiextras.Panel with a conventional uipanel, both not very satisfactory solutions. Am I doing something wrong?

f = figure
p = uiextras.Panel('Parent', f);
c = uicontainer( 'Parent', p );
a = axes('Parent', c);

pcolor(rand(10));
%pause(0.05)
colorbar

15 Mar 2013 Elliot

I realized after posting that my last question didn't make any sense, because it related to behavior that I thought was stock Matlab, but actually is not. I have another question, though. I'm trying to layout a plot and a uitable, and make it possible to print to a pdf that looks like the graphics on screen. However, while the on-screen display looks good, the table covers up part of the plot in the pdf. Is there any way to print to a vector pdf so it looks exactly like what I see on screen?

Thanks in advance for your help.

Here's the script I'm using:

X = randn(100,3);
summaryStats = [mean(X); std(X); min(X); median(X); max(X)];

fig = gcf();
set(fig, 'paperunits', 'inches', 'papersize', [11 8.5], 'paperposition', [0 0 11 8.5]);
set(fig, 'units', get(fig, 'paperunits'), 'position', get(fig, 'paperposition'));
set(fig, 'resize', 'off');

vBox = uiextras.VBox('Parent', fig);

p = uicontainer('Parent', vBox);
ax = axes('Parent', p);
plot(ax, X);

tab = uitable('Parent', vBox, 'Data', summaryStats);
ext = get(tab, 'Extent');
set(vBox, 'Sizes', [-1 ext(4)]);

print -painters -dpdf test.pdf

08 Mar 2013 Elliot

I've just started using this toolbox, and it looks great. One question: it looks like the standard Matlab rollover functionality (i.e. showing the values on the plot under the mouse) is working for only the last plot added. Is there any way to get it to work for all plots in a figure?

07 Mar 2013 Evgeny Pr

@Ben Tordoff
Oh, it's great! Thanks for the useful information!

07 Mar 2013 Ken Campbell

Excellent tool. Great documentation. Incredibly fast response from the author.

07 Mar 2013 Ken Campbell  
07 Mar 2013 Ben Tordoff

Thanks Sven, I'll get onto that and submit a fix.

07 Mar 2013 Ben Tordoff

Hi Evgeny, my recommendation is to use AppData, not UserData. It is both more flexible and I have found it to be substantially faster. Instead of

set( obj, 'UserData', data )

use

setappdata( obj, 'MyData', data )

Since each piece of app data is named you can have multiple sets of user-stored data in each object. This is a much better system, and works nicely with our uiextras layouts.

06 Mar 2013 Evgeny Pr

I think it would be cool to have a 'UserData' field in uiextras classes like all Matlab ui controls to store user data and various context.

06 Mar 2013 Sven

Ben, found another ismember hiccup:

Error in uiextras.Container/onChildParentChangedEvent (line 518)
[dummy, loc] = ismember( source, obj.Children_ ); %#ok<ASGLU>

06 Mar 2013 Evgeny Pr

@Ben Tordoff

Thanks!

We will have to keep the layout context (index, size, min size) for each hidden child element. :)

06 Mar 2013 Ben Tordoff

Hi Evgeny, I can see your use-case, but I'm not 100% convinced that setting a widget to be invisible is that same as saying it shouldn't take any space. I have GUIs where I need a widget to appear/disappear without affecting the layout of the rest of the GUI.

I suspect you can achieve what you want by simply setting the size of the element to zero. For example, given an HBox with three children I can make the middle one disappear by doing:

set(box, 'Sizes', [-1 0 -1])

and make it re-appear using:

set(box, 'Sizes', [-1 -1 -1])

No need to fiddle with the visibility - a zero-sized widget is not visible anyway!

06 Mar 2013 Ben Tordoff

I've been asked this and similar questions a few times, so I thought I would share my answer with everyone:

"Is it possible to adjust the position of an axis inserted into an HBox or does it have to fill the entire box?"

The answer, as always in computing, is an extra layer of indirection! If you put the axes in a uicontainer or uipanel and put that inside the layout then you have full control of its position within the container whilst still having the overall position managed by the layout. For example:

fig = figure();

box = uiextras.HBox('Parent', fig);

% Create some axes in a container with lots of padding
c1 = uicontainer('Parent', box);
ax1 = axes('Parent', c1, 'OuterPosition', [0.1 0.1 0.8 0.8]);

% Create some axes in a container with no padding
c2 = uicontainer('Parent', box);
ax2 = axes('Parent', c2, 'OuterPosition', [0 0 1 1]);

05 Mar 2013 Evgeny Pr

Hello!

Thanks for your job! This helps a lot. Almost as in Qt... :)

But there is one problem.
I want the layout to react automatically to 'Visible' property of the childrens.
If we set 'Visible' to 'off', layout should automatically extend, fill the empty space. That would be great!

See my demo screencast:
https://dl.dropbox.com/u/17400742/Video/guilayouts_test.avi

27 Feb 2013 Graham Fletcher

Thanks for the feedback Ben, much appreciated.

27 Feb 2013 Ben Tordoff

Hi Graham, a layout panel only shows a single child at a time. When you add the second axes it replaces the first. As with most computing problems, this can be solved with an extra layer of indirection. Simply put your combined axes into their own container and let that manage the position:

f1 = figure('Name', 'Fig1');
p1 = uiextras.Panel('Parent', f1);
c1 = uicontainer('Parent', p1);
ax1 = axes('Parent', c1);
ax2 = axes('Parent', c1, 'YAxisLocation', 'right');

This is the way to handle any custom widget made up from mutliple axes, uicontrols etc. - just put it in its own container.

26 Feb 2013 Katana13

Extremely useful toolbox for creating GUIs. I don't know if it's a limitation (Matlab R2012a,GUILayout_v1p12). Example:
h = figure('Menubar','none', 'Toolbar','none','Tag','figure');
hcom = uiextras.HBoxFlex('Parent',h,'Tag','hcom');
str = ' boub boub boub bou de la foucv oeufe fz ozfz efz fvousf zefzf ouvzfz ozfz fouz fz fzo ufzf zouz fozufozf uzo fzoufzo fuziofz fzofiuzfoiz fouzfo ';
hEdit = uicontrol('Parent',hcom, 'Style','edit','Min',0, 'Max',2, 'HorizontalAlignment','left','Units','normalized','String',str,'Tag','hEdit');
com = uicontrol('Style','edit','Parent',hcom,'Max',3,'Min',1,'HorizontalAlignment','left','Units','normalized','Tag','com');
saveas(h,'test','fig');

No problem, if you directly run the script. But if you launch the saved file : 'test.fig', 2 figures pop up (OK if you use "uiextras.HBox" instead of "uiextras.HBoxFlex")

Thanks

20 Feb 2013 Graham Fletcher

Very impressed, speeds complex GUI development and results in a much more polished UI.

1 problem I've encountered though - attempting to create something equivalent to a plotyy within a Panel fails, the 1st axes disappear when 2nd axes are created.

f1 = figure('Name', 'Fig1'); p1 = uiextras.Panel('Parent', f1); ax1 = axes('Parent', p1); ax2 = axes('Parent', p1, 'YAxisLocation', 'right');

20 Feb 2013 Graham Fletcher  
20 Feb 2013 Sven

Yes, agreed with Dan K. Grids are a little cumbersome to work with. Perhaps as a start a "ByRow" vs "ByCol" option could be helpful.

Dan, one thing that I do is simply add everything by columns, then at the end, grab the children of the grid and re-sort them into the desired order. For example:

C = get(GRID,'Children')
set(GRID,'Children',[C(1:2:end);C(2:2:end)])

20 Feb 2013 Dan K

Fabulous tool. There's one piece of functionality that I haven't figured out yet: How can one add items into a parent (such as a Grid) in an order that isn't just stepping down the columns? Is the only way to do it by adding empties? Likewise, how can I replace an entry in a grid/buttonbox/tabpanel once the other items have been added?

Thanks,
Dan

19 Feb 2013 Ben Tordoff

I have submitted an update that should fix the legend problems. This should appear here sometime in the next few days, once the upload is approved. When it does, can you check that your problems are fixed?

19 Feb 2013 Xin Wang

I found that i can't use legend with this tool.

example:

function bug()
S.f = figure();
tmph1 = uiextras.Panel('Parent',S.f);
S.Axes = axes('Parent',tmph1);
plot(S.Axes,[1,2]);
legend(S.Axes,{'line'});

end

18 Feb 2013 Ben Tordoff

Hi Sven, thanks for putting in the effort to nail this down so succinctly. I now have a fix for this ready to upload. You should see it appear here in the next few days.

17 Feb 2013 Ian

Can confirm Sven's error on OS X + pre-release2013a, no error on 2012b

15 Feb 2013 Sven

Oh, and I'm using the latest downloaded version (downloaded last week with a folder name "GUILayout-v1p11"). Note that the "ver" command and the documentation release notes still lists "Version 1.10", but without a date.

13 Feb 2013 Sven

Ha, I spent half an hour deconstructing a GUI I had made to try and make a nice file for you... turns out we only need 4 lines to reproduce the error:

f = figure;
axSet = uiextras.HBox('Parent',f);
axH = axes('Parent', axSet);
delete(axH)

The above code will run without error in 2012b (and I assume earlier), but it will produce an error in 2013a pre-release.

It comes down to an ismember call inside the Container.m object deletion function which compares "axes" to "doubles".

I'm not entirely sure if this is a GUI issue or MATLAB issue, so happy debugging!

13 Feb 2013 Ben Tordoff

Hi Sven, thanks for the heads-up! The release we uploaded in December should have fixed this (we were making an implicit conversion to double that needed to be explicit). If it hasn't fixed it for you can you send an example, as all the examples I have now work with the pre-release.

Thanks.
Ben

13 Feb 2013 Sven

Ben, just a heads-up that in 2013a (pre-release) it seems that MATLAB's builtin ismember function is a little more picky about comparing "axes" vs "double" types, and this affects, for example:

line 489 of Container.m

At this point, "source" is of type "axes", while "obj.Children_" is of type "double".

22 Jan 2013 Ian

Great tool. I also see a legend bug, and Stefan's fix worked great!

15 Jan 2013 Alexander

Unfortunately, the bug with TabPanel and axes is still present. Yes, axes are now always rendered (the effect that resizing or drawnow fixed previously), but, as before, they are not hidden when I switch to another tab. Seems like it depends on the level on which axes are nested. e.g if ancesting is as follows: tab->uipanel->axes, then everything works fine. But if I add one more layer, it breaks, e.g. tab->uipanel->uipanel->axes. (what's interesting, is than borders of uipanels are not rendered when switching to another tab, so they are indeed hidden, while axes are not hidden; they're not even being bound by these borders any more

14 Jan 2013 Stefan

Hi Ben, I've found a bug in the handling of legends. In Container.m on line 448:

isa( child, 'axes' )

Must be changed to

isa( eventData.Child, 'axes' )

The cast on line 426 means child will always be a double. This bug causes legends to be draw as separate objects that are disconnected from the axes.

13 Jan 2013 Heinrich

Very usefull. Thanks a lot.

If you can answer me the following
Question it would be perfect:

How do I get the parent of an uiextras-Object? get( h , 'Parent' ) just gives me the orinary Matlab-Panel wrapped by it.

regards

13 Jan 2013 Heinrich

Very usefull. Thanks a lot.

If you can answer me the following
Question it would be perfect:

How do I get the parent of an uiextras-Object? get( h , 'Parent' ) just gives me the orinary Matlab-Panel wrapped by it.

regards

03 Jan 2013 Wiliam

Amazing toolbox, very easy to learn and use. Nice functions to support dynamic layout.

16 Nov 2012 Nicholas

I tried to comment on this as I'm having issues, and for some reason my post isn't showing up. I put it on pastebin at: pastebin(dot)com(slash)Hm5K4pL5

16 Nov 2012 Nicholas  
15 Nov 2012 Wiliam

Very powerful and easy to use, this should be a part of core MATLAB.

13 Nov 2012 Nicholas  
08 Nov 2012 Graham

Any chance of getting it to manage ActiveX controls and make them look like they are part of a specific panel instead of a separate object under the figure? I'd like to be able to put a MSFlexGrid or MSTreeView control on a panel and have it scroll and appear/disappear with the parent TabPanel.

31 Oct 2012 Robert

Great code, thanks. I have an issue, apologies if already addressed and I did not find it.

Everything works great, but when I attempt to add items to a chart -- say, using text or patch function -- it adds it to a new figure. These functions don't work with handles, specifically, but even if I activate the figure just before running each of these functions...it still creates a new figure.

It seems like I am missing something fundamentally here, appreciate any thoughts you can provide.

25 Oct 2012 Tom  
16 Oct 2012 Jesse Hopkins

Looks like my comment didn't come through on the last rating. This has been a very useful toolbox, but we are having a minor cosmetic issue with VBoxFlex. It seems that about 50% of the time, moving across a flex boundary from right-to-left will cause the pointer to get stuck in the "resize" icon. If I move very slowly across the boundary (right-to-left), then 100% of the time the pointer will get stuck in the "resize" icon, but if I move very quickly across the boundary then it doesn't seem to get stuck in the resize icon. Note that the pointer icon does go back to the normal icon after I leave the layout, or move across the boundary again left-to-right. Any thoughts?

11 Oct 2012 Jesse Hopkins  
05 Oct 2012 Julien  
08 Aug 2012 Jeff Anderson

This is probably the best piece of code available on the exchange. It has really changed the way I write GUI's. WOW. THANK YOU!!!

19 Jul 2012 Sanchali Purandare  
12 Jul 2012 Jingjing Bao

Thanks, Ben. I didn't know the setappdata/getappdata pair, so I actually wrote one myself as a function, just adding my var to myhandles and attach to the figure handle. It worked fine for me so far :).

11 Jul 2012 Ben Tordoff

Hi Jingjing, that explains it. The return from FINDOBJ is always a MATLAB graphics primitive. Most of these layouts are built using several primitives. Right now there is no way for me to make them primitives themselves.

One suggestion: instead of using guidata, you might find that using "setappdata"/"getappdata" on the figure is both more flexible and faster. That's what I tend to use.

Ben

10 Jul 2012 Jingjing Bao

Ben, Thanks for the reply. I was trying to do this:
hf=figure;
bp = uiextras.BoxPanel('Parent',hf,...
'Tag','boxpanel');
bp.Title = 'Original Title';
hobj=findobj(hf,'Tag','boxpanel');
hobj.Title='New Title';

The objective is to be able to modify the title in a callback. I thought I could use the handle returned by findobj with tag string, but that handle seems not working. I think it due to the fact that the handle returned by findobj is the handle to the container of the composite GUI object, so it's not directly related to the title banner. Now I use guidata to save the actual handle of the boxpanel, then retrieve it inside the callback, and it works fine.
I don't know how difficult it is to modify the layout toolbox source code to make this happen, I will spend sometime look it up after finishing current task.
Thanks again for sharing a great GUI tool.

10 Jul 2012 Ben Tordoff

Hi Jingjing, glad you're finding this useful.

bp = uiextras.BoxPanel();
bp.Title = 'New Title';

is the right way to do it and seems to work fine for me. Could you be a little more specific about what hObj is or post an example? Is hObj definitely the BoxPanel?

09 Jul 2012 Jingjing Bao

One of the best!
I have one question related to the BoxPanel, I was trying to modify the 'Title' through hobj.Title='new Title', but it doesn't work. Is there a way to accomplish this? Thanks!

09 Jul 2012 Jingjing Bao  
09 Jul 2012 Eff

I believe I have found out how to reproduce the problem. If I use 'painters' (default) as figure renderer the problem does not occur. However, when using opengl rendering the above mentionend problem happens.

To reproduce, execute set(0,'DefaultFigureRenderer','OpenGL') before running my example code (text() makes no difference)

Unfortunately, 'painters' is no option for me as I am doing more advanced 3d rendering.

09 Jul 2012 Eff

Hi Ben,
I have messed a bit with drawnow. The simple example I have given is fine by using drawnow. However, if you additionally use the text function in the plot it is not working correctly. Maybe you can reproduce the issue on your system:

mainGrid = uiextras.Grid( 'Parent', figure);
tabPanel = uiextras.TabPanel( 'Parent', mainGrid, 'Padding', 5);

% first tab
firstHBox = uiextras.HBox( 'Parent', tabPanel);
firstVBox = uiextras.VBox('Parent', firstHBox);
uicontrol('style', 'pushbutton', 'String', 'b1', 'parent', firstVBox);
axes('parent', firstVBox);
hold on;
plot(1:100);
text(10,10, 'text of first tab');
drawnow;

set(firstVBox, 'Sizes', [-1 -4]);

% second tab
secondHBox = uiextras.HBox( 'Parent', tabPanel, ...
'Padding', 5);
secondVBox = uiextras.VBox('Parent', secondHBox);
axes('parent', secondVBox);
hold on;
plot(100:-1:1);
text(50,50, 'text of second tab');
drawnow;
uicontrol('style', 'pushbutton', 'String', 'b2', 'parent', secondVBox);

set(secondVBox, 'Sizes', [-4 -1]);

With using drawnow, I don't have any plot in my first tab. When drawnow is used, the effect is the same as in the screenshot above (additionally the text of tab 2 is schon in tab 1).

Thanks a lot!

06 Jul 2012 Jingjing Bao  
06 Jul 2012 Alain Barraud

Hi Ben,
I have found a workaround to my first question, putting the small active triangular symbol not exactly on the line separator between the two split panels but topdown and top up on respectively the top panel and bottom panel. The separator handel is not public and I did not modify your class library. Concerning the second point there is a solution within the FEX "Matlab swinging more" by Malcolm. However I am not a Java expert and the Malcom code is difficult to understand. There are some hard issues with this library and I'd like to use your submission which seems very stable.
Thanks again

06 Jul 2012 Ben Tordoff

Hi Eff, thanks for uploading the picture - I can see the issue. However I still can't reproduce it on R2011b using either Linux or Windows. I have managed to hit another problem which has an easy work-around. You could try this, but it probably won't work. It would be good if we could work out how to reproduce the problem on other systems.

The workaround for this other problem (axes not appearing at all) is to put a "drawnow" after adding each axes. It seems the axes positions are not correct until they have been drawn and this forces an initial draw. An alternative that also works is a resize after drawing, but I doubt this will help your case.

If you could find an example that works on Windows (7) or Mac OS/X (Lion), that would be good as there are far fewer variants of Windows and Mac OS/X than there are of Linux!

Cheers
Ben

06 Jul 2012 Eff

An addition: I also had similar issues on my Mac in my previous work.

06 Jul 2012 Eff

Hi Ben,

Thanks for your reply! I am running Matlab R2011b on Linux. Here is a screenshot of the problem: http://img41.imageshack.us/img41/9826/selection006a.png .

Also, the workarounds I described only work for the mini example. In my real application these workarounds are of no use.

Help is much appreciated!

05 Jul 2012 Ben Tordoff

Hi Alain, the easiest way to customize any of the layouts is to take a copy of the corresponding class, rename it and then start adding in the bits you want. Hopefully most of the code is commented in the places where it isn't obvious.

I'll have a think about how best to deal with too many tab labels. It would be good to deal with this in a more elegant way in the toolbox. If you manage to come up with something good before I do, please share it!

Cheers
Ben

05 Jul 2012 Ben Tordoff

Hi Eff,

I've just tried your example and didn't see anything weird happening. Probably that means I'm trying a different platform/version combination than you are. What platform are you running on (Windows, Mac or Linux)? Also, which MATLAB version? If I can reproduce the problem I can probably tell you what's wrong and the most robust way to work-around it (or even fix it).

Ben

04 Jul 2012 Eff

Extremely useful toolbox for creating GUIs. However, either I have found a bug or I am using the toolbox incorrectly:

With several tabs having an axes object it occurs that one of the axes objects is always on top, no matter what tab is currently active:

Simplest example I could find to reproduce the problem:

mainGrid = uiextras.Grid( 'Parent', figure);
tabPanel = uiextras.TabPanel( 'Parent', mainGrid, 'Padding', 5);

% first tab
firstHBox = uiextras.HBox( 'Parent', tabPanel);
firstVBox = uiextras.VBox('Parent', firstHBox);
uicontrol('style', 'pushbutton', 'String', 'b1', 'parent', firstVBox);
axes('parent', firstVBox);
hold on;
plot(1:100);

set(firstVBox, 'Sizes', [-1 -4]);

% second tab
secondHBox = uiextras.HBox( 'Parent', tabPanel, ...
'Padding', 5);
secondVBox = uiextras.VBox('Parent', secondHBox);
axes('parent', secondVBox);
hold on;
plot(100:-1:1);
uicontrol('style', 'pushbutton', 'String', 'b2', 'parent', secondVBox);

set(secondVBox, 'Sizes', [-4 -1]);

One workaround is to remove the 'Padding' attribute from tabPanel. Another workaround is to fill a cell of the Grid (which enables additions to the gui easily) with uiextras.empty.

Due to several possible 'solutions' it is not clear for me where the actual problem lies. Can anyone help me out?

03 Jul 2012 Alain Barraud

Fantastic,very well written, stable, works perfectly, no problem to use within complex GUI application.
Howewer two questions. How can I add some small trianguler mark on the separation bar (as active button) to set directly the divide value to some max and/or min value.(Full size of one the two splitted panels obtained with uiextras.V(H)BoxFlex).
When uiextra.TabPanel has many panels, there may be not enough room to see all the titles. How to add some facility to sroll right or left in order to access to all title panels?

Lastly, the documentation is one of the best or perhaps the bestI have never seen within FEX submission!!
Thanks a lot!

05 Jun 2012 Jens  
04 May 2012 Brendan

Hi Ben,

Cracking piece of kit - should definitely become part of core MATLAB.

One issue though, - tabpanels don't appear to support 3D plotting with transparency. I have an application where I need two panels for 3D graphics and two for 2D graphics. I want to use lighting and transparancy in my 3D plots (so render with opengl). I'm having problems doing this.

For example:

f = figure();
p = uiextras.TabPanel( 'Parent', f, 'Padding', 5 );

axes( 'Parent', p );
plot( sin(0:0.1:2*pi) );

axes( 'Parent', p );
surf( peaks )

p.TabNames = {'Sin', 'Peaks'};

doesn't appear to work properly. A portion of the 3D axes are visible in the 2D panel. I can remove this effect by switching the renderer to zbuffer but then I can't use transparency.

I'm guessing that this has something to do with the way that MATLAB is rendering the components - does anyone have any ideas for a workaround?

Cheers,

B

24 Apr 2012 Maxime Peuch

None of the solutions you suggest works. But I find a way :
I declare the main_Vbox as a global variable, not a part of a structure. It's implies some adjustments in my code but it will work just fine!

Thank for your quick answer, it led me to a solution.

With respect,
Maxime Peuch.

24 Apr 2012 Ben Tordoff

Hi Max, can you try setting it using "dot" notation:

GUI_data.main_Vbox.Sizes = [...]

A few people in the comments above have noted some odd behaviour when you put layouts inside a struct. It seems that they are then not recognized as proper objects. An alternative is something like:

tmp = GUI_data.main_Vbox;
set(tmp, 'Sizes', [...]);

Let me know if either of these options help.

Ben

24 Apr 2012 Maxime Peuch

Hi Ben,
First of all, Great Work! It's exactly what I needed.
I have an issue :

I created a GUI. Using check-boxes, I want to resize the component of an Vbox but I have an error message.

I create the Vbox an put some Hboxes in it.
In the callback function of the check-boxes, I wrote :
set(GUI_data.main_Vbox, 'Sizes', [...]); %GUI_data is the global variable that handles all GUI components.

The error message is :
??? Error using ==> set
There is no 'sizes' property in the 'uipanel' class.

Error in ==> callback_function at 174
set(GUI_data.main_Vbox, 'sizes', sizes);

??? Error while evaluating uicontrol Callback

Apparently, in other functions, a Vbox in see as a uipanel. How can I change the 'Sizes' property from outside the function I create it ?

Thanks, Max.

09 Apr 2012 Eric Donley

Please make this part of the Core MATLAB! I have wanted this for so long.

14 Mar 2012 Ben Tordoff

Hi Martyn, where does this warning come from - is it mcc? The toolbox doesn't contain a Tabpanel.p, so presumably this is a file being generated during compilation from TabPanel.m? What release are you using so that I can try and reproduce the same?

If you have a short example that shows this, feel free to email it to me using my author page (click my name next to this post).

Cheers. Ben

14 Mar 2012 Martyn Dorey

I get a message when compiling that the Tabpanel.p will not be supported in future versions... is it possible to update this file? Thanks and great piece of work.

03 Mar 2012 Jarrod Rivituso  
01 Mar 2012 Dani

Hi again,
this is embarrassing, but I cannot reproduce this. So please just ignore this.
Dani

27 Feb 2012 Dani

Hi,

the getpixelposition.p in the patch directory only takes one input argument as opposed to the corresponding Matlab function. Would it be possible to sync these two?

Thanks

Dani

27 Feb 2012 Ben Tordoff

Hi Dane,

I'm glad this has helped you in your work even with the problems. I have been looking into both the disappearing axes problem and ways to speed-up initialization, but right now don't have any good solutions that don't also break something else. Hopefully I will find a way to improve these soon, and will be able to post an update.

Ben

27 Feb 2012 Dane

Ben,
Thank you for this excellent tool. I've used it to develop MATLAB applications for a laser laboratory - interfacing and acquiring data from hardware, as well as data processing and visualization. Your toolkit has made things much more organized and has also influenced my decision to use MATLAB as a platform.

Some feedback:
I have experienced the disappearing axes problem mentioned by Brett and M Koelemay. I have tested both their code snippets in R2011b and reproduced the behavior they report. I haven't investigated Brett's HBox position solution because my axes are buried several levels deep and don't know which Container to play with. M Koelemay's resizing suggestion works every time however.

Regarding performance, for complex applications the startup time is becoming a slight nuisance. This could be related to Holger's suggestion of removing obj.redraw statements. Perhaps a command which globally requests a deferral of redraws, until a partner command is called again? This could be placed in constructor/GUI initialization code.

23 Feb 2012 M Koelemay

Fantastic toolbox, by the way

23 Feb 2012 M Koelemay

I also am having issues with "disappearing axes" on tab/cards. Sometimes the axes appear "half drawn" or sized incorrectly, and sometimes missing completely. Stepping through the following code will illustrate the issue (tested in R2010b and R2011a). Any help would be greatly appreciated.

f = figure;
cp = uiextras.CardPanel('Parent',f);
p1 = uiextras.Panel('Parent',cp);
p2 = uiextras.Panel('Parent',cp);

g = uiextras.Grid('Parent',p1);
ax = axes('Parent',g);
plot(ax,randn(10,1));
ax = axes('Parent',g);
plot(ax,randn(10,1));

g = uiextras.Grid('Parent',p2);
ax = axes('Parent',g);
plot(ax,randn(30,1));

% card 2 showing with 1 axes, all good

cp.SelectedChild = 1;

% card 1 showing blank, but should have 2 axes

% resizing the figure slightly makes axes appear!
set(f,'position',.99*get(f,'position'));

% going back to card 2, appears blank
cp.SelectedChild = 2;

% resizing the figure slightly makes axes appear!
set(f,'position',.99*get(f,'position'));

09 Feb 2012 Benjamin  
07 Oct 2011 jvc

Absolutely terrific! Thanks to the authors for this incredibly useful tool.

I have encountered one problem - I find that figures which contain the GridFlex object cannot be saved to disk without hanging Matlab. If I simply replace GridFlex with Grid then all is well. When a figure with GridFlex is saved the file is actually written to disk but Matlab has to be manually killed. When the saved figure is subsequently reloaded it generates a slew of errors like this:

??? Attempt to reference field of
non-structure array.

Error in ==>
MousePointerHandler>@(varargin)obj.onMouseMoved(varargin{:})
at 42
set(fig,'WindowButtonMotionFcn',
@obj.onMouseMoved);

06 Oct 2011 Sim

Great tool.

There is a problem with the BoxPanel. The widgets do not get the correct color when I set it to a different color than the default blueish one (in fact the widget color is hardcoded as 'titleColor' at line 71).

15 Sep 2011 Eva

Great Submission, the GUIs have a nice look.
I've experienced the same problem as Brett with "vanishing axes" but ao far didn't have any succes with his solution.
Any other ideas why this problem might occur?
Eva

31 Aug 2011 Brett Gyarfas

Hi Ben,
Thanks for the reply, I think I found my problem though. It had to do with having an axes which was a child of an HBox that was embedded in a bunch of VBox & HBox's and setting the selectedChild to a tab where the axes wasn't. I was able to fix it by making sure the VBox & HBox's units were set to normalized and the position set to [0 0 1 1].

Here is an example though to illustrate. The first time you run it you'll notice that 'Page 2' appears empty. If you run it again with the last line commented out then it appears to work fine. If you run it one last time with the last line uncommented and the first HBox with the units as normalized and position [0 0 1 1] (uncomment line 7, comment line 8) then you can start on the first Page and still have Page 2 work properly.

%Example of 'disappearing' axes
newFig = figure('Toolbar', 'None', 'MenuBar', 'None', 'Position', [0 0 200 350]);

g = uiextras.TabPanel('Parent', newFig);

uicontrol('Parent', g, 'Background','r')

% z = uiextras.HBox('Parent', g,'Units', 'normalized', 'Position', [0 0 1 1]);
z = uiextras.HBox('Parent', g);

uiextras.Empty('Parent', z);

y = uiextras.VBox('Parent', z);

uiextras.Empty('Parent', y);

zxcv = axes('Parent', y,...
'ActivePositionProperty', 'Position', ...
'GridLineStyle', 'none', 'TickLength',...
[0 0],'XLim',[0 11], 'YLim', [0 11]);

tData = uint8(round(rand(10,10,3).*255));

image('Parent', zxcv, 'CData', tData);

uiextras.Empty('Parent', y);

set(y, 'Sizes', [-1 20 -1]);

uiextras.Empty('Parent', z);

set(z, 'Sizes', [-1 20 -1]);

g.SelectedChild = 1;

31 Aug 2011 Ben Tordoff

Hi Brett, could you share a short example to demonstrate this? Glad you're finding it useful and educational.

Thanks
Ben

30 Aug 2011 Brett Gyarfas

Awesome Toolbox! I've enjoyed looking through the code to help me in my own OOP work in MATLAB.
I found a bug with using Axes and the TabPanel. If you have an Axes on a tab and you switch to another that has a 'spacing' where the axes is in the other tab then you can see the axes. I don't know if this is related to the clipping bug w/ UIPANELS or not but I thought I would put it out there.

Thanks Again!
Brett

28 Jul 2011 Etienne

That works great, thanks Ben.

28 Jul 2011 Ben Tordoff

Hi Etienne,
we've had a few requests to make the properties of the layouts observable, which would have helped - I will look into this. However you can do this in a neater way as follows:

<code>
% Build a simple GUI
h = uiextras.HBoxFlex('Spacing',10);
button = uicontrol( 'String', 'button', 'Parent', h );
table = uitable( 'Parent', h );
% Now listen out for movements
addlistener( button, 'Position', 'PostSet', @(a,b) disp('button moved') );
addlistener( table, 'Position', 'PostSet', @(a,b) disp('table moved') );
</code>

Hopefully you can just slot your desired callback into the final argument to "addlistener" and you're done. This also has the advantage of not being anything to do with the layouts - it'll work no matter how you design your GUI.

Let me know if that works for you.
Ben

28 Jul 2011 Etienne

Hi Ben

I have a uitable placed in an HBox object, and would like the table to resize with the divider. I was hoping to do this with a callback from the HBox component. How would I go about implementing this type of functionality?

Regards

Etienne

P.S. Great toolbox by the way.

17 Jul 2011 Etienne Coetzee

Great submission. Makes the look and feel a lot better than previously. Thanks.

13 Jul 2011 Joseph Burgel

Ben,

Regarding July 1 post, I created a public property called "Locked" and wrapped the tab callback in TabPanel:

function iTabClicked( src, evt, obj, idx ) %#ok<INUSL>

if ~obj.Locked
% Call the user callback before selecting the tab
evt = struct( ...
'Source', obj, ...
'PreviousChild', obj.SelectedChild, ...
'SelectedChild', idx );
uiextras.callCallback( obj.Callback, obj, evt );
obj.SelectedChild = idx;
end

end % iTabClicked

Setting Locked to true will allow the user to do things on the active tab but will not allow the tab to change. I tried to subclass TabPanel and overload 'onChildAdded' and 'iTabClicked' to do this but couldn't get this to work because of these private properties:

properties( SetAccess = private, GetAccess = private, Hidden = true )
Images_ = struct()
TabImage_ = []
PageLabels = []
end % private propertie

Next rev, can you add the Locked feature or set these properties to 'protected'

Great package. Thanks.

01 Jul 2011 Joseph Burgel

Hi Ben,

I've got a tab panel where I'd like to implement a 'edit' mode on one of the tabs. The user should NOT be able to change the active tab until she comes out of 'edit' mode. So, during 'edit mode' the tab control should be disabled. The problem is, Enable property on the tab disables the tab kids as well so the user cannot do anything to child controls of the tab while in 'edit' mode. I'm not allowed to subsequently change Enable on kids either. I see in your code where to change this. Should I just subclass the TabPanel and implement what I describe. Your comments? Suggestions?

16 Jun 2011 Henry Harrison

Hi- thanks for a great toolbox!

I had a quick question. Is there any way to get a ButtonBox to behave like a uibuttongroup? Basically to enforce 1 button selected at a time, and a selectionchange callback. Should not be hard to implement manually but a bit over my head I'm afraid.

31 May 2011 Nicolas

got it:
delete(get(layout, 'Children'));

30 May 2011 Nicolas

it's ok, i'll rearange to use an entire column :/ thank you for trying!

could you help me to destroy/delete a layout and replace it by another one?
or even better:
how to clear the content of a layout to refill it.

thx

27 May 2011 Ben Tordoff

I've tried a few things and asked a few people and it looks like getting the clipping right isn't currently possible. If you just need buttons and other similar widgets to be scrollable it might be possible to do it all using a Java scroll-panel embedded in the MATLAB figure. You can't put MATLAB widgets inside one of those though. I can't think of any other good options, sorry.

27 May 2011 Nicolas

Jason Kinchen has done a very nice ScrollPanel class.
However it also laks the ability to clip "heavyweight object" (buttons, tables, ect.)

http://www.mathworks.com/matlabcentral/fileexchange/29776-scrollpanel

27 May 2011 Nicolas

Ey Ben

I was just about to formulate occuring problems with clipping.
Obviously you've already understood ;)

"...using some combination of parenting and clipping settings."
If you could give me some more hints I'll try to make it work and keep you updated...

thx

ps: the idea of posting my own fileexchange hasn't occured to me jet. since you think it could be worthwhile i do consider...

27 May 2011 Ben Tordoff

Hi Nicolas, this is nice. Thanks for posting it for everyone to share. You might consider submitting it as a separate File Exchange submission and posting a link here. That way you can update the code without having to keep reposting it.

However, there are some clipping issues. If you don't have the main panel filling the window (e.g. position [0.1 0.1 0.8 0.8]) then the contents of the scroll panel show outside the panel boundary. This doesn't matter if the panel fills the figure. It might be possible to fix this using some combination of parenting and clipping settings. I haven't had chance to try these yet but will let you know.

Thanks. Ben

27 May 2011 Nicolas

addlistener(... ;)

26 May 2011 Nicolas

sorry 4 the previous post, there have been some buggs...
this version also has mousewheel functionality:
(this might not bee the apropriate forum to post this but i belive it might help Ben to improve this great toolbox)
********************************
function test
%

mainpanelheight = 400;
mainpanelwidth = 400;
scrollbarwidth = 20;

f = figure('Position', [50 50 mainpanelwidth mainpanelheight], ...
'ResizeFcn', @slider);

mainpanel = uiextras.HBox('Parent', f, ...
'Units', 'normalized', ...
'Position', [0 0 1 1]);

controlpanel = uiextras.VBox('Parent', mainpanel);
scrollpanel = uiextras.VBox('Parent', mainpanel);

uicontrol('Parent', controlpanel, 'Background', 'r')
uicontrol('Parent', controlpanel, 'Background', 'b')
uicontrol('Parent', controlpanel, 'Background', 'g')

set(controlpanel, 'Sizes', [400, 1000, 200]);
controlpanelheight = sum(get(controlpanel, 'Sizes'))
controlpanelpos = [1 (mainpanelheight-controlpanelheight) mainpanelwidth-scrollbarwidth controlpanelheight];
set(controlpanel, 'Position', controlpanelpos);

set(mainpanel, 'Sizes', [-1 scrollbarwidth]);

pause(0.1);

scrollbar = uicontrol('Style', 'slider', ...
'Parent', scrollpanel, ...
'String', 'drueck', ...
'Callback', @slider);
addlistener(scrollbar, 'Value', 'PostSet', @slider);
set(f, 'WindowScrollWheelFcn', @scroll);

set(scrollbar, 'Value', 1);

slider;

function slider(~, ~)
pause(0.05);

set(mainpanel, 'Units', 'pixel');

mainpanelpos = get(mainpanel, 'Position');
mainpanelwidth = mainpanelpos(3);
mainpanelheight = mainpanelpos(4);
controlpanelpos(2)=(mainpanelheight-controlpanelheight);
controlpanelpos(3)=(mainpanelwidth-scrollbarwidth);

if(mainpanelheight>controlpanelheight)
set(scrollbar, 'Value', 1, 'Enable', 'off');
else
set(scrollbar, 'Enable', 'on');
end %if

slidervalue = get(scrollbar, 'Value');

set(controlpanel, 'Position', [controlpanelpos(1) controlpanelpos(2)+(mainpanelheight-controlpanelheight)*(slidervalue-1) controlpanelpos(3) controlpanelpos(4)])

set(mainpanel, 'Units', 'normalized');

set(scrollbar, 'SliderStep',[mainpanelheight/controlpanelheight/5 mainpanelheight/controlpanelheight])
end

function scroll(object, event)
scrollbarstep = get(scrollbar, 'SliderStep');
newscrollbarvalue = get(scrollbar, 'Value')-event.VerticalScrollCount*scrollbarstep(1);
if(newscrollbarvalue>1)
newscrollbarvalue = 1;
elseif(newscrollbarvalue<0)
newscrollbarvalue = 0;
end %if
set(scrollbar, 'Value', newscrollbarvalue);

end

end
********************************

26 May 2011 Nicolas

Hy Ben!
Thank you for the feedback.
I've managed to get it to work for my purposes. Here the example (sorry it's undocumented):
********************************
function test
%

mainpanelheight = 400;
mainpanelwidth = 400;
scrollbarwidth = 20;

f = figure('Position', [50 50 mainpanelwidth mainpanelheight], ...
'ResizeFcn', @slider);

mainpanel = uiextras.HBox('Parent', f, ...
'Units', 'normalized', ...
'Position', [0 0 1 1]);

controlpanel = uiextras.VBox('Parent', mainpanel);
scrollpanel = uiextras.VBox('Parent', mainpanel);

uicontrol('Parent', controlpanel, 'Background', 'r')
uicontrol('Parent', controlpanel, 'Background', 'b')
uicontrol('Parent', controlpanel, 'Background', 'g')

set(controlpanel, 'Sizes', [400, 400, 20]);
controlpanelheight = sum(get(controlpanel, 'Position'));
controlpanelpos = [1 (mainpanelheight-controlpanelheight) mainpanelwidth-scrollbarwidth controlpanelheight];
set(controlpanel, 'Position', controlpanelpos);

set(mainpanel, 'Sizes', [-1 scrollbarwidth]);

pause(0.01);

scrollbar = uicontrol('Style', 'slider', ...
'Parent', scrollpanel, ...
'String', 'drueck', ...
'Callback', @slider);
set(scrollbar, 'Value', 1);

slider;

function slider(~, ~)
pause(0.01);
slidervalue = get(scrollbar, 'Value')

set(mainpanel, 'Units', 'pixel');

mainpanelpos = get(mainpanel, 'Position');
mainpanelwidth = mainpanelpos(3)
mainpanelheight = mainpanelpos(4)
controlpanelpos(2)=(mainpanelheight-controlpanelheight);
controlpanelpos(3)=(mainpanelwidth-scrollbarwidth);

set(controlpanel, 'Position', [controlpanelpos(1) controlpanelpos(2)+(mainpanelheight-controlpanelheight)*(slidervalue-1) controlpanelpos(3) controlpanelpos(4)])

set(mainpanel, 'Units', 'normalized');
end

end
*************************
Hopefully this can help others...
Greetings!

25 May 2011 Ben Tordoff

Hi Nicolas, your top-level layout defaults to being the same size as its parent figure (400x400) and you haven't told it do grow. It has to fit its contents into that space and no matter how big you tell the contents to be, unless you also tell the layout to grow they will be reduced to fit. Simply put "set( layout, 'Position', [1 1 400 820] )" and the layout grows, along with its contents.

I do not know of any simple way to add scroll-bars to a panel. You might be able to hack something together using sliders but I suspect you will hit problems with clipping. I'll do a bit of investigating though.

Cheers. Ben

25 May 2011 Nicolas

quote Adam:
Wonderful package. But I would like to ask if there is any possibility to add scroll bars to your panels, and if so, how could I do that. Thank you very much, Adam
end quote

I also would like to know how to make this work.
Here an example:

f = figure('Position', [50 50 400 400])
layout = uiextras.VBox('Parent', f);
uicontrol( 'Parent', layout, 'Background', 'r' )
uicontrol( 'Parent', layout, 'Background', 'b' )
uicontrol( 'Parent', layout, 'Background', 'g' )
set(layout, 'Sizes', [400, 400, 20]);

The window size is 400 and i want to add 3 items with a total size greater 400.
Instead of using a scrollbar the items are scaled to fit into the window.
If this behaviour were requested one could use negative numbers.

Thank you for you consideration and this (otherwise) fabulous toolbox.
I look forward to reading from you...

18 May 2011 Thomas

Fantastic!

18 May 2011 Ben Tordoff

Hi Thomas. Your example produces an error message because "units" should have a capital "U" and position a capital "P". Fix this and it works fine as far as I can see.

Cheers. Ben

17 May 2011 Thomas

I'm afraid that I don't see any scaling behavior in the included examples - even with the changes suggested on 06 may. I just get a grey figure. (with MatLab 2011a)

Here's the code:

f = figure( 'Position', 200*ones(1,4) );
vbox = uiextras.VBox( 'Parent', f, 'units','normalized', 'position', [0 0 1 1] );
axes( 'Parent', vbox );
hbox = uiextras.HButtonBox( 'Parent', vbox, 'Padding', 5 );
uicontrol( 'Parent', hbox, ...
'String', 'Button 1' );
uicontrol( 'Parent', hbox, ...
'String', 'Button 2' );
set( vbox, 'Sizes', [-1 35] )

10 May 2011 Andreas  
09 May 2011 Simon

Great! Thanks, Ben!

06 May 2011 Ben Tordoff

Hi Simon, you need to set the units of "vbox" to be normalized and the position to be [0 0 1 1]. This is exactly as you would do for any other MATLAB GUI element if you wanted it to scale with the figure. I hope to make this the default again in future - it used to be but it caused a bug with the way panels were drawn.

06 May 2011 Simon

Hm. Maybe I'm missing something but I copied this code from the docs:

f = figure( 'Position', 200*ones(1,4) );
vbox = uiextras.VBox( 'Parent', f );
axes( 'Parent', vbox );
hbox = uiextras.HButtonBox( 'Parent', vbox, 'Padding', 5 );
uicontrol( 'Parent', hbox, ...
'String', 'Button 1' );
uicontrol( 'Parent', hbox, ...
'String', 'Button 2' );
set( vbox, 'Sizes', [-1 35] )

And it doesn't scale at all.

I'm completely new to MATLAB GUIs so I apologize if this is a stupid question.

03 May 2011 Adam

Wonderful package. But I would like to ask if there is any possibility to add scroll bars to your panels, and if so, how could I do that. Thank you very much, Adam

13 Apr 2011 Ken

Thanks for the quick response Ben. This issue is covered by Bug#260354, so I added feedback on that bug.

13 Apr 2011 Ben Tordoff

Hi Ken,
This is a problem with UIPANELs in general, not just the ones used by the Layouts to group their contents. You can easily reproduce the problem with a single UIPANEL:

f=figure;
p=uipanel('Parent',f);
a=axes('Parent',p);
title('Axes in a panel');
axis(a,[-1 1 -1 1]);
rectangle('Parent',a,'Position',[-2 -0.5 4 1],'FaceColor','r');
patch([0.5 0.5 0.75 0.75],[-2 2 2 -2],'y','Parent',a);
line([-2 2],[-0.5 0.5],'Parent',a);

I would strongly urge you to report this bug here: http://www.mathworks.com/support/bugreports

In some cases you may be able to work around it by switching the figure renderer to be OpenGL or ZBuffer, but each has its own quirks. For your example these other renderers draw the line and patch with different depth ordering, so they may just make things worse. However, I'm not sure what else to suggest.

Sorry about that.
Ben

13 Apr 2011 Adam Wyatt

Excellent work!

12 Apr 2011 Ken

Just in case it got lost among the comments above, I want to re-post a bug I encountered with clipping...

Putting an axes object inside a layout box appears to break clipping for rectangles and patches plotted in those axes (but strangely not for lines).

Here's a code snippet that demonstrates the issue...

f=figure;
a=axes('Parent',f);
title('Without GUI Layout Toolbox');
axis(a,[-1 1 -1 1]);
rectangle('Parent',a,'Position',[-2 -0.5 4 1],'FaceColor','r');
patch([0.5 0.5 0.75 0.75],[-2 2 2 -2],'y','Parent',a);
line([-2 2],[-0.5 0.5],'Parent',a);

f=figure;
hbox=uiextras.HBox('Parent',f);
a=axes('Parent',hbox);
title('With GUI Layout Toolbox');
axis(a,[-1 1 -1 1]);
rectangle('Parent',a,'Position',[-2 -0.5 4 1],'FaceColor','r');
patch([0.5 0.5 0.75 0.75],[-2 2 2 -2],'y','Parent',a);
line([-2 2],[-0.5 0.5],'Parent',a);

Ken

06 Apr 2011 Julian Villegas

Thank you very much for this useful and well documented Toolbox.

I'm running into a problem and I was hoping someone with more experience in this could help me:

My application uses a FlexGrid with three axes, and one of the axes (the one in the bottom) comprises several jcontrol objects. Everything works fine, and looks good, excepting when a user resize the axis containing the jcontrol objects or the axis immediately on top. The jcontrol are not repositioned where they should be. How can I call a function when the axis is being resized?
Thank you.

04 Apr 2011 Ben Tordoff

Hi Johnson,
thanks for reporting this - it will be fixed in the next version. In the meantime, replace "figh" with "obj.Parent" at the point the error was hit and this should fix things.

Cheers. Ben

02 Apr 2011 Johnson Gad Elkarim

There is an error
??? Error while evaluating figure WindowButtonMotionFcn

??? Undefined function or variable 'figh'.

Error in ==> MousePointerHandler>MousePointerHandler.onMouseMoved at 79
currpos = hgconvertunits( figh, [currpos,0,0], figUnits,
'pixels', 0 );

Error in ==> MousePointerHandler>@(varargin)obj.onMouseMoved(varargin{:}) at
42
set(fig,'WindowButtonMotionFcn', @obj.onMouseMoved);

??? Error while evaluating figure WindowButtonMotionFcn

31 Mar 2011 Emil

Thank you for your quick reply Ben! Your suggestion did the trick. The 'TabSize' property was what I was looking for.

Don't be sorry for not including this in the documentation. I'm very grateful that this toolbox is available in the first place. Everything else is just icing on the cake :)

Thanks again!

31 Mar 2011 Ben Tordoff

Hi Emil, I believe what you want is something like:

t = uiextras.TabPanel( 'FontSize', 16, 'TabSize', 150, 'Units', 'Normalized', 'Position', [0 0 1 1] );
uicontrol( 'Parent', t );
uicontrol( 'Parent', t );

The 'TabSize' property lets you control the size of the tabs. Let me know if this doesn't fix your problem. For some reason this property was missing in the documentation - sorry about that.

Ben

31 Mar 2011 Ben Tordoff

Thanks Jesse, I'm glad you're finding it useful. Please feel free to add any suggestions for improvements or fixes to this forum - I do keep track of them even if I can't implement them all.

Cheers. Ben

30 Mar 2011 Jesse Hopkins

Thanks so much for this awesome submission. It's been a lifesaver and made me look really impressive :)

But my problem is.. JK, thought I'd just leave a thank you without a problem statement!

30 Mar 2011 Emil

First of all I would like to express my gratitude for all your hard work. This is a very useful tool which saves a lot of time!

I have a problem with TabPanel. The width of each tab is fixed and doesn't stretch with the TabNames. If I have longer TabNames than 5 characters in the default FontSize the rest is cut of. Is t suppose to be like this or am I doing something wrong? I also haven't found any property which sets the width of each (or all) tab.

Best regards
Emil

25 Mar 2011 Ben Tordoff

Hi Patrick. Yes, this is a known problem. The older version used to default to units being "normalized" and position [0 0 1 1], which makes it fill the window. Unfortunately this caused a bug with panels where extra space was left at the top. I had to change them back to defaulting to pixel units which means they no longer automatically resize with the window. I hope to restore the default to being "normalized" once I've found a way to do it without breaking the panels.

In the meantime, simply set your top-most layout to have pixel units and position [0 0 1 1]. It will then always fill the figure. So long as it isn't a panel you shouldn't suffer any ill effects.

Hope that helps. Ben.

24 Mar 2011 Patrick

Hi, great toolbox! It sould really be a part of the MATLAB stanard distrubtion.

Now to my problem: I have two vboxes that are children an hbox which is a child my main figure. With the older version, the hbox and the two vboxes would resize with the windo, but with the new version, released in March, they won't resize. Do you know why this would happen? Thanks.

17 Mar 2011 Ben Tordoff

Hi Joseph. As regards hiding a child, the best thing to do is not to reparent it as that can make it hard to put back in the right place (for instance if you want to hide the middle of three children of an HBox then put it back in the middle). For many cases, simply hiding it is enough:

f = figure();
h = uiextras.HBox( 'Parent', f, 'Units', 'Normalized', 'Position', [0 0 1 1] );
controls = [
uicontrol( 'Parent', h, 'String', 'Button 1' )
uicontrol( 'Parent', h, 'String', 'Button 2' )
uicontrol( 'Parent', h, 'String', 'Button 3' )
];
pause(1)

set( controls(2), 'Visible', 'off' );
set( h, 'Sizes', [-1 0 -1] );
pause(1)

set( controls(2), 'Visible', 'on' );
set( h, 'Sizes', [-1 -1 -1] );

Note however that if "Spacing" is not zero you end up with some extra space between the remaining elements. I've tried the re-parenting away technique too and the following seems to work OK:

f = figure();
h = uiextras.HBox( 'Parent', f, 'Units', 'Normalized', 'Position', [0 0 1 1] );
null = uiextras.HBox( 'Parent', f, 'Position', [-1000 -1000 10 10] );
controls = {
uicontrol( 'Parent', h, 'String', 'Button 1' )
uicontrol( 'Parent', h, 'String', 'Button 2' )
uicontrol( 'Parent', h, 'String', 'Button 3' )
};
pause(1)

set( controls{2}, 'Parent', double(null) );
pause(1)

set( controls{2}, 'Parent', double(h) );

16 Mar 2011 Marian Hertrich

Hi Ben,

thanks for your reply. Meanwhile we fixed the problem by putting the parent-handle in brackets
gui.box2=uiextras.VBox('Parent', gui.box1); % here it works without problem
gui.edit1=uicontrol(...
'Style', 'Edit',
'Parent', gui.('box2'));

Anyway this problem occured only in a few of our GUI's, for others the conventional call went without errors. Maybe our workaround helps to locate and fix the problem.

16 Mar 2011 Joseph Burgel

Here's some code that show's a (at least one) problem:

classdef TestIt < hgsetget
properties
ShiftPanel
end

methods

function Test1(Obj)

f = figure( 'Position', 200*ones(1,4) );
vbox = uiextras.VBox( 'Parent', f );
axes( 'Parent', vbox );
hbox = uiextras.HButtonBox( 'Parent', vbox, 'Padding', 5 );
uicontrol( 'Parent', hbox, ...
'String', 'Button 1' );
uicontrol( 'Parent', hbox, ...
'String', 'Button 2' );

end

function Test2(Obj)

f = figure( 'Position', 200*ones(1,4) );
vbox = uiextras.VBox( 'Parent', f );
axes( 'Parent', vbox );
Obj.ShiftPanel = uiextras.HButtonBox( 'Parent', vbox, 'Padding', 5 );
uicontrol( 'Parent', Obj.ShiftPanel, ...
'String', 'Button 1' );
uicontrol( 'Parent', Obj.ShiftPanel, ...
'String', 'Button 2' );
end



end

end

Test1 works but Test2 doesn't. Why can I not instantiate a member property but I can instantiate to a local variable??

16 Mar 2011 Joseph Burgel

Further investigation reveals the tab container is not rendering correctly because one of the child uiextra containers contains a uicontrol object. remove the uicontrol and the problem disappears....

16 Mar 2011 Joseph Burgel

Just to echo the parenting concerns. I'm not having a lot of luck moving containers from one parent to another. Using double() isn't helping. uiextras parents or classic Matlab parents do not seem to matter. Sometimes I get indexing errors from within the uiextra code where the number of kids are not correct. Now, I'm getting problems with a Tab view not rendering out correctly because child containers were re-parented.

16 Mar 2011 Joseph Burgel

What do you all do if you need to remove a container from a parent temporarily? Say, due to state, I only want 2 kids not three. Where do I put third kid. My solution was to give the figure a invisible "Null" container and parent the orphaned container to null when I don't need it. When I tried to use Uiextras.panel as "Null" I got several errors in the uiextras code. When I made the null container's type uipanel, it worked. Not sure why uiextras.panel didn't work? Good method or keeping orphaned containers?

16 Mar 2011 Sebastian Held

Hi Ben,
thanks for the quick reply. Ok a read about that before, but didn't realize it's the same issue. Sorry for the noise.

16 Mar 2011 Ben Tordoff

Hi Sebastian, Marian,

this has come up a few times now in slightly different ways, and whilst I still don't know the cause, the remedy is to call double(layout) to explicitly convert the layout to a double handle:

set(u,'Parent',double(layout)); %reparent

It shouldn't be necessary, and wasn't in older MATLAB releases. It is being investigated...

16 Mar 2011 Sebastian Held

I've a problem reparenting objects drawn inside GUIDE to a layout:
f=figure;
u=uicontrol(f,'Style','Frame');
layout = uiextras.GridFlex( 'Parent', f );
set(u,'Parent',layout); %reparent
??? Error using ==> set
Parameter must be 'hgsetget'.
isa(layout,'hgsetget')
ans = 1

Why does Matlab 2010b not recognize layout as a 'hgsetget'?

16 Jan 2011 Marian Hertrich

Hi Ben, thanks for this excellent tool. We have developed a relatively large project using the Gui Layout Tool v1p8.
I just tested it on 2010b and get the error explained by William Weideman on Sept, 15th: Conversion to double from unknown is not possible.
In Container.m there is a function that should actually cast the handle in the structure (function container = double( obj )) but I still get the same error. Applying your workaround would require a lot of work. Is there a better solution in sight?

13 Jan 2011 Ben Tordoff

Hi Dani, Dirk, sorry for the lack of response. I will look into these issues as soon as I can take some time out. Bear with me!

12 Jan 2011 Dani

I think I have a similar problem as Andrew Stamps. When I switched to 1.8 all my layouts all of a sudden had additional spaces. This can be reproduced with the following code:

f = figure();
h_p = uiextras.Panel( 'Parent', f, 'Title', 'Test', 'Padding', 0);
h_vbox = uiextras.VBox('Parent', h_p, 'Padding', 0, 'Spacing',0);
uicontrol('Parent', h_vbox, 'Style', 'text', 'String', 'Test', 'HorizontalAlignment', 'Left');

There is a large gap between the uicontrol and the top panel border. Previous to 1.8 this was not the case and I have no idea how to control this.

29 Dec 2010 Dirk Engel

Thank you Ben and David for this contribution. The flexible boxes finally provide a way of real interactive GUI scalability. Found nothing comparable.

Unfortunately, still some bugs and missing features (in v1.8) for large GUI applicatons. E.g.
* for containers with 2 or more dividers, sliding one divider behind another one throws "Width and height must be > 0" in Container>Container.repositionChild at 340
* dividers often overlap borders of adjacent panels, looks very unprofessional (perhaps a rounding problem of pixel positions?)
* poor redrawing in case of many nested flexible boxes (one has to watch the controls getting resized back and forth several times until the final result)
* user-defined WindowButtonUpFcn is getting lost when a divider is moved while any figure mode is on (e.g. zoom). When turning off the mode, the WindowButtonUpFcn of the devider is restored instead of the user-defined callback function.
* nice to have: height and width limits and maybe other constraints for flexible containers. Perhaps one can adopt some ideas from another nice layout manager: GridBagLayout. Thanks to OOP I'm of course free to do this by subclassing, but maybe the feature finds its way into the uiextras toolbox.

14 Dec 2010 Joseph Burgel

I'm getting the same bug Holger mentions above:

Try moving the vertical gridflex divider in your example "gridflexpositioning". Only the horizontal dividers are functional.

14 Dec 2010 andres llopis

Hello again. I am using the version 1.6 of the tool. Is it possible to hide a tab in a tabpanel? I don't want to delete it, just hide it.

And another one: is it possible that when you hide a button in a Vbox whose sizes are fixed pixel values (with no negative values), it resizes automatically? For example, the button underneath could move up to fill the space the one you hid left behind.

Thanks a lot guys =)

10 Dec 2010 Joseph Burgel

Good Idea. Thanks Dave.

09 Dec 2010 David Sampson

In response to the question about custom resize behavior, subclass our relevant class and implement your own resize method.

09 Dec 2010 Joseph Burgel

I'm looking at issues where, for instance, I want to maintain the aspect ratio of flex box kids. So, I'd like to know when a flex box resizes - ideally just before and just after a resize. Then, based on this, I might change the sizes property of sub containers, resize panels etc. I don't see callbacks for these events or preset postset, setobservable property attributes set to allow this on the ideal properties. Things like flex resize, I'm currently using child uipanel resize handlers to do this but this seems sloppy. Anybody have a 'best practice' approach to handling resize events in the toolbox?

09 Dec 2010 andres llopis

Hello there!

I am having a problem with the stacking of components. I want to be able to move one of the children of a vbox behind the other one, in order to scroll through the interface. The problem is that the moving children is always on top. I have tried using uistack, but it doesn't work either.

Any help would be appreciated. Thank you!

19 Nov 2010 Ken

Thanks for this great toolbox Ben and David, I've found it very useful.

I think I've discovered a bug. Putting an axes object inside a layout box appears to break clipping for rectangles and patches plotted in those axes (but strangely not for lines).

Here's a code snippet that demonstrates the issue...

f=figure;
a=axes('Parent',f);
title('Without GUI Layout Toolbox');
axis(a,[-1 1 -1 1]);
rectangle('Parent',a,'Position',[-2 -0.5 4 1],'FaceColor','r');
patch([0.5 0.5 0.75 0.75],[-2 2 2 -2],'y','Parent',a);
line([-2 2],[-0.5 0.5],'Parent',a);

f=figure;
hbox=uiextras.HBox('Parent',f);
a=axes('Parent',hbox);
title('With GUI Layout Toolbox');
axis(a,[-1 1 -1 1]);
rectangle('Parent',a,'Position',[-2 -0.5 4 1],'FaceColor','r');
patch([0.5 0.5 0.75 0.75],[-2 2 2 -2],'y','Parent',a);
line([-2 2],[-0.5 0.5],'Parent',a);

Ken

10 Nov 2010 Sven

Ben, it's fantastic to see you responding to comments/requests. I also encountered the axes creation from a uiextras.Panel bug as above and created a bug request. You can reproduce the error with the following function:

function testgui( )
figH = figure;
s.normalPanH = uipanel('Parent',figH);
s.uiextraPanH = uiextras.Panel('Parent',figH);
tmp = s.uiextraPanH;
axH1 = axes( 'Parent', tmp ); % This command runs
axH2 = axes( 'Parent', s.normalPanH ); % This command runs
axH3 = axes( 'Parent', s.uiextraPanH ); % This command errors
end

Interestingly enough, those same commands pasted into the command window don't throw an error - it only occurs when embedded inside a function.

I have created bug report: 1-DX1A26

09 Nov 2010 Andrew Stamps

Ben,

This is essentially the same example as I posted above, but I believe it demonstrates my point:

f1 = figure;
p1 = uiextras.Panel('Parent', f1, 'Title', 'Panel 1');
p2 = uiextras.Panel('Parent', p1, 'Title', 'Panel 2');

f2 = figure;
p3 = uiextras.Panel('Parent', f2, 'Title', 'Panel 3');
p4 = uiextras.Panel('Parent', p3, 'Title', 'Panel 4', 'Units', 'Pixels');

Figure 1 has additional space at the top and right in between panel 1 and panel 2 compared to panels 3 and 4 in figure 2. I just reinstalled v1.8 and removed all other versions from my path as a precaution. I am using R2010B.

We don't appear to be able to upload files or else I would include screenshots as well.

Thanks,
Andy

09 Nov 2010 Ben Tordoff

Hi Andrew, the problem with getting a blank area near the top of panels should have been fixed by the v1.8 update. If it isn't, can you send a short example that shows the problem?
Thanks. Ben

08 Nov 2010 Andrew Stamps

I need to retract my "correction" of lines 133-134 of Panel.m. However, I believe I am now closer to an answer. In normalized units, the border/title area is excluded from the control area. You have to compensate for this when you specify the width and height to obj.ShowSelectedChild. I can provide code, if interested.

05 Nov 2010 Andrew Stamps

I wanted to follow up on my previous comment. First, I believe lines 133-134 of Panel.m should be:

x0 = border;
y0 = border;

Also, the issue with the normalized panels appears to be that the uipanel reserves some space at the top of the panel such that a normalized position of [0 0 1 1] does not fully cover the area returned by getpixelpostion. I haven't figured out yet how to set/get what the "normalized" area actually is relative to the getpixelposition area.

Thanks,
Andy

05 Nov 2010 Andrew Stamps

Ben,

I think this toolbox is fantastic. It has already saved me a ton of time. However, I wanted to point out one issue that has popped up recently. I believe that your bugfix in v1.7 that changed the unit-setting behavior when children are added has had some unintended consequences. Here's a simple example:

f = figure;
p1 = uiextras.Panel('Parent',f,'Title','Panel 1');
p2 = uiextras.Panel('Parent',p1,'Title','Panel 2');

This produces a figure where there is an overly large gap between the top of the first panel and the second inset panel. In previous versions (definitely v1.5) the gap was much tighter. If you specify pixel units for the second panel explicitly:

f = figure;
p1 = uiextras.Panel('Parent',f,'Title','Panel 1');
p2 = uiextras.Panel('Parent',p1,'Title','Panel 2','Units','pixels');

Then the figure initially looks the same as the first example, but then as soon as you do anything to resize the figure, the second panel suddenly snaps up tight to the first panel like it used to be.

I am guessing that your intentions are to have the results relatively independent of the units being used, but this does not appear to be the case.

Thanks,
Andy

03 Nov 2010 Holger

Hi Ben,

just tried it and "print" and "save" (the toolbar buttons) do work. Many thanks for that!

But I think, you introduced a bug:
Try moving the vertical gridflex divider in your example "gridflexpositioning". Only the horizontal dividers are functional.

Thanks again,
Holger

03 Nov 2010 Ben Tordoff

Hi Holger, I've just updated the package with a fix for the printing problem. Let me know if you still have problems.

29 Oct 2010 Ben Tordoff

Hi Holger, I'll look into the print problem on Monday. A work-around between now and then is to use getframe instead of print. Not ideal, I know. Hopefully I can get a fix out on Monday.

I'll have a think about the performance and see if there's a good way to reduce the number of redraws that happen.

Cheers. Ben

29 Oct 2010 Holger

I like it.

Regarding the performance:
After outcommenting obj.redraw() at many locations it's not that slow and can be used for complicated layouts with many elements.
Especially Container::OnChildAdded() and set.Children() with obj.redraw() is a real peformance hit.
So, I'm building the GUI and call redraw() manually after all childs have been added.

Anoher peformance issue is ver('Matlab'). I simply use the old version, it also works in the newer versions.

One problem though:
My figure with a gridflex can not be printed or saved (e.g. as png). I get an error in Mathworks 'print.m'.

Any chance someone can look into it?

29 Oct 2010 Holger  
19 Oct 2010 Corey Gravelle

umm SWEEeET!! This has been a savior, thanks a million (:

07 Oct 2010 Tony  
04 Oct 2010 andres llopis  
03 Oct 2010 Sherif Elnabarawy

Finally got what i am looking for ! Brilliant effort , Excellent documentation ! Great thanks !
now , i am using that fcns but i need to ask about somethings , first can i assign more than one children to HBox or Vbox and give them a positioning values ? if i created boxes for every children needed to set their resizing state , then i'll create many boxes which slow down the app. .
second , can i merge specific boxes ?

Thanks a lot,
Sherif Elnabarawy.

16 Sep 2010 Ben Tordoff

Hi William, I haven't had chance to really dig into this in detail, but suspect the problem is with the structure. For some reason it looks like in R2010b calling the "double" method fails if the object is stored as a field of a structure. I haven't found any way around this other than to take a temporary copy of the layout before use:

temp = gui.aDetailPlotB;
axes1 = axes('Parent', temp, ... );

This then seems to work. This looks like a definite regression between R2010b and R2010a and I would encourage you to report it using the links on the MathWorks homepage. I will do the same!

Let me know if that works (even if it is a pain). Ben

15 Sep 2010 William Weideman

I recently had to upgrade to the R2010b release and now I am having problems with passing handles to the objects created in the Gui Layout. It is a lot of code (a large layout with speed issues as Dani mentioned above.) I will show what is relevant IMHO.

global gui
...
function gui = createInterface()
% Create the user interface for the application and return a
% structure of handles for global use.
gui = struct();
...
gui.aDetailPlotB = uiextras.Panel('Parent', aDetailPlot, 'BackgroundColor', 'w', 'BorderType', 'none');

...

In another function file, the gui structure is passed as an argument and then we come down to:

axes1 = axes('Parent', gui.aDetailPlotB,
'ActivePositionProperty', 'OuterPosition');

I get the following error message.

??? Error using ==> axes
Conversion to double from unknown is not possible.

Stepping through the debugger, steps into Container.m (part of the +uiextras folder) where it dies in the function

function container = double( obj )
%double Convert a container to an HG double handle.
%
% D = double(C) converts a container C to an HG handle D.
container = obj.UIContainer;
end % double

I can't go back to R2010a so how do I get it working?

Thanks in advance.

01 Sep 2010 Dani

The response times for large layouts becomes quite slow, mostly due to the frequent calls to getpixelposition. Even just switching from one figure menu to the other may take a while. Is it possible to deactivate the layout management? As long as a figure does not get resized all these calls are mostly unnecessary anyhow.

12 Aug 2010 David Sampson

In response to the question regarding sizes of panel decorations, first let me state the obvious, just in case it isn't obvious. Once a panel with a container inside is on screen, you can call getpixelposition on the panel and the container inside to find the size of the decorations.

The GUI Layout Toolbox takes an outside-in approach in that contents do not influence the size of a container. You give a container some space and it lays out the contents as best it can. If the contents are too big for the container then they just disappear to the top or the right. This is fundamental to how the Toolbox works.

I have been expecting a request to support minimum sizes for contents. Anyone interested in this could extend their container of choice by adding a property and overloading redraw. Care is required to react as children are added and removed; see how we handle 'Sizes' for guidance.

The next question that arises is how to establish the minimum reasonable size for each child. I recommend hard-coding. uicontrols do provide a property 'Extent', but it doesn't return anything useful for combo boxes, and it gives the wrong answer for normalized units, and neither containers nor axes report Extent.

It is possible to enforce limits on figure size by hooking into the figure ResizeFcn. I don't advise trying this below the figure level.

11 Aug 2010 Joseph Burgel

Just answered my own question, I'm handlng the 'callback' property of the tab control.That works just find.

Never mind...

11 Aug 2010 Joseph Burgel

I need to handle the condition when a new tab is selected in the tab container. This would mean I'd like to handle the SelectedChild property change event. When I run findprop, I see that SetObservable is 0 for SelectedChild. Any suggestions? Any reason why this can't be 1? Thanks.

mp = findprop(Dat.Container.h_RightTabPanel,'SelectedChild')

mp =

meta.property handle
Package: meta

Properties:
Name: 'SelectedChild'
Description: ''
DetailedDescription: ''
GetAccess: 'public'
SetAccess: 'public'
Dependent: 1
Constant: 0
Abstract: 0
Transient: 0
Hidden: 0
GetObservable: 0
SetObservable: 0
AbortSet: 0
GetMethod: [function_handle]
SetMethod: [function_handle]
HasDefault: 0
DefiningClass: [1x1 meta.class]

11 Aug 2010 Dani

Just tried to use an VBoxFlex and could not see not access the draggable dividers. Turned out that this was caused because I had created the figure with the DefaultUIControlUnit set to 'norm', the GUI Layout Toolbox seems to rely on this to be set to pixels.

Thanks for the answers to my other questions and comments!
(The size of the panel header/title height is still open though)

11 Aug 2010 David Sampson

Dani, in response to your posting about vertical alignment of text in a row of controls, I agree that this is an issue. The issue is specific to the HBox.

We need a VerticalAlignment property for the uicontrol.

I think that the place to fix this is by creating a text label widget implemented as a uicontrol inside a uicontainer. The widget exposes a property to control vertical alignment and positions the uicontrol accordingly. I have created such a widget for inclusion in our upcoming GUI Controls Toolbox.

Another possibility is to set the vertical alignment in the underlying Java object, to which Yair Altman's findjobj can provide access.

I do not think that adding a property to provide vertical padding within the HBox is a good solution.

09 Aug 2010 David Sampson

plotyy is another example of MATLAB using two axes at the same level of the HG hierarchy. Again, put the axes inside a container, and position the container.

>> h = uiextras.HBox( 'Padding', 10, 'Spacing', 10 );
>> c = uicontainer( 'Parent', h );
>> v = uiextras.VBox( 'Parent', h, 'Spacing', 10 );
>> for ii = 1:4, uicontrol( 'Parent', v, 'String', 'Press me' ); end
>> a = axes( 'Parent', c );
>> x = 0:0.1:10;
>> plotyy( a, x, sin( x ), x, 10*cos( x ) );
>> h.Sizes = [-1 150];

09 Aug 2010 Joseph Burgel

One thing I'm dealing with now is the need to superimpose two axes over the top of each other. This, to get two Y axes on the same plot. My best guess is to put the two axes in a single uipanel and then add the panel to a parent container. Sound like a the best approach?

09 Aug 2010 David Sampson

MATLAB draws colorbars on a second set of axes that is a sibling of the first. In order to position axes with a colorbar, put the axes inside a container, and position the container. MATLAB will take care of positioning the plot and colorbar inside the container.

>> h = uiextras.HBox( 'Padding', 10, 'Spacing', 10 );
>> c = uicontainer( 'Parent', h );
>> v = uiextras.VBox( 'Parent', h, 'Spacing', 10 );
>> for ii = 1:4, uicontrol( 'Parent', v, 'String', 'Press me' ); end
>> axes( 'Parent', c );
>> peaks; colorbar;
>> h.Sizes = [-1 150]

07 Aug 2010 Dani

Last one - promised.

In your help files you show how one deals with the positioning of axes. However, most of the time one has axes with corresponding colorbars and it would be helpful to have a guideline on how to deal with having both of them.

07 Aug 2010 Dani

More questions.

1.
uicontrols such as 'text' and 'edit' styles allow for changing of their height. The exception is 'popmenu', which insists on its default height (at least I found no way around it). Combined with the problem that uicontrols do not seem to allow for vertical positioning of the content we get rather ugly top alignment when we combine the different uicontrols, e.g.

figure
DUP = get(0, 'DefaultUicontrolPosition');
uicontrol('Style', 'popupmenu', 'String', {'Yes', 'No'}, 'Value', 1, 'Position', DUP);
uicontrol('Style', 'text', 'String', 'Test', 'Position', [5+DUP(1)+DUP(3), DUP(2:4)], 'HorizontalAlignment', 'left');

The GridBagLayout contribution by Jason in the File Exchange addresses this problem by allowing to specify insets such as 'TopInset'. I think a solution to this problem is necessary since the UIs resulting from code such as the above fragment really don't look professional.

2.
Another nice feature of GridBagLayout is that it allows for easy distribution of elements. Let's assume that I have a panel with a VBox that contains 3 HBoxes with some uicontrols. I would like to specify the height of the individual entry in VBox to the default height of uicontrols, which is possible with 'Sizes'. However I would like these three rows be equally distributed throughout the height of the panel, which means that 'Spacing' in VBox should be calculated automatically, which is not the case.

Any ideas how to address these two cases?

06 Aug 2010 Dani

Thanks for adding the possibility to set the defaults!

I have another request. In order to figure out how large a figure should be it is necessary to know all the sizes of the objects that one puts into them. I have a VBox with several panels, which in turn again contain VBoxes that contain HBoxes. I can specify all the sizes and gaps, with the exception of how much the title of the panels takes. It looks like it takes approx. 15 pixels, however, it would be useful if you would specify this value for the various types of panels. Thanks.

05 Aug 2010 Tanyer Alan  
16 Jul 2010 Joseph Burgel

Thanks for the post. The examples won't run. I'm using ML 7.5 2007b. 2007b doesn't support 'packages'. So, I guess this toolbox won't work for me right? Bummer, it would have been a big help. Thanks.

09 Jul 2010 Ben Tordoff

Hi Jaoa,

It should have worked with R2008b although it isn’t designed to do so and hasn’t been thoroughly tested on anything before R2010a. Whilst the examples in the documentation use the new ‘~’ syntax, the toolbox code itself does not use any R2010a specific language features. I have removed the “feature” command that crept in and will upload a new version that should work for you. We have targeted the current shipping release as that is the version used by the majority of the customers with whom we are working on GUI building projects.

The doc comment is a bit misleading – the “doc” wrapper I have supplied works around a deliberate change in the doc command introduced in R2007a and present in all subsequent releases. It is necessary in order for the doc command to find user toolbox documentation. I have improved the comments in this function accordingly.

Watch this space for an update soon!

06 Jul 2010 Joao Henriques

This seems pretty neat, but I can't get it to work with R2008b. Isn't backward compatibility a concern? At least to some degree -- 2008b is not that old (we're in 2010), and I like it as a stable platform; I can't change every year :)

More specifically, some examples use the brand-new "~ for unused parameters" functionality (which is fixed easily), and calls to the "feature" function result in the error "An unknown feature was specified".
>> which feature
built-in (undocumented)

All in all, this seems like a good system and I'd love to try it, but it only seems directed at the newest ML release (which seems odd, considering it includes a "doc" replacement that intends to fix a R2007 problem).

01 Jul 2010 DNF

A problem with the HButtonBox for aligning text is that the text control cannot be vertically aligned inside its own bounding box. So HButtonBox resizes the text uicontrol and then the text appears above its intended position.

Perhaps using a swing text control fixes this, but maybe it would be possible make something specifically for lining up text?

01 Jul 2010 Ben Tordoff

Hi Felix,

another thought - if all you want is to centre something vertically or horizontally, the HButtonBox and VButtonBox might help you. Don't let the names mislead you, these can layout any widgets! They allow control over the content size and justification in a way that is messy to achieve using standard box layouts.

01 Jul 2010 Felix

Hi Ben,

thanks for the hint. I had a feeling it might be a scoping issue and tried assigning the handle to a WS variable, which seems to have been only half of the solution. I was able to use uipanels in place of the Empties successfully, though.

01 Jul 2010 Ben Tordoff

Hi Felix,

this is a problem of scoping that is fixed in v1.3 (awaiting approval right now). Whilst you wait for this update, the solution is to keep hold of the empty element so that it doesn't go out of scope and get deleted. "e = uiextras.Empty();setappdata(e,'MyObject',e)" would do the trick (this is what the fix does behind the scenes and it ensures that the object only goes out of scope when the graphics themselves die).

Sorry about that - hopefully the fixed version will appear here very soon.

01 Jul 2010 Magnus

This is exactly what I was looking for! Finally it is possible to make a nice-looking GUI. It took a while to find the toolbox, googling for "java layout matlab" gave some hits to people with the same intentions of producing GUIs with java-type layout. A big thanks to Ben and the other authors of this toolbox.

30 Jun 2010 Felix

A great submission, very well structured. Great documentation, too.

I seem to have issues with using uiextra.Empy, though. when I put Empties in a VBox or HBox among other child elements, the empties vanish from the layout, either when I add more children or even when I do get(layout,'Children'). It's not that they are not displayed, they are actually gone and the layout changes.

The full problem is that I try to center a text uicontrol vertically, by putting it in a VBox Layout with an Empty above and one beneath it.

29 Jun 2010 David Sampson

A reasonable request, but not possible at this time, since these are not builtin Handle Graphics classes. We'll have to think about whether there is another reasonable way to provide the ability to specialize such default property values without bloating the API. Thanks for the feedback.

29 Jun 2010 Dani

This contribution is fantastic! Very easy to use, fast, and reliable.

One question though. When I use standard user interface objects I can set their defaults through, for example, set(0, 'DefaultUipanelBackgroundColor'). This functionality is very useful as it allows for a centralized control of the GUI looks. Is there a possibility to have the same for the GUI Layout Toolbox, so that, for example, the standard TitleColor in the BoxPanel can be set to something else than bright blue?

28 Jun 2010 Ben Tordoff

Hi Jesse, I understand your pain - I have been through a similar exercise myself in the past.

For better or worse, the MATLAB object system is case-sensitive. Whilst there are (undocumented) ways to make property access case-insensitive, the object names and methods will always be case sensitive. Using the incorrect case for property access can be between 5 and 10 times slower and it is very likely that in the distant future all MATLAB objects, graphics or otherwise, will become case sensitive for that reason.

In my opinion (humble or otherwise) it's better to have a one-off hit on my time converting the code than a permanent performance hit for users of my application. I guess that depends on the scale of the changes and the number of users though.

Thanks for the feedback, and let me know if you find other problems or have other suggestions.

24 Jun 2010 Jesse Hopkins

Excellent submission, very feature rich layout editor. I do have one nit-pick however, which is that when using set/get function, the property names are case-sensitive. This is different then the behavior for figure handles and other matlab graphics handles, and has caused some difficulty trying to port some existing GUIs to using this layout manager.

21 Jun 2010 Ben Tordoff

Hi Jveer,

GUIs built using this tool can definitely be deployed as executable applications, but you need to remember to include any icons or other resources that are used (basically the stuff in the "+uiextras/Resources" folder). I'll add some documentation explaining this in more detail.

This toolbox is all about laying out widgets in an interface rather than providing any widgets, so trees don't really fit in. I've used the built-in UITREE with some success in the past, even though it claims to be experimental. You can also pull any Java or ActiveX tree widgets into a MATLAB GUI fairly easily. I do have a toolbox of enhanced widgets that I'll publish here soon, but unfortunately there are no trees in it.

20 Jun 2010 Jveer

looks amazing!

any chance of seeing support for tree objects any time soon?

also, can guis created using this tool be compiled into standalone applications using the matlab compiler?

11 Jun 2010 Matthew Whitaker

Completely brilliant and easy to use. Extremely well documented. Hopefully this will become part of core MATLAB in the future.

The only trivial thing I have so far is that the layoutRoot function seems to be missing from the dowload

07 Jun 2010 Sam Mirsky  
Updates
02 Jun 2010

Fixed some typos in the documentation

03 Jun 2010

Further documentation typo fixes (must use spellchecker more...)

07 Jun 2010

Add link to documentation from description

09 Jun 2010

Added missing "root" and "version" functions

18 Jun 2010

* Ensure layout objects are deleted when the graphics are deleted
* Add "ancestor" method
* Fix bug in GridFlex divider positioning
* Remove ">>" from examples in documentation
* Improve formatting of examples in documentation

28 Jun 2010

* Fix bug with Panel titles
* Fix bug with EmptyWidget going out of scope
* Prevent legends being hijacked by the layout managers!
* Add option for showing markings on the movable dividers
* Add documentation on building executables

15 Jul 2010

* Add ability to set defaults for various properties
* Remove R2010a specific code to allow use on older releases

23 Jul 2010

* Add DeleteFcn property
* Improve Docking and Minimizing examples
* Fix flexible layouts when figure units are not pixels (e.g. in GUIDE apps)
* Documentation on using layouts in a GUIDE-built GUI
* Fix parenting bug with ButtonBoxes

28 Jul 2010

Fix link in description (hopefully - it's a bit of a moving target)

24 Sep 2010

* Make panel "SelectedChild" property observable for use with event.proplistener
* Fix bug with dividers disappearing when GridFlex's are nested
* Fix clipping bug with Tab label text drawing outside parent container

22 Oct 2010

* Improve enable behavior when used with custom widgets
* Add an explanation of cell arrays used to pass extra function arguments
* Fix bug in unit-setting of children added to layouts (improves axes handling)

02 Nov 2010

* Add PreviousChild event-data to uiextras.TabPanel Callback
* Add guards to prevent errors when focus is lost whilst dragging a flexible divider
* Fix bug when trying to print figures containing flexible layouts

08 Mar 2011

* Add MinimumSize properties to Boxes and Grids
* Minor improvements to mouse-over and redraw speed
* Fix bug with ordering of controls that sometimes prevented grid dividers being dragged

22 Jun 2011

Update description to include a link to Matthew Whitaker's ButtonGroup objects.

14 Jul 2011

* Add TabEnable property for controlling the enabled state of individual tabs
* Revert to normalized units for all layouts
* Fix bug with mouse-over events

23 May 2012

Remove documentation link from description since the new File Exchange page does not allow this.

19 Dec 2012

* Fix (I hope) bug where axes disappear from tabs
* Fix bug where axes position is corrupted if tabs become too small to draw

22 Feb 2013

* Fix a bug when deleting axes using R2013a
* Fix a bug in how legends are handled

22 Feb 2013

* Fix error when axes deleted using R2013a
* Fix handling of legends (which I broke in the last update)

26 Apr 2013

* Improve colorbar handling (ignoring)
* Fix bug in reparenting children
* Fix background color of BoxPanel icons

13 Sep 2013

Fix support for appdata.

04 Mar 2014

* Allow vresion to be checked using ver('layout')
* Misc doc fixes (including spelling of hierarchy!)
* Fix some edge-case bahaviours for TabPanel

Contact us