Over the past couple of years, I posted several articles using the JavaFrame property of the figure handle, which enables access to the GUI’s underlying Java peer object. Today, I show how using JavaFrame we can solve a very frequent user request on the Matlab CSSM forum.
Matlab figures can be maximized, minimized and restored by interactively clicking the corresponding icon (or menu item) on the figure window’s frame (the title bar). However, we often need to create maximized main-application windows, and wish to save the users the need to manually maximize the window. Moreover, we may sometimes even wish to prevent users from resizing a maximized main window.
Unfortunately, Matlab does not contain any documented or supported way to programmatically maximize, minimize or restore a figure window.
This is very strange considering the fact that these are such elementary figure operations. Moreover, these operations are supported internally (and have been for many releases already), as shown below. It is therefore difficult for me to understand why they were not added to the documented Matlab HG wrapper functionality a long time ago. I fail to understand why obscure features such as docking were added to the wrapper, but standard minimization and maximization were not.
Several solutions have been presented to this problem over the years. Let us start with the pressing question of figure maximization:
Solutions that rely on documented Matlab features tend to compute the available screen size and resize the figure accordingly. The result is lacking in many respects: it does not account for the taskbar (neither in size nor in location, which is not necessarily at the bottom of the screen); it does not remove the window border as in regular maximized figures; and it often ignores extended desktops (i.e. an attached additional monitor).
The solutions that do work properly all rely on undocumented features: Some use platform-specific native Windows API in a mex-file (Jan Simon’s recent WindowAPI submission really pushes the limit in this and other regards). Alternately, we can easily use the platform-independent JavaFrame:
>> jFrame = get(handle(gcf),'JavaFrame') jFrame = com.mathworks.hg.peer.FigurePeer@cdbd96 >> jFrame.setMaximized(true); % to maximize the figure >> jFrame.setMaximized(false); % to un-maximize the figure
To the best of my knowledge, there are no solutions for minimizing figure windows that use documented Matlab features. Again, this can be done using either native Windows API, or the platform-independent JavaFrame:
>> jFrame.setMinimized(true); % to minimize the figure >> jFrame.setMinimized(false); % to un-minimize the figure
Maximized and Minimized are mutually-exclusive, meaning that no more than one of them can be 1 (or true) at any time. This is automatically handled – users only need to be aware that a situation in which a window is both maximized and minimized at the same time is impossible (duh!).
There are several equivalent manners of setting
jFrame‘s Maximized and Minimized property values, and your choice may simply be a matter of aesthetics and personal taste:
% Three alternative possibilities of setting Maximized: jFrame.setMaximized(true); set(jFrame,'Maximized',true); % note interchangeable 1< =>true, 0< =>false jFrame.handle.Maximized = 1;
jFrame follows Java convention: the accessor method that retrieves boolean values is called is<Propname>() instead of get<Propname>. In our case: isMaximized() and isMinimized():
flag = jFrame.isMinimized; % Note: isMinimized, not getMinimized flag = get(jFrame,'Minimized'); flag = jFrame.handle.Minimized;
In some old Matlab releases,
jFrame did not possess the Maximized and Minimized properties, and their associated accessor methods. In this case, use the internal
FrameProxy which has always contained them:
>> jFrameProxy = jFrame.fFigureClient.getWindow() jFrameProxy = com.mathworks.hg.peer.FigureFrameProxy$FigureFrame[fClientProxyFrame,227,25,568x502,invalid,layout=java.awt.BorderLayout,title=Figure 1,resizable,normal,defaultCloseOperation=DO_NOTHING_ON_CLOSE,...] >> % Three alternative possibilities of setting Minimized: >> jFrameProxy.setMinimized(true); >> set(jFrameProxy,'Minimized',true); >> jFrameProxy.handle.Minimized = true;
FrameProxy for figure minimization and maximization works correctly on both old and new Matlab releases; using
jFrame is slightly simpler but only works on recent Matlab releases. Depending on your needs you may choose to use either of these. They are entirely equivalent.
When either the Maximized or Minimized properties are changed back to false, the window is restored to regular mode, which is the
FrameProxy‘s RestoredLocation and RestoredSize.
Use of the JavaFrame property
Note that all this relies on the undocumented hidden figure property JavaFrame, which issues a standing warning (since Matlab release R2008a) of becoming obsolete in some future Matlab release (HG2?):
>> jFrame = get(gcf,'JavaFrame') Warning: figure JavaFrame property will be obsoleted in a future release. For more information see the JavaFrame resource on the MathWorks web site. (Type "warning off MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame" to suppress this warning.) jFrame = com.mathworks.hg.peer.FigurePeer@1ffbad6
To remove the above warning I have used (note the handle wrapper, as suggested by Donn Shull):
jFrame = get(handle(gcf),'JavaFrame')
If and when JavaFrame does become obsolete in some future Matlab version, be sure to look in this blog for workarounds.
You may also wish to inform MathWorks on the dedicated webpage that they have set up for specifically this reason (http://www.mathworks.com/javaframe), how you are using JavaFrame and why it is important for you. This may help them to decide whether to keep JavaFrame or possibly add the functionality using other means.
Do you have a smart use for the figure’s minimization or maximization feature? or another use for JavaFrame? If so, please share your ideas in a comment below.