プログラムによるカスタム UI コンポーネントの開発
カスタム UI と可視化を作成するために、複数のグラフィックス オブジェクトと UI オブジェクトを組み合わせたり、それらのプロパティを変更したり、追加の関数を呼び出したりすることができます。R2020a 以前のリリースでは、カスタマイズ コードを保存し他者と共有する一般的な方法は、スクリプトまたは関数の作成です。
R2020b 以降は、スクリプトや関数の代わりに、ComponentContainer
基底クラスのサブクラスを定義することで UI コンポーネントのクラス実装を作成することができます。クラスの作成には以下の利点があります。
カスタマイズが簡単 — ユーザーが UI コンポーネントの特性をカスタマイズする場合、コードの変更と再実行を行うことなしに、プロパティを設定することができます。ユーザーはコマンド ラインでプロパティを変更したり、プロパティ インスペクターでプロパティを確認できます。
カプセル化 — コードをこの方法で整理することで、ユーザーに対し実装の詳細を非表示にすることができます。計算を実行し、基となるグラフィックス オブジェクトを管理するメソッドを実装します。
このトピックは、プログラムでクラスを定義することでカスタム UI コンポーネントを作成する手順の概要を示したものです。R2022a 以降では、代わりに App Designer を使用して対話形式でカスタム UI コンポーネントを作成できます。対話形式による方法の詳細については、Create a Simple Custom UI Component in App Designerを参照してください。
UI コンポーネント クラスの構造
UI コンポーネント クラスには、いくつかの必須部分と、いくつかのオプション部分があります。
UI コンポーネント クラスの最初の行では、matlab.ui.componentcontainer.ComponentContainer
クラスをスーパークラスとして指定します。たとえば、ColorSelector
というクラスの最初の行は次のようになります。
classdef ColorSelector < matlab.ui.componentcontainer.ComponentContainer
スーパークラスの指定に加えて、以下のコンポーネントをユーザー クラス定義に含めます。いくつかのコンポーネントは必須で、他のコンポーネントは推奨またはオプションです。
コンポーネント | 説明 |
---|---|
パブリック プロパティ ブロック | このブロックは、ユーザーがアクセスできるすべてのプロパティを定義します。これらのプロパティが一緒になって、UI コンポーネントのユーザー インターフェイスを構成します。 |
プライベート プロパティ ブロック | このブロックは、ユーザーがアクセスできない、基となるグラフィックス オブジェクトや他の実装詳細を定義します。 このブロックでは、以下の属性値が設定されます。
|
イベント ブロック | このブロックは、この UI コンポーネントがトリガーするイベントを定義します。 このブロックでは、以下の属性値が設定されます。
|
| このメソッドは、UI コンポーネントの初期状態を設定します。MATLAB がオブジェクトを作成すると 1 回実行されます。 このメソッドは、保護された |
| このメソッドは、UI コンポーネント内の基となるオブジェクトを更新します。以下の条件で実行されます。
このメソッドは、 |
コンストラクター メソッド
コンストラクターは ComponentContainer
基底クラスから継承されるため、ユーザー クラスにコンストラクター メソッドを作成する必要はありません。継承されたコンストラクターは、オプションの入力引数 (親コンテナーと、UI コンポーネントにプロパティを設定するための任意数の名前と値のペアの引数) を受け入れます。たとえば、パブリック プロパティ Value
および ValueChangedFcn
をもつ ColorSelector
というクラスを定義する場合、次のコードを使用してユーザー クラスのインスタンスを作成できます。
f = uifigure; c = ColorSelector(f,'Value',[1 1 0],'ValueChangedFcn',@(o,e)disp('Changed'))
別の構文または別の動作をもつコンストラクターを指定する場合は、カスタム コンストラクター メソッドを定義できます。カスタム コンストラクターの例は、チャート クラスのコンストラクターの作成を参照してください。
パブリックおよびプライベートのプロパティ ブロック
ユーザー クラスのプロパティを、少なくとも 2 つのブロック間で分割します。
ユーザー向けインターフェイスのコンポーネントを保存するためのパブリック ブロック
非表示にする実装の詳細を保存するためのプライベート ブロック
パブリック ブロックに収められるプロパティは、ユーザーの指定する入力値を保存します。たとえば、ユーザーがカラー値を選択できる UI コンポーネントでは、パブリック プロパティにカラー値が保存されている可能性があります。プロパティの名前と値のペアの引数は暗黙的なコンストラクター メソッドのオプション入力であるため、パブリック プロパティを既定値に初期化する方法が推奨されます。
プライベート ブロックに収められるプロパティには、保存するすべての計算値に加えて、UI コンポーネントを構成する基となるグラフィックス オブジェクトが保存されます。最終的に、ユーザー クラスはパブリック プロパティ内のデータを使用して、基となるオブジェクトを構成します。プライベート ブロックに Transient
属性と NonCopyable
属性を設定することで、ユーザーが UI コンポーネントのインスタンスのコピーや保存をする場合に、冗長な情報が保存されることを回避します。
たとえば、次に示すのは、ユーザーがカラー値を選択できる UI コンポーネントのプロパティ ブロックです。パブリック プロパティ ブロックには、ユーザーが制御できる値としてカラー値が保存されています。プライベート プロパティ ブロックには、グリッド レイアウト マネージャー、ボタン、編集フィールドの各オブジェクトが保存されています。
properties Value {validateattributes(Value, ... {'double'},{'<=',1,'>=',0,'size',[1 3]})} = [1 0 0]; end properties (Access = private,Transient,NonCopyable) Grid matlab.ui.container.GridLayout Button matlab.ui.control.Button EditField matlab.ui.control.EditField end
イベント ブロック
オプションとして、UI コンポーネントが発生させるイベント用に 3 番目のブロックを追加することができます。
HasCallbackProperty
属性を指定することにより、ブロック内に各イベントのパブリック プロパティを作成します。そのパブリック プロパティには、イベントが発生すると実行される、ユーザー指定のコールバックが保存されます。パブリック プロパティの名前は、イベント名に文字 Fcn
を追加したものとなります。たとえば、ユーザーがカラー値を選択できる UI コンポーネントがイベント ValueChanged
を定義するならば、これによって、対応するパブリック プロパティ ValueChangedFcn
が生成されます。notify
メソッドを使用してイベントを発生させ、プロパティ内のコールバックを実行します。
たとえば、ユーザーがカラー値を選択できる UI コンポーネントに対するイベント ブロックは、次のようになります。
events (HasCallbackProperty, NotifyAccess = protected) ValueChanged end
notify
メソッドが呼び出されて ValueChanged
イベントが発生し、ValueChangedFcn
プロパティ内のコールバックが実行されます。function getColorFromUser(comp) c = uisetcolor(comp.Value); if (isscalar(c) && (c == 0)) return; end % Update the Value property oldValue = comp.Value; comp.Value = c; % Execute user callbacks and listeners notify(comp,'ValueChanged'); end
f = uifigure; c = ColorSelector(f,'ValueChangedFcn',@(o,e)disp('Changed'))
setup メソッド
クラスに setup
メソッドを定義します。setup
メソッドは、MATLAB が UI コンポーネント オブジェクトを作成するときに一度実行されます。名前と値の引数としてコンストラクター メソッドに渡されたプロパティ値は、このメソッドの実行後に割り当てられます。
次の場合に setup
メソッドを使用します。
コンポーネントを構成するグラフィックス オブジェクトと UI オブジェクトを作成する。
オブジェクトをプライベート プロパティとしてコンポーネント オブジェクト上に保存する。
オブジェクトの配置と構成を行う。
コンポーネント内で有用な動作をするよう、オブジェクトを互いにつなげる。
setup
メソッドは、保護されたブロック内で定義します。
ほとんどの UI オブジェクト作成関数には、親を指定するためのオプションの入力引数があります。クラス メソッド内からこれらの関数を呼び出す際には、ターゲットの親を指定しなければなりません。設定する UI コンポーネント オブジェクトとして、メソッドに渡されるクラス インスタンスの引数を使用してターゲットの親を指定します。
たとえば、次のプロパティをもつ UI コンポーネントについて考えます。
Value
という 1 つのパブリック プロパティGrid
、Button
、およびEditField
という 3 つのプライベート プロパティ
setup
メソッドでは、UI コンポーネントのインスタンス (comp
) をターゲットの親として指定し、関数 uigridlayout
、uieditfield
、uibutton
を呼び出して各プライベート プロパティの基となるグラフィックス オブジェクトを作成します。
function setup(comp) % Create grid layout to manage building blocks comp.Grid = uigridlayout(comp,[1 2],'ColumnWidth',{'1x',22},... 'RowHeight',{'fit'},'ColumnSpacing',2,'Padding',2); % Create edit field for entering color value comp.EditField = uieditfield(comp.Grid,'Editable',false,... 'HorizontalAlignment','center'); % Create button to confirm color change comp.Button = uibutton(comp.Grid,'Text',char(9998), ... 'ButtonPushedFcn',@(o,e) comp.getColorFromUser()); end
update メソッド
ユーザー クラスに update
メソッドを定義します。このメソッドは、UI コンポーネント オブジェクトが値の変化に応じてその外観を変える必要がある場合に実行されます。
update
メソッドを使用して、プロパティの新しい値を基に、UI コンポーネント内の基となるグラフィックス オブジェクトを再構成します。通常、このメソッドではどのプロパティが変更されたかを判定しません。プロパティに依存する、基となるグラフィックス オブジェクトのすべての特性が再構成されます。
たとえば、次のプロパティをもつ UI コンポーネントについて考えます。
Value
という 1 つのパブリック プロパティGrid
、Button
、およびEditField
という 3 つのプライベート プロパティ
update
メソッドは、Value
に保存されている色を使って EditField
オブジェクトと Button
オブジェクトの BackgroundColor
を更新します。update
メソッドはまた、色の数値表現によっても EditField
オブジェクトを更新します。この方法では、Value
がどのように変更されても、その変更はあらゆる場所で等しく可視化されます。
function update(comp) % Update edit field and button colors set([comp.EditField comp.Button],'BackgroundColor',comp.Value, ... 'FontColor',comp.getContrastingColor(comp.Value)); % Update edit field display text comp.EditField.Value = num2str(comp.Value,'%0.2g '); end
プロパティ値を変更してから、それら変更の結果が表示されるまでには遅延が生ずる場合があります。update
メソッドは、setup
メソッドの実行後に初めて実行され、その後は、drawnow
が実行されるたびに実行されます。関数 drawnow
は、ユーザーの MATLAB セッションにおけるグラフィックス環境の状態に基づき、定期的に自動実行されます。この定期的な実行は、遅延につながる可能性があります。
例: カラー セレクターの UI コンポーネント
この例では、このページの他の節で説明されているコードを使用して、色を選択するための UI コンポーネントを作成する方法を説明します。ColorSelectorComponent.m
という名前のクラス定義ファイルを、MATLAB パス上にあるフォルダー内に作成します。以下の手順に従ってクラスを定義します。
手順 | 実装 |
---|---|
|
classdef ColorSelector < matlab.ui.componentcontainer.ComponentContainer |
パブリック プロパティを定義します。 |
properties Value {validateattributes(Value, ... {'double'},{'<=',1,'>=',0,'size',[1 3]})} = [1 0 0]; end |
パブリック イベントを定義します。 |
events (HasCallbackProperty, NotifyAccess = protected) ValueChanged % ValueChangedFcn will be the generated callback property end |
プライベート プロパティを定義します。 |
properties (Access = private, Transient, NonCopyable) Grid matlab.ui.container.GridLayout Button matlab.ui.control.Button EditField matlab.ui.control.EditField end |
|
methods (Access = protected) function setup(comp) % Grid layout to manage building blocks comp.Grid = uigridlayout(comp,[1,2],'ColumnWidth',{'1x',22}, ... 'RowHeight',{'fit'},'ColumnSpacing',2,'Padding',2); % Edit field for value display and button to launch uisetcolor comp.EditField = uieditfield(comp.Grid,'Editable',false, ... 'HorizontalAlignment','center'); comp.Button = uibutton(comp.Grid,'Text',char(9998), ... 'ButtonPushedFcn',@(o,e) comp.getColorFromUser()); end |
|
function update(comp) % Update edit field and button colors set([comp.EditField comp.Button],'BackgroundColor',comp.Value, ... 'FontColor',comp.getContrastingColor(comp.Value)); % Update the display text comp.EditField.Value = num2str(comp.Value,'%0.2g '); end end |
プライベート メソッドを使用して、コールバックと他の要素をつなげます。 ボタン押下で
|
methods (Access = private) function getColorFromUser(comp) c = uisetcolor(comp.Value); if (isscalar(c) && (c == 0)) return; end % Update the Value property comp.Value = c; % Execute user callbacks and listeners notify(comp,'ValueChanged'); end function contrastColor = getContrastingColor(~,color) % Calculate opposite color c = color * 255; contrastColor = [1 1 1]; if (c(1)*.299 + c(2)*.587 + c(3)*.114) > 186 contrastColor = [0 0 0]; end end end end |
次に、いくつかのパブリック プロパティを指定して暗黙的なコンストラクター メソッドを呼び出すことで、UI コンポーネントのインスタンスを作成します。コールバックを、カラー値が変更されると Color changed
という語が表示されるように指定します。
h = ColorSelector('Value', [1 1 0]); h.ValueChangedFcn = @(o,e) disp('Color changed');
ボタンをクリックし、カラー ピッカーを使用して色を選択します。コンポーネントの外観が変わり、MATLAB は Color changed
の語をコマンド ウィンドウに表示します。