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.
The problem
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.
Maximization
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 |
Minimization
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 |
Usage notes
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; |
Using 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.
Hi Yair,
To maximise figures I use the outerposition property :
In the past I used this following Technical solution
http://www.mathworks.com/support/solutions/en/data/1-3MY8PN/index.html?solution=1-3MY8PN
The drawback is that you have to recompile pcodes for each new release
Aurélien
Dear Aurelien,
The debugger, inmem and L=import reveal that the P-files shown on solution 1-3MY8PN call the same java methods as used by Yair here. Hiding the code in a P-file is not really helpful.
Kind regards, Jan
Hi Yair,
The results of setting the visible area of a figure to full-screen have been strange from Matlab 5.3 to 2009a (I cannot test current versions):
The same problem appeared in WindowAPI, when the window is resized without setting the SWP_NOSENDCHANGING flag in the Windows-API function SetWindowPos.
If the figure height is increased over the screen height, Matlab performs a magic movement automatically also:
But setLocation and setSize of javaFrame.fFigureClient.getWindow() works as expected.
Now I found out how to limit the dialog size efficiently. I cannot implement this in Matlab’s ResizeFcn reliably. But this works:
Thanks, Yair, to help me to find this method!
Kind regards, Jan
For anyone interested, Leah Kaffine has posted a trick to maximize a figure window on a second connected monitor:
On the same page, Ismail Ilker Delice has posted a nice comment about the possibility to “minimize” windows, using the following pure-Matlab code:
Using [-1,-1,eps,eps] is a nice trick to hide the figure window. However, it simply moves the figure to an impossible screen location (thereby hiding it) – it does not really minimize the figure. You can see this by right-clicking the figure icon in the task-bar – there is no “restore” option, just “minimize” and “maximize”. Still, I like the fact that this trick relies on the undocumented fact that [-1,-1,eps,eps] are acceptable parameters.
Hi Yair.
There are two problems with the solution you’ve proposed. whn running the command
1) The following warning “Warning: figure JavaFrame property will be obsoleted in a future release” is presented. While this warning can be turned off, it is bad news to see that this functionality will not work in future releases.
2) Sometimes a following Java error occurs
” java.lang.NullPointerException
at com.mathworks.hg.peer.FigureFrameProxy.setMaximized(FigureFrameProxy.java:208)
at com.mathworks.hg.peer.FigureMediator.setMaximized(FigureMediator.java:388)
at com.mathworks.hg.peer.FigurePeer.doSetMaximized(FigurePeer.java:3256)
at com.mathworks.hg.peer.FigurePeer$26.run(FigurePeer.java:3245)
at com.mathworks.hg.util.HGPeerQueue$HGPeerRunnablesRunner.runit(HGPeerQueue.java:229)
at com.mathworks.hg.util.HGPeerQueue$HGPeerRunnablesRunner.runNotThese(HGPeerQueue.java:261)
at com.mathworks.hg.util.HGPeerQueue$HGPeerRunnablesRunner.run(HGPeerQueue.java:277)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source) “
@Nikolay – I believe the occasional Java errors may be due to one of two reasons:
1. The figure is not yet fully rendered and visible when you are calling the setMaximized function. Unfortunately,
JavaFrame
functionality is only accessible when the figure is visible and fully rendered. So, for example, if you place the call to setMaximized in your GUI’s *_OpeningFcn() function (when the figure is not yet visible), it will fail. Instead, place the call in your GUI’s *_OutputFcn() function.2. Another possible reason is due to EDT effects. The easiest solution is to place a call to drawnow; pause(0.1); before you access the
JavaFrame
functionality (setMaximized or any other Java function).Hi again.
Indeed, a few minutes after writing my comment I’ve tried pause(0.3) and it seems to eliminate the errors. I have also bypassed the warning with “warning(‘off’,’MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame’);” nut both issues solution is far from good Matlabing :(… That’s why i haven’t posted this solution on Matlab Central yet 😉
Hi everybody,
I’m a newcomer here on this fantastic page.
Here are my solution:
Have a nice weekend
S
@S – this is indeed the regular solution but it does not create true maximization of the window, like you would expect from any other regular application. Also, it does not provide a solution for minimization. For these reasons we need to use the mechanism that was posted in the article above.
Excellent solution! After lots of exhaustive searches, I’ve finally found a solution different from
which simply resize the OUTER BORDER of the figure window accordingly to the size of the screen, and not truly maximize it (i.e., VISIBLE AREA resized to fit the entire screen).
Very good indeed!
Thanks a lot!
Hey everybody,
First of all congratulation to this post, but it is not clear in my mind how is possible to switch the units from pixel to normalized. I have understood that is possible with
but if in the panel there are other javacomponent such as jButton or jTextField how we can use javacomponent function? Can we use the “mhandle”? I mean
I have tried this solution but it is not working 🙁
Thanks in advance to everyone
Bob
@Bob – you can indeed use a uipanel handle, rather than the figure handle, as the javacomponent parent. Read this article about it.
[…] Note that we have used the figure handle’s hidden JavaFrame property, accessed through the reference’s handle() wrapper, to prevent an annoying warning […]
Hello Everyone!
Has anyone tried to use this when doing X-Forwarding through a SSH session on Linux? No matter what I do with changing the maximized or minimized Java state, it doesn’t impact what is going on with the window. Is there any way around this?
Thanks!
Troy
Very nice. Any suggestions on maximizing/minimizing the entire MATLAB base window? I tried
but it gives the following error.
I’m in R2012b on Linux.
@Brian
Hi Yair,
Thanks very much for the solution.
However, I don’t know why your solution is still not a “real” maximization for my GUI: the taskbar are still there.
I am using Windows7 and MatlabR2010b.
Thanks in advance for your help!
@Bibo, in Windows the taskbar remains visible when you maximize any window in any application.
[…] […]
[…] the solution of the rbbox-anywhere feature relies on using a temporary transparent window that spans the entire desktop area, capturing user rbbox clicks anywhere within the desktop area. […]
>> 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.
I’ve used JavaFrame to toggle “always on top” property: http://www.mathworks.com/matlabcentral/fileexchange/42252
.. and, most probably, it can be used to access most of features, provided by this submission: http://www.mathworks.com/matlabcentral/fileexchange/31437-windowapi too.
MATLAB R2013a for
returns
‘cdbd96’ is not a valid base class.
@Andrey – the second line is the result of running the first line. It is not a separate command by itself, and you cannot run it by itself. It is simply the reference handle for the figure’s Java frame object
FigurejFrame
:OK, now it works in sample code, but in my script it gives:
java.lang.NullPointerException
at com.mathworks.hg.peer.FigureFrameProxy.setMaximized(FigureFrameProxy.java:249)
at com.mathworks.hg.peer.FigureMediator.setMaximized(FigureMediator.java:392)
at com.mathworks.hg.peer.FigurePeer.doSetMaximized(FigurePeer.java:3365)
at com.mathworks.hg.peer.FigurePeer$26.run(FigurePeer.java:3354)
at com.mathworks.hg.util.HGPeerQueue$HGPeerRunnablesRunner.runit(HGPeerQueue.java:262)
at com.mathworks.hg.util.HGPeerQueue$HGPeerRunnablesRunner.runNotThese(HGPeerQueue.java:294)
at com.mathworks.hg.util.HGPeerQueue$HGPeerRunnablesRunner.run(HGPeerQueue.java:310)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
perhaps the figure window is not visible or fully rendered when you run setMaximized()
Is there a way to wait until figure window is fully rendered before calling setMaximized()?
This helped to achieve desired behavior.
Thank you!
[…] Maximized figure window […]
Hi Yair,
I put the following code in output function of my gui
But the figure is neither maximizing nor any error is displaying.
@Ayantha – I explained this in the Usage Notes section of the article – read carefully.
Thanks Yair,It worked. For some unknown reason, it didn’t work with an inbuilt example of Matlab. But it worked fine with my own code. Thanks again and keep your good work going.
Any ideas on how to remove the Title Bar from the figure window? I’ve tried frame.setExtendedState(JFrame.MAXIMIZED_BOTH); frame.setUndecorated(true); but get the error “Undefined variable “JFrame” or function “JFrame.MAXIMIZED_BOTH”.”
@Terence – you cannot undecorate a Java Frame (figure window) using Java code after the JFrame is made visible, and you cannot access the JFrame in Matlab before it is made visible. In practice this means that you [probably] cannot do that with Java.
However, you may possibly be able to do it using Windows API if you’re running Windows. For this you can try using Jan Simon’s WindowAPI utility.
Hi there,
I tried to loop minimizing multiple figures with this ‘JavaFrame’ property.
I works fine for minimizing the matlab desktop, the current figure and for a specific figure. But till now i cant loop these commands.
So is there a reason why this code does not work?
The idea is that when i start a certain GUI, all other Matlab windows will be minimized.
Other options i have in mind:
1. resize all figures and put them to an edge of the screen
% but this is not what i want
2. trying to ‘auto-click’ the ‘show desktop’ button in windows 7
Then i just automatically minimize all, and then start my gui window. This would be my best case scenario.
btw, nice site, learned a lot about matlab here.
@Dubbel – it should work, assuming all your figures are in fact visible. I would wrap the internals of the loop in a try-catch, so that if one figures fails to minimize, the others will still work. Something like this:
Thanks, yours works.
and figured out what my fault was:
instead off:
so now both methods work 🙂
Hi,
On figure creation, I would like to maximize it (easily done with your method) and then prevents users to change its size. To do so I use documented Matlab function ( set(hfig,’Resize’,’off’) ). There seems to have a side-effect: figure is slightly maximized. That means inner borders of the window are at the limits of the screensize and the not outer borders.. Why ?
my code:
Thanks in advance
@Luis – simply switch the order of the actions:
Thanks a lot, Yair, it works fine
Hi,
I have one last issue with the use of this programming technique. Here is my code:
It works fine until I double-click on the title bar (I am running Matlab R2014a on Windows 7 sp1). Then the window of my application shrinks to a small square (about 100×100 pixels) and there is no way I can maximize it again.
Thanks in advance for your help
Luis
@Luis – of course it does! what else did you expect? you created the figure with an initial size (Position) of 100×100 pixels, so when you de-maximize the figure it goes back to this size. Instead, create your initial figure with a larger size.
Thank you for your help, Yair.
Indeed, that was obvious…
Here’s my code:
If I just let this run in R2014b (HG2) it throws an exception:
and does not maximize the figure. HOWEVER, if I put a breakpoint anywhere in the try/catch, and it stops there, and I hit F5 to continue, it works just fine with no exception at all being thrown, just an orange warning:
Why does it work only if there is a breakpoint stopped at and not when I just run it non-stop like I’d want?
@IA – Probably because the figure window is not fully rendered when the jFrame code is reached. This is due to the fact that in R2014b, the figure function no longer blocks execution until the figure is fully rendered.
I suggest moving the
drawnow; pause(0.1);
code to before the jFrame code, rather than after it – this will ensure that the figure is fully rendered at that time:Yair, it works now. Just one little problem. It’s SO maximized that it covers up the Windows 7 task bar at the bottom of my screen. Is there any way to have it maximized but still have the taskbar show up? That’s the way maximizing normally works.
@IA – I’m afraid that this is the behavior for figure windows that have Resize=’off’. If you set Resize=’on’ (the default value), then it will work as you expect vis-a-vis the taskbar. If you wish to get the Resize=’on’ behavior while still disabling resizing you can use the following code snippet:
It’s not perfect, but close enough…
Thanks. I didn’t know what that resize stuff was – I just had it in there because other code above did, and I thought I needed it. I just removed that line and now everything works great. Thanks for figuring it out for me!
I wanted to use the maximize function to get the size of the screen on which a figure is shown (using multiple screens). And “manually” (step by step) this works, but in a function, this doesn’t! In debugging mode, executing it, it works too.
When I first saw this, I thought: “simple: just add drawnow”, but that didn’t help.
Any idea?
@Stijn – try adding pause(0.5) after the drawnow. If it works then you can play with the pause duration to find the minimal duration value that works well on your specific system.
In 2017a, jFrameProxy = jFrame.fFigureClient.getWindow() gives an error:
Undefined function or variable ‘fFigureClient’
Is there any replacement for functionality?
@Richard – https://undocumentedmatlab.com/blog/hg2-update#observations