Up until Matlab release R2008a, the Matlab compiler enabled compiled Matlab applications to have dockable figure windows, which docked into a “Figures” container. Starting with R2008a, the compiler removed the figure’s docking capability and figures can no longer be docked.
Well, at least not officially 🙂
The following trick restores the docking controls to figures in R2008a-compiled applications, enabling figure docking. Simply add one or both of the following alternatives in your application, after the figure has been created:
% Alternative #1 - uses pure Matlab set(hFig, 'DockControls', 'on'); % Alternative #2 - uses the underlying Java frame jFrame = get(handle(hFig), 'JavaFrame'); try % This works up to R2011a jFrame.fFigureClient.setClientDockable(true); catch % This works from R2008b and up jFrame.fHG1Client.setClientDockable(true); end
hFig is the figure handle. This will have no effect for the regular interpreted (non-compiled) run of the application, where these controls are ‘on’ by default. But in the compiled application, although it may erroneously report that the controls are ‘on’, they are in fact ‘off’, so turning them ‘on’ fixes the problem.
Note: the two variants in alternative #2 above are actually identical, it is simply that the relevant field name has changed: Up to R2008a, only the
fFigureClientexisted; in R2008b, the
fHG1Clientfield was added, which was simply an alias for
fFigureClient, holding the same reference handle, so either of these fields could be used (a corresponding fHG2Client was also added – more on HG1 and HG2 here). In R2011b (at least the pre-release), the
fFigureClientalias field was dropped and only
fHG1Clientremained. While the field name has changed, the underlying docking functionality appears to have remained stable over all these releases. For the record, in answer to a user question below, these fields can be listed using the built in fieldnames function:
% R2008b - R2011a: >> fieldnames(jFrame) ans = 'fFigureClient' 'fHG2Client' 'fHG1Client' 'fUseHG2' 'UICONTROLBACKGROUND_OS' 'UICONTROLBACKGROUND_COMPATIBLE'
I was reminded of this trick by Aurélien’s recent comment, where he mentions MathWorks so-called workaround for this problem, which (IMHO) is really not a work-around at all: MathWorks advises to modify our application to use – would you believe this – tabbed panels to “dock” the separate figures contents onto separate panels. Not to mention the fact that this so-called “solution” relies on undocumented and unsupported Matlab functionality (that of tabbed-panels) and requires major rework of existing applications, it also results in far inferior look-and-feel than simple docking as G-d intended…
Since I have demonstrated above that the docking functionality actually exists in compiled apps just as in the interpreted m-file apps, I do not understand why MathWorks took such great pains to prevent this important functionality in the compiler. There must be some important reason for this, but I cannot think of any. Perhaps if there is enough public demand, MathWorks will agree to return the docking functionality.
Unfortunately, I recently discovered that in the most recent compiler, that ships with R2011a, alternative #1 above (which uses pure Matlab) no longer works. Sometime between R2008a and R2011a MathWorks discovered my first back-door and closed it. Such a pity…
Luckily, alternative #2 (which uses the underlying Java frame object) seems to still work, even on R2011a.
I still haven’t tested this on R2011b’s compiler (whose pre-release has become available for download yesterday), but hopefully the trick above will continue to work on R2011b and on subsequent releases – please tell me if you find out otherwise.
Addendum: Since 2013, possibly as a direct result of this post, MathWorks have prevented this workaround. MathWorks officially states that docking figures is not possible in deployed applications. I do not know the reason for this, and I have still not discovered if another workaround for this annoying limitation is possible.