You can adjust the size and location of components, and manage front-to-back order of
grouped components by setting certain property values. This topic explains how to use
these properties to get the layout you want. It also explains how to use the
SizeChangedFcn
callback to control the UI’s resizing
behavior.
A UI layout consists of a figure and one or more components that you place inside the figure. Accurate placement and sizing of each component involves setting certain properties and understanding how the inner and outer boundaries of the figure relate to each other.
The area inside the figure, which contains the UI components, is called the
drawable area. The drawable area
excludes the figure borders, title bar, menu bar, and
tool bars. You can control the location and size of the drawable area by setting
the Position
property of the figure as a four-element row vector. The first two elements of
this vector specify the location. The last two elements specify the size. By
default, the figure’s Position
values are in pixels.
This command creates a figure and sets the Position
value. The left edge of the drawable area is 258 pixels from the left side of
the screen. Its bottom edge is 132 pixels up from the bottom of the screen. Its
size is 560 pixels wide by 420 pixels high:
f = figure('Position',[258 132 560 420]);
You can query or change the outer bounds of the figure by using the OuterPosition
property. The region enclosed by the outer bounds of the figure includes the
figure borders, title bar, menu bar, and tool bars. Like the
Position
property, the
OuterPosition
is a four element row
vector:
f.OuterPosition
ans = 250 124 576 512
Explicitly changing the Position
or
OuterPosition
causes the other property to change. For
example, this is the current Position
value of
f
:
f.Position
ans = 258 132 560 420
OuterPosition
causes the Position
to
change:f.OuterPosition = [250 250 490 340]; f.Position
ans = 258 258 474 248
Other UI components, such as UIControl
,
Table
, and Panel
objects have a
Position
property, which you can use to set their
location and size.
The default units associated with the Position
property
depend on the component you are placing. However, you can change the Units
property to
lay out your UI in the units of your choice. There are six different units of
measure to choose from: inches, centimeters, normalized, points, pixels, and
characters.
Always specify Units
before Position
for the most predictable
results.
f = figure('Units','inches','Position',[4 3 6 5]);
Your choice of units can affect the appearance and resizing behavior of the UI:
If you want the UI components to scale proportionally with the figure
when the user resizes the figure, set the Units
property of the components to 'normalized'
.
UI Components do not scale proportionally inside the figure when their
Units
property is set to
'inches'
, 'centimeters'
,
'points'
, 'pixels'
, or
'characters'
.
If you are developing a cross-platform UI, then set the
Units
property to 'points'
or 'characters'
to make the layout consistent across
all platforms.
Here is the code for a simple app containing an axes and a button. To see how it works, copy and paste this code into the editor and run it.
function myui % Add the UI components hs = addcomponents; % Make figure visible after adding components hs.fig.Visible = 'on'; function hs = addcomponents % add components, save handles in a struct hs.fig = figure('Visible','off',... 'Resize','off',... 'Tag','fig'); hs.btn = uicontrol(hs.fig,'Position',[10 340 70 30],... 'String','Plot Sine',... 'Tag','button',... 'Callback',@plotsine); hs.ax = axes('Parent',hs.fig,... 'Position',[0.20 0.13 0.71 0.75],... 'Tag','ax'); end function plotsine(hObject,event) theta = 0:pi/64:6*pi; y = sin(theta); plot(hs.ax,theta,y); end end
The main function, myui
, calls the
addcomponents
function. The
addcomponents
function returns a structure,
hs
, containing the handles to all the UI
components.
The addcomponents
function creates a figure,
an axes, and a button, each with specific
Position
values.
Notice that the Resize
property
of the figure is 'off'
. This value
disables the resizing capability of the figure.
Notice that the Visible
property
of the figure is 'off'
inside the
addcomponents
function. The
value changes to 'on'
after
addcomponents
returns to the
calling function. Doing this delays the figure display
until after MATLAB® adds all the components. Thus, the
resulting UI has a clean appearance when it starts
up.
The plotsine
function plots the sine function
inside the axes when the user clicks the button.
To create a resizable UI and manage the layout when the user resizes the window,
set the figure’s SizeChangedFcn
property to be a handle to a
callback function. Code the callback function to manage the layout when the window
size changes.
If your UI has another container, such as a panel or button group, you can manage
the layout of the container’s child components in a separate callback function that
you assign to the SizeChangedFcn
property.
The SizeChangedFcn
callback executes only under these circumstances:
The container becomes visible for the first time.
The container is visible while its drawable area changes.
The container becomes visible for the first time after its drawable area changes. This situation occurs when the drawable area changes while the container is invisible and becomes visible later.
Note
Typically, the drawable area changes at the same time the outer bounds
change. However, adding or removing menu bars or tool bars to a figure
causes the outer bounds to change while the drawable area remains constant.
Therefore, the SizeChangedFcn
callback does not execute
when you add or remove menu bars or tool bars.
This app is a resizable version of the simple app defined in Example of a Simple Layout. This code includes a figure
SizeChangedFcn
callback called resizeui
.
The resizeui
function calculates new
Position
values for the button and axes when the user
resizes the window. The button appears to be stationary when the user resizes the
window. The axes scales with the
figure.
function myui % Add the UI components hs = addcomponents; % Make figure visible after adding components hs.fig.Visible = 'on'; function hs = addcomponents % Add components, save handles in a struct hs.fig = figure('Visible','off',... 'Tag','fig',... 'SizeChangedFcn',@resizeui); hs.btn = uicontrol(hs.fig,'String',... 'Plot Sine',... 'Callback',@plotsine,... 'Tag','button'); hs.ax = axes('Parent',hs.fig,... 'Units','pixels',... 'Tag','ax'); end function plotsine(hObject,event) theta = 0:pi/64:6*pi; y = sin(theta); plot(hs.ax,theta,y); end function resizeui(hObject,event) % Get figure width and height figwidth = hs.fig.Position(3); figheight = hs.fig.Position(4); % Set button position bheight = 30; bwidth = 70; bbottomedge = figheight - bheight - 50; bleftedge = 10; hs.btn.Position = [bleftedge bbottomedge bwidth bheight]; % Set axes position axheight = .75*figheight; axbottomedge = max(0,figheight - axheight - 30); axleftedge = bleftedge + bwidth + 30; axwidth = max(0,figwidth - axleftedge - 50); hs.ax.Position = [axleftedge axbottomedge axwidth axheight]; end end
resizeui
function sets the location and size of the button
and axes whenever the user resizes the window:
The button height, width, and left edge stay the same when the window resizes.
The bottom edge of the button, bbottomedge
, allows
50 pixels of space between the top of the figure and the top of the
button.
The value of the axes height, axheight
, is 75% of
the available height in the figure.
The value of the axes bottom edge, axbottomedge
,
allows 30 pixels of space between the top of the figure and the top of
the axes. In this calculation, the max
function limits
this value to nonnegative values.
The value of the axes width, axwidth
, allows 50
pixels of space between the right side of the axes and the right edge of
the figure. In this calculation, the max
function
limits this value to nonnegative values.
Notice that all the layout code is inside the
resizeui
function. It is a good practice to put all the
layout code inside the SizeChangedFcn
callback to ensure the
most accurate results.
Also, it is important to delay the display of the entire UI window until after all
the variables that a SizeChangedFcn
callback uses are defined.
Doing so can prevent the SizeChangedFcn
callback from returning
an error. To delay the display of the window, set the Visible
property of the figure to 'off'
. After you define all the
variables that your SizeChangedFcn
callback uses, set the
Visible
property to 'on'
.
The default front-to-back order, or stacking order, of components in a UI is as follows:
Axes and other graphics objects appear behind other components. UI components and containers (panels, button groups, and tabs) appear in front of them.
UI components and containers appear in the order in which you create them. New components appear in front of existing components.
You can change the stacking order at any time, but there are some restrictions. Axes and other graphics objects can stack in any order with respect to each other. However, axes and other graphics objects cannot stack in front of UI components and containers. They always appear behind UI components and containers.
You can work around this restriction by grouping graphics objects into separate
containers. Then you can stack those containers in any order. To group a graphics
object into a container, set its Parent
property to be that
container. For example, you can group an axes into a panel by setting the
Parent
property of the axes to be the panel.
The Children
property of a Panel
,
ButtonGroup
, or Tab
object lists the child
objects inside the container according to their stacking order.