Main Content

Develop Custom UI Components Programmatically

To create custom UIs and visualizations, you can combine multiple graphics and UI objects, change their properties, or call additional functions. In R2020a and earlier releases, a common way to store your customization code and share it with others is to write a script or a function.

Starting in R2020b, instead of a script or function, you can create a class implementation for your UI components by defining a subclass of theComponentContainerbase class. Creating a class has these benefits:

  • Easy customization — When users want to customize an aspect of your UI component, they can set a property rather than having to modify and rerun your code. Users can modify properties at the command line or inspect them in the Property Inspector.

  • Encapsulation — Organizing your code in this way allows you to hide implementation details from your users. You implement methods that perform calculations and manage the underlying graphics objects.

This topic gives an overview of the steps to create a custom UI component by defining a class programmatically. Alternatively, starting in R2022a, you can create a custom UI component interactively using App Designer. For more information about the interactive approach, seeCreate a Simple Custom UI Component in App Designer.

Structure of a UI Component Class

一个UI component class has several required parts, and several more that are optional.

In the first line of a UI component class, specify thematlab.ui.componentcontainer.ComponentContainerclass as the superclass. For example, the first line of a class calledColorSelectorlooks like this:

classdefColorSelector < matlab.ui.componentcontainer.ComponentContainer

In addition to specifying the superclass, include the following components in your class definition. Some components are required, while other components are either recommended or optional.

Component Description

Public property block
(recommended)

This block defines all the properties that users have access to. Together, these properties make up the user interface of your UI component.

Private property block
(recommended)

This block defines the underlying graphics objects and other implementation details that users cannot access.

In this block, set these attribute values:

  • 一个ccess = private

  • Transient

  • NonCopyable

Events block
(optional)

This block defines the events that this UI component will trigger.

In this block, set these attribute values:

  • HasCallbackProperty

  • NotifyAccess = protected

当你设置HasCallbackPropertyattribute, MATLAB®creates a public property for each event in the block. The public property stores the user-provided callback to execute when the event fires.

setupmethod
(required)

This method sets the initial state of the UI component. It executes once when MATLAB constructs the object.

Define this method in a protectedmethodsblock.

updatemethod
(required)

This method updates the underlying objects in your UI component. It executes under the following conditions:

  • During the nextdrawnowexecution after the user changes one or more property values

  • When an aspect of the user's graphics environment changes (such as the size)

Define this method in the same protected block as thesetupmethod.

Constructor Method

You do not have to write a constructor method for your class, because it inherits one from theComponentContainerbase class. The inherited constructor accepts optional input arguments: a parent container and any number of name-value pair arguments for setting properties on the UI component. For example, if you define a class calledColorSelectorthat has the public propertiesValueandValueChangedFcn, you can create an instance of your class using this code:

f = uifigure; c = ColorSelector(f,'Value',[1 1 0],'ValueChangedFcn',@(o,e)disp('Changed'))

If you want to provide a constructor that has a different syntax or different behavior, you can define a custom constructor method. For an example of a custom constructor, seeWrite Constructors for Chart Classes.

Public and Private Property Blocks

Divide your class properties between at least two blocks:

  • 一个public block for storing the components of the user-facing interface

  • 一个private block for storing the implementation details that you want to hide

The properties that go in the public block store the input values provided by the user. For example, a UI component that allows a user to pick a color value might store the color value in a public property. Since the property name-value pair arguments are optional inputs to the implicit constructor method, the recommended approach is to initialize the public properties to default values.

The properties that go in the private block store the underlying graphics objects that make up your UI component, in addition to any calculated values that you want to store. Eventually, your class will use the data in the public properties to configure the underlying objects. Set theTransientandNonCopyableattributes for the private block to avoid storing redundant information if the user copies or saves an instance of the UI component.

For example, here are the property blocks for a UI component that allows a user to pick a color value. The public property block stores the value that the user can control: the color value. The private property block stores the grid layout manager, button, and edit field objects.

propertiesValue{validateattributes(Value,...{'double'},{'<=',1,'>=',0,'size',[1 3]})}= [1 0 0];endproperties(Access = private,Transient,NonCopyable) Gridmatlab.ui.container.GridLayoutButtonmatlab.ui.control.ButtonEditFieldmatlab.ui.control.EditFieldend

Event Block

You optionally can add a third block for events that the UI component fires.

Create a public property for each event in the block by specifying theHasCallbackPropertyattribute. The public property stores the user-provided callback to execute when the event fires. The name of the public property is the name of the event appended with the lettersFcn. For example, a UI component that allows a user to pick a color value might define the eventValueChanged, which generates the corresponding public propertyValueChangedFcn. Use thenotifymethod to fire the event and execute the callback in the property.

For example, here is the event block for a UI component that allows a user to pick a color value.

events(HasCallbackProperty, NotifyAccess = protected) ValueChangedend
When the user picks a color value, call thenotifymethod to fire theValueChangedevent and execute the callback in theValueChangedFcnproperty.
functiongetColorFromUser(comp) c = uisetcolor(comp.Value);if(isscalar(c) && (c == 0))return;end% Update the Value propertyoldValue = comp.Value; comp.Value = c;% Execute user callbacks and listenersnotify(comp,'ValueChanged');end
When a user creates an instance of the UI component, they can specify a callback to execute when the color value changes using the generated public property.
f = uifigure; c = ColorSelector(f,'ValueChangedFcn',@(o,e)disp('Changed'))
For more information about specifying callbacks to properties, seeCreate Callbacks for Apps Created Programmatically.

Setup Method

Define asetupmethod for your class. Asetupmethod executes once when MATLAB constructs the UI component object. Any property values passed as name-value arguments to the constructor method are assigned after this method executes.

Use thesetupmethod to:

  • Create graphics and UI objects that make up the component.

  • Store the objects as private properties on the component object.

  • Lay out and configure the objects.

  • Wire up the objects to do something useful within the component.

Define thesetupmethod in a protected block.

Most UI object creation functions have an optional input argument for specifying the parent. When you call these functions from within a class method, you must specify the target parent. Specify the target parent as the UI component object being set up by using the class instance argument passed to the method.

For example, consider a UI component that has these properties:

  • One public property calledValue

  • Three private properties calledGrid,Button, andEditField

Thesetupmethod calls theuigridlayout,uieditfield, anduibuttonfunctions to create the underlying graphics object for each private property, specifying the instance of the UI component (comp) as the target parent.

functionsetup(comp)% Create grid layout to manage building blockscomp.Grid = uigridlayout(comp,[1 2],'ColumnWidth',{'1x',22},...'RowHeight',{'fit'},'ColumnSpacing',2,'Padding',2);% Create edit field for entering color valuecomp.EditField = uieditfield(comp.Grid,“可编辑”,false,...'HorizontalAlignment','center');% Create button to confirm color changecomp.Button = uibutton(comp.Grid,'Text',char(9998),...'ButtonPushedFcn',@(o,e) comp.getColorFromUser());end

Update Method

Define anupdatemethod for your class. This method executes when your UI component object needs to change its appearance in response to a change in values.

Use theupdatemethod to reconfigure the underlying graphics objects in your UI component based on the new values of the properties. Typically, this method does not determine which of the properties changed. It reconfigures all aspects of the underlying graphics objects that depend on the properties.

For example, consider a UI component that has these properties:

  • One public property calledValue

  • Three private properties calledGrid,Button, andEditField

Theupdatemethod updates theBackgroundColorof theEditFieldandButtonobjects with the color stored inValue. Theupdatemethod also updates theEditFieldobject with a numeric representation of the color. This way, howeverValueis changed, the change becomes equally visible everywhere.

functionupdate(comp)% Update edit field and button colorsset([comp.EditField comp.Button],'BackgroundColor',comp.Value,...'FontColor'comp.getContrastingColor (comp.Value));% Update edit field display textcomp.EditField.Value = num2str(comp.Value,'%0.2g ');end

There might be a delay between changing property values and seeing the results of those changes. Theupdatemethod runs for the first time after thesetupmethod runs and then it runs every timedrawnowexecutes. Thedrawnowfunction automatically executes periodically, based on the state of the graphics environment in the user's MATLAB session. This periodic execution can lead to the potential delay.

Example: Color Selector UI Component

This example shows how to create a UI component for selecting a color, using the code discussed in other sections of this page. Create a class definition file namedColorSelectorComponent.min a folder that is on the MATLAB path. Define the class by following these steps.

Step Implementation

Derive from theComponentContainerbase class.

classdefColorSelector < matlab.ui.componentcontainer.ComponentContainer

Define public properties.

propertiesValue{validateattributes(Value,...{'double'},{'<=',1,'>=',0,'size',[1 3]})}= [1 0 0];end

Define public events.

events(HasCallbackProperty, NotifyAccess = protected) ValueChanged% ValueChangedFcn will be the generated callback propertyend

Define private properties.

properties(Access = private, Transient, NonCopyable) Gridmatlab.ui.container.GridLayoutButtonmatlab.ui.control.ButtonEditFieldmatlab.ui.control.EditFieldend

Implement thesetupmethod. In this case, call theuigridlayout,uieditfield, anduibuttonfunctions to createGridLayout,EditField, andButtonobjects. Store those objects in the corresponding private properties.

Specify thegetColorFromUsermethod as theButtonPushedFcncallback that is called when the button is pressed.

methods(Access = protected)functionsetup(comp)% Grid layout to manage building blockscomp.Grid = uigridlayout(comp,[1,2],'ColumnWidth',{'1x',22},...'RowHeight',{'fit'},'ColumnSpacing',2,'Padding',2);% Edit field for value display and button to launch uisetcolorcomp.EditField = uieditfield(comp.Grid,“可编辑”,false,...'HorizontalAlignment','center'); comp.Button = uibutton(comp.Grid,'Text',char(9998),...'ButtonPushedFcn',@(o,e) comp.getColorFromUser());end

Implement theupdatemethod. In this case, update the background color of the underlying objects and the text in the edit field to show the color value.

functionupdate(comp)% Update edit field and button colorsset([comp.EditField comp.Button],'BackgroundColor',comp.Value,...'FontColor'comp.getContrastingColor (comp.Value));% Update the display textcomp.EditField.Value = num2str(comp.Value,'%0.2g ');endend

Wire the callbacks and other pieces together using private methods.

When thegetColorFromUsermethod is triggered by a button press, call theuisetcolorfunction to open the color picker and then call thenotifyfunction to execute the user callback and listener functions.

When thegetContrastingColormethod is called by theupdatemethod, calculate whether black or white text is more readable on the new background color.

methods(Access = private)functiongetColorFromUser(comp) c = uisetcolor(comp.Value);if(isscalar(c) && (c == 0))return;end% Update the Value propertycomp.Value = c;% Execute user callbacks and listenersnotify(comp,'ValueChanged');endfunctioncontrastColor = getContrastingColor(~,color)%计算相反的颜色c = color * 255; contrastColor = [1 1 1];if(c(1)*.299 + c(2)*.587 + c(3)*.114) > 186 contrastColor = [0 0 0];endendendend

Next, create an instance of the UI component by calling the implicit constructor method with a few of the public properties. Specify a callback to display the wordsColor changedwhen the color value changes.

h = ColorSelector('Value', [1 1 0]); h.ValueChangedFcn = @(o,e) disp('Color changed');

Instance of the color selector UI component displaying the color yellow.

Click the button and select a color using the color picker. The component changes appearance and MATLAB displays the wordsColor changedin the Command Window.

Instance of the color selector UI component displaying the color blue.

See Also

Classes

Functions

Related Topics