Undocumented Matlab
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT

AppDesigner's mlapp file format

August 17, 2016 12 Comments

Six years ago, I exposed the fact that *.fig files are simply MAT files in disguise. This information, in addition to the data format that I explained in that article, can help us to introspect and modify FIG files without having to actually display the figure onscreen.
Matlab has changed significantly since 2010, and one of the exciting new additions is the AppDesigner, Matlab’s new GUI layout designer/editor. Unfortunately, AppDesigner still has quite a few limitations in functionality and behavior. I expect that this will improve in upcoming releases since AppDesigner is undergoing active development. But in the meantime, it makes sense to see whether we could directly introspect and potentially manipulate AppDesigner’s output (*.mlapp files), as we could with GUIDE’s output (*.fig files).
A situation for checking this was recently raised by a reader on the Answers forum: apparently AppDesigner becomes increasingly sluggish when the figure’s code has more than a few hundred lines of code (i.e., a very simplistic GUI). In today’s post I intend to show how we can explore the resulting *.mlapp file, and possibly manipulate it in a text editor outside AppDesigner.

Matlab's new AppDesigner (a somewhat outdated screenshot)
Matlab's new AppDesigner (a somewhat outdated screenshot)

The MLAPP file format

Apparently, *.mlapp files are simply ZIP files in disguise (note: not MAT files as for *.fig files). A typical MLAPP’s zipped contents contains the following files (note that this might be a bit different on different Matlab releases):

  • [Content_Types].xml – this seems to be application-independent:
    <?xml version="1.0" encoding="UTF-8" standalone="true"?>
    <types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
       <default Extension="mat" ContentType="application/vnd.mathworks.matlab.appDesigner.appModel+mat"/>
       <default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
       <default Extension="xml" ContentType="application/vnd.mathworks.matlab.code.document+xml;plaincode=true"/>
       <override ContentType="application/vnd.openxmlformats-package.core-properties+xml" PartName="/metadata/coreProperties.xml"/>
       <override ContentType="application/vnd.mathworks.package.coreProperties+xml" PartName="/metadata/mwcoreProperties.xml"/>
       <override ContentType="application/vnd.mathworks.package.corePropertiesExtension+xml" PartName="/metadata/mwcorePropertiesExtension.xml"/>
    </types>

    <?xml version="1.0" encoding="UTF-8" standalone="true"?> <types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"> <default Extension="mat" ContentType="application/vnd.mathworks.matlab.appDesigner.appModel+mat"/> <default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/> <default Extension="xml" ContentType="application/vnd.mathworks.matlab.code.document+xml;plaincode=true"/> <override ContentType="application/vnd.openxmlformats-package.core-properties+xml" PartName="/metadata/coreProperties.xml"/> <override ContentType="application/vnd.mathworks.package.coreProperties+xml" PartName="/metadata/mwcoreProperties.xml"/> <override ContentType="application/vnd.mathworks.package.corePropertiesExtension+xml" PartName="/metadata/mwcorePropertiesExtension.xml"/> </types>

  • _rels/.rels – also application-independent:
    <?xml version="1.0" encoding="UTF-8" standalone="true"?>
    <relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
       <relationship Type="http://schemas.mathworks.com/matlab/code/2013/relationships/document" Target="matlab/document.xml" Id="rId1"/>
       <relationship Type="http://schemas.mathworks.com/package/2012/relationships/coreProperties" Target="metadata/mwcoreProperties.xml" Id="rId2"/>
       <relationship Type="http://schemas.mathworks.com/package/2014/relationships/corePropertiesExtension" Target="metadata/mwcorePropertiesExtension.xml" Id="rId3"/>
       <relationship Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="metadata/coreProperties.xml" Id="rId4"/>
       <relationship Type="http://schemas.mathworks.com/appDesigner/app/2014/relationships/appModel" Target="appdesigner/appModel.mat" Id="rId5"/>
    </relationships>

    <?xml version="1.0" encoding="UTF-8" standalone="true"?> <relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"> <relationship Type="http://schemas.mathworks.com/matlab/code/2013/relationships/document" Target="matlab/document.xml" Id="rId1"/> <relationship Type="http://schemas.mathworks.com/package/2012/relationships/coreProperties" Target="metadata/mwcoreProperties.xml" Id="rId2"/> <relationship Type="http://schemas.mathworks.com/package/2014/relationships/corePropertiesExtension" Target="metadata/mwcorePropertiesExtension.xml" Id="rId3"/> <relationship Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="metadata/coreProperties.xml" Id="rId4"/> <relationship Type="http://schemas.mathworks.com/appDesigner/app/2014/relationships/appModel" Target="appdesigner/appModel.mat" Id="rId5"/> </relationships>

  • metadata/coreProperties.xml – contains the timestamp of figure creation and last update:
    <?xml version="1.0" encoding="UTF-8" standalone="true"?>
    <cp:coreProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties">
       <dcterms:created xsi:type="dcterms:W3CDTF">2016-08-01T18:20:26Z</dcterms:created>
       <dcterms:modified xsi:type="dcterms:W3CDTF">2016-08-01T18:20:27Z</dcterms:modified>
    </cp:coreProperties>

    <?xml version="1.0" encoding="UTF-8" standalone="true"?> <cp:coreProperties xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"> <dcterms:created xsi:type="dcterms:W3CDTF">2016-08-01T18:20:26Z</dcterms:created> <dcterms:modified xsi:type="dcterms:W3CDTF">2016-08-01T18:20:27Z</dcterms:modified> </cp:coreProperties>

  • metadata/mwcoreProperties.xml – contains information on the generating Matlab release:
    <?xml version="1.0" encoding="UTF-8" standalone="true"?>
    <mwcoreProperties xmlns="http://schemas.mathworks.com/package/2012/coreProperties">
       <contentType>application/vnd.mathworks.matlab.app</contentType>
       <contentTypeFriendlyName>MATLAB App</contentTypeFriendlyName>
       <matlabRelease>R2016a</matlabRelease>
    </mwcoreProperties>

    <?xml version="1.0" encoding="UTF-8" standalone="true"?> <mwcoreProperties xmlns="http://schemas.mathworks.com/package/2012/coreProperties"> <contentType>application/vnd.mathworks.matlab.app</contentType> <contentTypeFriendlyName>MATLAB App</contentTypeFriendlyName> <matlabRelease>R2016a</matlabRelease> </mwcoreProperties>

  • metadata/mwcorePropertiesExtension.xml – more information about the generating Matlab release. Note that the version number is not exactly the same as the main Matlab version number: here we have 9.0.0.328027 whereas the main Matlab version number is 9.0.0.341360. I do not know whether this is checked anywhere.
    <?xml version="1.0" encoding="UTF-8" standalone="true"?>
    <mwcoreProperties xmlns="http://schemas.mathworks.com/package/2014/corePropertiesExtension">
       <matlabVersion>9.0.0.328027</matlabVersion>
    </mwcoreProperties>

    <?xml version="1.0" encoding="UTF-8" standalone="true"?> <mwcoreProperties xmlns="http://schemas.mathworks.com/package/2014/corePropertiesExtension"> <matlabVersion>9.0.0.328027</matlabVersion> </mwcoreProperties>

  • appdesigner/appModel.mat – This is a simple MAT file that holds a single Matlab object called “appData” (of type appdesigner.internal.serialization.app.AppData) the information about the uifigure, similar in concept to the *.fig files generated by the old GUIDE:
    >> d = load('C:\Yair\App3\appdesigner\appModel.mat')
    Warning: Functionality not supported with figures created with the uifigure function. For more information,
    see Graphics Support in App Designer.
    (Type "warning off MATLAB:ui:uifigure:UnsupportedAppDesignerFunctionality" to suppress this warning.)
    d =
        appData: [1x1 appdesigner.internal.serialization.app.AppData]
    >> d.appData
    ans =
      AppData with properties:
          UIFigure: [1x1 Figure]
          CodeData: [1x1 appdesigner.internal.codegeneration.model.CodeData]
          Metadata: [1x1 appdesigner.internal.serialization.app.AppMetadata]
        ToolboxVer: '2016a'
    >> d.appData.CodeData
    ans =
      CodeData with properties:
        GeneratedClassName: 'App3'
                 Callbacks: [0x0 appdesigner.internal.codegeneration.model.AppCallback]
                StartupFcn: [1x1 appdesigner.internal.codegeneration.model.AppCallback]
           EditableSection: [1x1 appdesigner.internal.codegeneration.model.CodeSection]
                ToolboxVer: '2016a'
    >> d.appData.Metadata
    ans =
      AppMetadata with properties:
        GroupHierarchy: {}
            ToolboxVer: '2016a'

    >> d = load('C:\Yair\App3\appdesigner\appModel.mat') Warning: Functionality not supported with figures created with the uifigure function. For more information, see Graphics Support in App Designer. (Type "warning off MATLAB:ui:uifigure:UnsupportedAppDesignerFunctionality" to suppress this warning.) d = appData: [1x1 appdesigner.internal.serialization.app.AppData] >> d.appData ans = AppData with properties: UIFigure: [1x1 Figure] CodeData: [1x1 appdesigner.internal.codegeneration.model.CodeData] Metadata: [1x1 appdesigner.internal.serialization.app.AppMetadata] ToolboxVer: '2016a' >> d.appData.CodeData ans = CodeData with properties: GeneratedClassName: 'App3' Callbacks: [0x0 appdesigner.internal.codegeneration.model.AppCallback] StartupFcn: [1x1 appdesigner.internal.codegeneration.model.AppCallback] EditableSection: [1x1 appdesigner.internal.codegeneration.model.CodeSection] ToolboxVer: '2016a' >> d.appData.Metadata ans = AppMetadata with properties: GroupHierarchy: {} ToolboxVer: '2016a'

  • matlab/document.xml – this file contains a copy of the figure’s classdef code in plain-text XML:
    <?xml version="1.0" encoding="UTF-8"?>
    <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
       <w:body>
          <w:p>
             <w:pPr>
                <w:pStyle w:val="code"/>
             </w:pPr>
             <w:r>
                <w:t>
                   <![CDATA[classdef App2 < matlab.apps.AppBase % Properties that correspond to app components properties (Access = public) UIFigure matlab.ui.Figure UIAxes matlab.ui.control.UIAxes Button matlab.ui.control.Button CheckBox matlab.ui.control.CheckBox ListBoxLabel matlab.ui.control.Label ListBox matlab.ui.control.ListBox end methods (Access = public) function results = func(app) % Yair 1/8/2016 end end % App initialization and construction methods (Access = private) % Create UIFigure and components function createComponents(app) % Create UIFigure app.UIFigure = uifigure; app.UIFigure.Position = [100 100 640 480]; app.UIFigure.Name = 'UI Figure'; setAutoResize(app, app.UIFigure, true) % Create UIAxes app.UIAxes = uiaxes(app.UIFigure); title(app.UIAxes, 'Axes'); xlabel(app.UIAxes, 'X'); ylabel(app.UIAxes, 'Y'); app.UIAxes.Position = [23 273 300 185]; % Create Button app.Button = uibutton(app.UIFigure, 'push'); app.Button.Position = [491 378 100 22]; % Create CheckBox app.CheckBox = uicheckbox(app.UIFigure); app.CheckBox.Position = [491 304 76 15]; % Create ListBoxLabel app.ListBoxLabel = uilabel(app.UIFigure); app.ListBoxLabel.HorizontalAlignment = 'right'; app.ListBoxLabel.Position = [359 260 43 15]; app.ListBoxLabel.Text = 'List Box'; % Create ListBox app.ListBox = uilistbox(app.UIFigure); app.ListBox.Position = [417 203 100 74]; end end methods (Access = public) % Construct app function app = App2() % Create and configure components createComponents(app) % Register the app with App Designer registerApp(app, app.UIFigure) if nargout == 0 clear app end end % Code that executes before app deletion function delete(app) % Delete UIFigure when app is deleted delete(app.UIFigure) end end end]]>
                </w:t>
             </w:r>
          </w:p>
       </w:body>
    </w:document>

    <?xml version="1.0" encoding="UTF-8"?> <w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"> <w:body> <w:p> <w:pPr> <w:pStyle w:val="code"/> </w:pPr> <w:r> <w:t> <![CDATA[classdef App2 < matlab.apps.AppBase % Properties that correspond to app components properties (Access = public) UIFigure matlab.ui.Figure UIAxes matlab.ui.control.UIAxes Button matlab.ui.control.Button CheckBox matlab.ui.control.CheckBox ListBoxLabel matlab.ui.control.Label ListBox matlab.ui.control.ListBox end methods (Access = public) function results = func(app) % Yair 1/8/2016 end end % App initialization and construction methods (Access = private) % Create UIFigure and components function createComponents(app) % Create UIFigure app.UIFigure = uifigure; app.UIFigure.Position = [100 100 640 480]; app.UIFigure.Name = 'UI Figure'; setAutoResize(app, app.UIFigure, true) % Create UIAxes app.UIAxes = uiaxes(app.UIFigure); title(app.UIAxes, 'Axes'); xlabel(app.UIAxes, 'X'); ylabel(app.UIAxes, 'Y'); app.UIAxes.Position = [23 273 300 185]; % Create Button app.Button = uibutton(app.UIFigure, 'push'); app.Button.Position = [491 378 100 22]; % Create CheckBox app.CheckBox = uicheckbox(app.UIFigure); app.CheckBox.Position = [491 304 76 15]; % Create ListBoxLabel app.ListBoxLabel = uilabel(app.UIFigure); app.ListBoxLabel.HorizontalAlignment = 'right'; app.ListBoxLabel.Position = [359 260 43 15]; app.ListBoxLabel.Text = 'List Box'; % Create ListBox app.ListBox = uilistbox(app.UIFigure); app.ListBox.Position = [417 203 100 74]; end end methods (Access = public) % Construct app function app = App2() % Create and configure components createComponents(app) % Register the app with App Designer registerApp(app, app.UIFigure) if nargout == 0 clear app end end % Code that executes before app deletion function delete(app) % Delete UIFigure when app is deleted delete(app.UIFigure) end end end]]> </w:t> </w:r> </w:p> </w:body> </w:document>

I do not know why the code is duplicated, both in document.xml and (twice!) in appModel.mat. On the face of it, this does not seem to be a wise design decision.

Editing MLAPP files outside AppDesigner

We can presumably edit the app in an external editor as follow:

  1. Open the *.mlapp file in your favorite zip viewer (e.g., winzip or winrar). You may need to rename/copy the file as *.zip.
  2. Edit the contents of the contained matlab/document.xml file in your favorite text editor (Matlab’s editor for example)
  3. Load appdesigner/appModel.mat into Matlab workspace.
  4. Go to appData.CodeData.EditableSection.Code and update the cell array with the lines of your updated code (one cell element per user-code line).
  5. Do the same with appData.CodeData.GeneratedCode (if existing), which holds the same data as appData.CodeData.EditableSection.Code but also including the AppDesigner-generated [non-editable] code.
  6. Save the modified appData struct back into appdesigner/appModel.mat
  7. Update the zip file (*.mlapp) with the updated appModel.mat and document.xml

In theory, it is enough to extract the classdef code and same it in a simple *.m file, but then you would not be able to continue using AppDesigner to make layout modifications, and you would need to make all the changes manually in the m-file. If you wish to continue using AppDesigner after you modified the code, then you need to save it back into the *.mlapp file as explained above.
If you think this is not worth all the effort, then you’re probably right. But you must admit that it’s a bit fun to poke around…
One day maybe I’ll create wrapper utilities (mlapp2m and m2mlapp) that do all this automatically, in both directions. Or maybe one of my readers here will pick up the glove and do it sooner – are you up for the challenge?

Caveat Emptor

Note that the MLAPP file format is deeply undocumented and subject to change without prior notice in upcoming Matlab releases. In fact, MathWorker Chris Portal warns us that:

A word of caution for anyone that tries this undocumented/unsupported poking into their MLAPP file. Taking this approach will almost certainly guarantee your app to not load in one of the subsequent releases. Just something to consider in your off-roading expedition!

Then again, the same could have been said about the FIG and other binary file formats used by Matlab, which remained essentially the same for the past decade: Some internal field values may have changed but not the general format, and in any case the newer releases still accept files created with previous releases. For this reason, I speculate that future AppDesigners will accept MLAPP files created by older releases, possibly even hand-modified MLAPP files. Perhaps a CRC hash code of some sort will be expected, but I believe that any MLAPP that we modify today will still work in future releases. However, I could well be mistaken, so please be very careful with this knowledge. I trust that you can make up your own mind about whether it is worth the risk (and fun) or not.
AppDesigner is destined to gradually replace the aging GUIDE over the upcoming years. They currently coexist since AppDesigner (and its web-based uifigures) still does not contain all the functionality that GUIDE (and JFrame-based figures) provides (a few examples). I already posted a few short posts about AppDesigner (use the AppDesigner tag to list them), and today’s article is another in that series. Over the next few years I intend to publish more on AppDesigner and its associated new GUI framework (uifigures).

Zurich visit, 21-31 Aug 2016

I will be traveling to Zürich for a business trip between August 21-31. If you are in the Zürich area and wish to meet me to discuss how I could bring value to your work, then please email me (altmany at gmail).

Related posts:

  1. FIG files format – FIG files are actually MAT files in disguise. This article explains how this can be useful in Matlab applications....
  2. MLintFailureFiles or: Why can't I save my m-file?! – Sometimes Matlab gets into a state where it cannot use a valid m-file. This article explains what can be done. ...
  3. Setting axes tick labels format – Matlab plot axes ticks can be customized in a way that will automatically update whenever the tick values change. ...
  4. File deletion memory leaks, performance – Matlab's delete function leaks memory and is also slower than the equivalent Java function. ...
  5. Customizing uifigures part 1 – Matlab's new web-based uifigures can be customized in a variety of undocumented ways. ...
  6. Customizing uifigures part 3 – As I have repeatedly posted in recent years, Matlab is advancing towards web-based GUI. The basic underlying technology is more-or-less stable: an HTML/Javascript webpage that is created-on-the-fly and rendered in a stripped-down browser window (based on Chromium-based jxBrowser in recent...
AppDesigner GUI GUIDE Pure Matlab uifigure Undocumented feature
Print Print
« Previous
Next »
12 Responses
  1. Sam August 17, 2016 at 20:19 Reply

    Though not quite the same as what you’re envisioning, there’s a proof of concept implementation of *.mlapp -> *.m classdef on FEX (http://www.mathworks.com/matlabcentral/fileexchange/56237-mlapp2classdef).

    It’s a pretty basic thing thrown together so I could use AppDesigner’s layout tools and get a programmatic GUI out of it, which is my preferred GUI medium. It also attempts to strip the new UI elements out in favor of the “traditional” ones so I could work with older versions of MATLAB.

    • Sam August 17, 2016 at 20:23 Reply

      Forgot the GH link: https://github.com/StackOverflowMATLABchat/mlapp2classdef

    • Dev-iL August 17, 2016 at 21:34 Reply

      I’d like to point out one of the things we found while making the tool that Sam had mentioned: .mlapp -> .m conversion can very easily be done using the built-in function type (docs). The earliest MATLAB version where it worked (out of those we collectively had access to) was 2014b.
      Regarding the customization of .mlapp figures – the fact they’re webpages might actually be beneficial for customization, as UI elements can now be customized using CSS. I have explored this a bit and made a small demonstration after reading your “Customizing uifigures part 1” post. (Thanks!)

      • Yair Altman August 17, 2016 at 21:40

        Thanks for this – I believe that a guest post about your experience with customizing uifigures using CSS would be highly appreciated by readers. Care to give it a shot? Send me an email to discuss the technical details

  2. Terry Brennan October 7, 2016 at 18:15 Reply

    Why not use class inheritance to achieve your goals? As for working programmatically, one of the things I like about the app designer is that the resulting mlapp file defines a class so I can derive other classes from the gui-created class and work programmatically without the visual interface on the derived class. One can add components, modify properties etc. One can even declare methods and/or properties in the mlapp to be Abstract within the appdesigner. This allows the creation of a base class from which customizations can be derived.

    For example if I have a working appGUI.mlapp I can create

    classdef myAppGUI < appGUI
       properties
          NewButton matlab.ui.control.Button
       end
       methods
          function A = myAppGUI
             % A = A@appGUI; <-- usually not necessary
             A.NewButton = uibutton(A.UIFigure);
             A.NewButton.Position = [20 20 100 22];
          end
       end
    end

    classdef myAppGUI < appGUI properties NewButton matlab.ui.control.Button end methods function A = myAppGUI % A = A@appGUI; <-- usually not necessary A.NewButton = uibutton(A.UIFigure); A.NewButton.Position = [20 20 100 22]; end end end

    To assist you in recalling component names, etc, while programming the derived class you can have an instance of the base class (if it is not Abstract) in the workspace

    >> Base = appGUI;

    >> Base = appGUI;

    to interrogate its methods and properties. This is almost as good as having the appGUI code.

    Of course, this approach should not become obsolete, unless the MathWorks does something dumb like making mlapp classes Sealed.

  3. Oleg March 21, 2017 at 17:01 Reply

    The following methods load the data:

    lf      = appdesigner.internal.serialization.AppLoadingFactory.instance();
     
    appData = lf.getAppData('C:Usersok1011Documentsgithubcarv-realtime-matlabsrcutilities+carv+plotturn.mlapp')
     
      AppData with properties:
     
                       UIFigure: [1×1 Figure]
                       CodeData: [1×1 appdesigner.internal.codegeneration.model.CodeData]
                       Metadata: [1×1 appdesigner.internal.serialization.app.AppMetadata]
                     ToolboxVer: '2016b'
                    FullVersion: '9.1.0.441655 (R2016b)'
        MinimumSupportedVersion: 'R2016b'

    lf = appdesigner.internal.serialization.AppLoadingFactory.instance(); appData = lf.getAppData('C:Usersok1011Documentsgithubcarv-realtime-matlabsrcutilities+carv+plotturn.mlapp') AppData with properties: UIFigure: [1×1 Figure] CodeData: [1×1 appdesigner.internal.codegeneration.model.CodeData] Metadata: [1×1 appdesigner.internal.serialization.app.AppMetadata] ToolboxVer: '2016b' FullVersion: '9.1.0.441655 (R2016b)' MinimumSupportedVersion: 'R2016b'

    Or using the file reader, which allows to read Matlab code directly:

    fid     = appdesigner.internal.serialization.FileReader('C:Usersok1011Documentsgithubcarv-realtime-matlabsrcutilities+carv+plotturn.mlapp');
    appData = fid.readAppDesignerData();
    mcode   = fid.readMATLABCodeText();

    fid = appdesigner.internal.serialization.FileReader('C:Usersok1011Documentsgithubcarv-realtime-matlabsrcutilities+carv+plotturn.mlapp'); appData = fid.readAppDesignerData(); mcode = fid.readMATLABCodeText();

    The appdesigner.internal.serialization.FileWriter() class allows to write code to the .mlapp file.

  4. Tom April 17, 2018 at 16:43 Reply

    Thanks for this tutorial. You saved me a ton of work. After Matlab crashed and corrupted my .mlapp file, I was able to unzip the .mlapp file and get to my GUI code and recreate my GUI. Without this, I would be months behind recreating the GUI and rewriting all the code. This website was a lifesaver. Thank you very much.

  5. Antonio Martinez July 30, 2019 at 18:06 Reply

    So, I don’t know if anyone is still reading this comment section but I tried digging a bit more into how MLAPP files are generated, following up Oleg’s contribution.

    My conclusion is that, as far as I have been able to reach without basically fully reverse engineering AppDesigner’s inner workings, there is no way to use the methods available in appdesigner.internal such as FileWriter() to generate MLAPP files from the class definition in text format in an M file.

    Here’s what I found.

    • In newer versions of MATLAB the MLAPP file is organized in pretty much the same way but the appdesigner/appModel.mat file has a different organization. Now the AppData field is deprecated but kept for compatibility, and the data it contained is replace by two new fields ‘code’ and ‘components’. The ‘code’ struct stores the code from the app in separated sections (EditableSectionCode which is the part that contains the methods and properties, Callbacks, StartupCallback, etc), and components stores the UIFigure and the group hierarchy (I have no idea what this is, is generated by the AppModel method getGroupHierarchy() and is way to deep for me too understand already). The groups hierarchy was previusly stored inside appData.metadata.

    • AppModel: probably the parent for all apps created in AppDesigner is the class appdesigner.internal.model.AppModel . The AppModel contains the save() method, and has the properties Metadata and CodeModel among others. CodeModel is generated from the class appdesigner.internal.codegeneration.model.CodeModel, and contains the different sections of the code.

    • FileWriter(): as Oleg’s pointed correctly, appdesigner.internal.serialization.FileWriter() is a class that can generate and write to MLAPP files. It has 4 methods (writeMATLABCodeText, writeAppDesignerData, writeAppMetadata, writeAppScreenshot) that have to be called to succesfully contruct an MLAPP file, and can be called from the command line, which would allow using them to generate MLAPP files from its components. The problem is, this components can only be accessed by AppDesigner itself, which renders this methods useless.

    • Hypothesis for MLAPP file saving: my hypothesis is that when an app is saved, the save() method in the AppModel class is called, which in turn calls the AppModel method writeAppToFile(), which creates an appdesigner.internal.serialization.MLAPPSerializer instance. The AppModel’s method setDataOnSerializer() copies all the required information to MLAPPSerializer, including the code sections, the metadata, group hierarchy, etc. Then, MLAPPSerializer creates a fileWriter instance, divides the different objects received from AppModel and passes them to the relevant fileWriter methods to generate the MLAPP file.

    I’m afraid there is literally no way to correctly generate the data scructures that are necessary to reconstruct an MLAPP file from the plain code without putting a ton of hours into untangling all the logic behind AppDesigner. Maybe someone can use this information to take on that task in the future.

    • Antonio Martinez July 30, 2019 at 18:07 Reply

      By the way, these are the relevant MATLAB files if someone wants so keep reverse engineering this thing

      • C:\Program Files\MATLAB\R2018b\toolbox\matlab\appdesigner\appdesigner\+appdesigner\+internal\+model\AppModel.m
      • C:\Program Files\MATLAB\R2018b\toolbox\matlab\appdesigner\appdesigner\+appdesigner\+internal\+codegeneration\+model\CodeModel.m
      • C:\Program Files\MATLAB\R2018b\toolbox\matlab\appdesigner\appdesigner\+appdesigner\+internal\+serialization\MLAPPSerializer.m
      • C:\Program Files\MATLAB\R2018b\toolbox\matlab\appdesigner\appdesigner\+appdesigner\+internal\+serialization\FileWriter.m

  6. Bradley Stiritz November 5, 2019 at 01:13 Reply

    It’s great to see that Yair and others are digging into the internals of AppDesigner. It seems to have a lot of promise. At the same time, AppDesigner is still often unstable and unusable, as of R2019b. I just posted on the running Mathworks Answers thread about this–

    https://www.mathworks.com/matlabcentral/answers/279042-app-designer-s-editor-is-slow-and-gets-stuck-alot

    Question for anyone who has studied the internals– have you also experienced problems in AppDesigner, and then gained any insights whatsoever via your sleuthing? Do you have any clues or hypotheses about what could be going wrong for so many users?

    Surely, after all these years of hard work, the AppDesigner team should have worked out most of the minor bugs..?

  7. Adil November 15, 2020 at 05:02 Reply

    Thank you for the blog, it was useful for me. I have a file named App_project.mlapp.zip and when I extract it through Winzip it gives all the files exactly as you described above. I don’t know how to load these all files in App designer in matlab. Please guide. I have also all functions .m files that were used in this app as well.

  8. Stéphane Issartel July 27, 2021 at 13:08 Reply

    Both .mlx and .mlapp file format seem to be “Open Packaging Conventions” formatted files. See https://en.wikipedia.org/wiki/Open_Packaging_Conventions#Package,_parts,_and_relationships and https://docs.microsoft.com/en-us/previous-versions/windows/desktop/opc/packaging

Leave a Reply
HTML tags such as <b> or <i> are accepted.
Wrap code fragments inside <pre lang="matlab"> tags, like this:
<pre lang="matlab">
a = magic(3);
disp(sum(a))
</pre>
I reserve the right to edit/delete comments (read the site policies).
Not all comments will be answered. You can always email me (altmany at gmail) for private consulting.

Click here to cancel reply.

Useful links
  •  Email Yair Altman
  •  Subscribe to new posts (feed)
  •  Subscribe to new posts (reader)
  •  Subscribe to comments (feed)
 
Accelerating MATLAB Performance book
Recent Posts

Speeding-up builtin Matlab functions – part 3

Improving graphics interactivity

Interesting Matlab puzzle – analysis

Interesting Matlab puzzle

Undocumented plot marker types

Matlab toolstrip – part 9 (popup figures)

Matlab toolstrip – part 8 (galleries)

Matlab toolstrip – part 7 (selection controls)

Matlab toolstrip – part 6 (complex controls)

Matlab toolstrip – part 5 (icons)

Matlab toolstrip – part 4 (control customization)

Reverting axes controls in figure toolbar

Matlab toolstrip – part 3 (basic customization)

Matlab toolstrip – part 2 (ToolGroup App)

Matlab toolstrip – part 1

Categories
  • Desktop (45)
  • Figure window (59)
  • Guest bloggers (65)
  • GUI (165)
  • Handle graphics (84)
  • Hidden property (42)
  • Icons (15)
  • Java (174)
  • Listeners (22)
  • Memory (16)
  • Mex (13)
  • Presumed future risk (394)
    • High risk of breaking in future versions (100)
    • Low risk of breaking in future versions (160)
    • Medium risk of breaking in future versions (136)
  • Public presentation (6)
  • Semi-documented feature (10)
  • Semi-documented function (35)
  • Stock Matlab function (140)
  • Toolbox (10)
  • UI controls (52)
  • Uncategorized (13)
  • Undocumented feature (217)
  • Undocumented function (37)
Tags
ActiveX (6) AppDesigner (9) Callbacks (31) Compiler (10) Desktop (38) Donn Shull (10) Editor (8) Figure (19) FindJObj (27) GUI (141) GUIDE (8) Handle graphics (78) HG2 (34) Hidden property (51) HTML (26) Icons (9) Internal component (39) Java (178) JavaFrame (20) JIDE (19) JMI (8) Listener (17) Malcolm Lidierth (8) MCOS (11) Memory (13) Menubar (9) Mex (14) Optical illusion (11) Performance (78) Profiler (9) Pure Matlab (187) schema (7) schema.class (8) schema.prop (18) Semi-documented feature (6) Semi-documented function (33) Toolbar (14) Toolstrip (13) uicontrol (37) uifigure (8) UIInspect (12) uitools (20) Undocumented feature (187) Undocumented function (37) Undocumented property (20)
Recent Comments
  • Nicholas (6 days 23 hours ago): Hi Yair, Thanks for the reply. I am on Windows 10. I also forgot to mention that this all works wonderfully out of the editor. It only fails once compiled. So, yes, I have tried a...
  • Nicholas (6 days 23 hours ago): Hi Yair, Thanks for the reply. I am on Windows 10. I also forgot to mention that this all works wonderfully out of the editor. It only fails once compiled. So, yes, I have tried a...
  • Yair Altman (7 days 6 hours ago): Nicholas – yes, I used it in a compiled Windows app using R2022b (no update). You didn’t specify the Matlab code location that threw the error so I can’t help...
  • Nicholas (8 days 3 hours ago): Hi Yair, Have you attempted your displayWebPage utility (or the LightweightHelpPanel in general) within a compiled application? It appears to fail in apps derived from both R2022b...
  • João Neves (11 days 7 hours ago): I am on matlab 2021a, this still works: url = struct(struct(struct(struct(hF ig).Controller).PlatformHost). CEF).URL; but the html document is empty. Is there still a way to do...
  • Yair Altman (14 days 6 hours ago): Perhaps the class() function could assist you. Or maybe just wrap different access methods in a try-catch so that if one method fails you could access the data using another...
  • Jeroen Boschma (14 days 8 hours ago): Never mind, the new UI components have an HTML panel available. Works for me…
  • Alexandre (14 days 9 hours ago): Hi, Is there a way to test if data dictionnatry entry are signal, simulink parameters, variables … I need to access their value, but the access method depends on the data...
  • Nicholas (15 days 0 hours ago): In case anyone is looking for more info on the toolbar: I ran into some problems creating a toolbar with the lightweight panel. Previously, the Browser Panel had an addToolbar...
  • Jeroen Boschma (18 days 7 hours ago): I do not seem to get the scrollbars (horizontal…) working in Matlab 2020b. Snippets of init-code (all based on Yair’s snippets on this site) handles.text_explorer...
  • Yair Altman (46 days 9 hours ago): m_map is a mapping tool, not even created by MathWorks and not part of the basic Matlab system. I have no idea why you think that the customizations to the builtin bar function...
  • chengji chen (46 days 15 hours ago): Hi, I have tried the method, but it didn’t work. I plot figure by m_map toolbox, the xticklabel will add to the yticklabel at the left-down corner, so I want to move down...
  • Yair Altman (54 days 8 hours ago): @Alexander – this is correct. Matlab stopped including sqlite4java in R2021b (it was still included in 21a). You can download the open-source sqlite4java project from...
  • Alexander Eder (60 days 4 hours ago): Unfortunately Matlab stopped shipping sqlite4java starting with R2021(b?)
  • K (66 days 15 hours ago): Is there a way to programmatically manage which figure gets placed where? Let’s say I have 5 figures docked, and I split it into 2 x 1, I want to place 3 specific figures on the...
Contact us
Captcha image for Custom Contact Forms plugin. You must type the numbers shown in the image
Undocumented Matlab © 2009 - Yair Altman
This website and Octahedron Ltd. are not affiliated with The MathWorks Inc.; MATLAB® is a registered trademark of The MathWorks Inc.
Scroll to top