Minimize/maximize figure window

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.

Related posts:

  1. Enable/disable entire figure window Disabling/enabling an entire figure window is impossible with pure Matlab, but is very simple using the underlying Java. This article explains how....
  2. Transparent Matlab figure window Matlab figure windows can be made fully or partially transparent/translucent or blurred - this article explains how...
  3. Blurred Matlab figure window Matlab figure windows can be blurred using a semi-transparent overlaid window - this article explains how...
  4. Detecting window focus events Matlab does not have any documented method to detect window focus events (gain/loss). This article describes an undocumented way to detect such events....
  5. Customizing figure toolbar background Setting the figure toolbar's background color can easily be done using just a tiny bit of Java magic powder. This article explains how. ...
  6. Figure toolbar customizations Matlab's toolbars can be customized using a combination of undocumented Matlab and Java hacks. This article describes how to customize the Matlab figure toolbar....

Categories: Figure window, GUI, Hidden property, Java, Medium risk of breaking in future versions, Undocumented feature, Undocumented function

Tags: , , , , , ,

Bookmark and SharePrint Print

39 Responses to Minimize/maximize figure window

  1. Aurélien says:

    Hi Yair,

    To maximise figures I use the outerposition property :

     figure('units','normalized','outerposition',[0 0 1 1])

    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

    • Jan Simon says:

      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

  2. Jan Simon says:

    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):

    set(gcf, 'Units', 'normalized', 'Position', [0, 0, 1, 1])
    get(gcf, 'Position')   % >> 0 0 1.0 0.9154

    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:

    set(gcf, 'Units', 'pixels', 'Position', [1, 1, 1024, 768])  % correct
    pause(1);
    set(gcf, 'Units', 'pixels', 'Position', [1, 1, 1024, 820])  % bad

    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:

    jh = get(handle(gcf), 'JavaFrame');
    jp = jh.fFigureClient.getWindow();
    jp.setMinimumSize(java.awt.Dimension(200, 200));

    Thanks, Yair, to help me to find this method!
    Kind regards, Jan

  3. For anyone interested, Leah Kaffine has posted a trick to maximize a figure window on a second connected monitor:

    set(gcf, 'Units', 'normalized', 'Position', [0, 0, 1, 1])  % maximize on main monitor
    set(gcf, 'Units', 'normalized', 'Position', [1, 0, 1, 1])  % maximize on secondary 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:

    set(gcf, 'Units', 'normalized', 'Position', [0, 0, 1, 1]);          % Maximization as suggested above
    set(gcf, 'Units', 'normalized', 'Position', [-1, -1, eps, eps]);    % Minimize
    set(gcf, 'Units', 'normalized', 'Position', [0.1, 0.1, 0.5, 0.5]);  % Restore

    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.

  4. Nikolay says:

    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).

    • Nikolay says:

      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 ;)

  5. S says:

    Hi everybody,
    I’m a newcomer here on this fantastic page.
    Here are my solution:

    %for gui with guide (OutputFcn)
    a=get(0,'ScreenSize');
    set(handles.figure1,'position',a);

    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.

  6. Tadeu says:

    Excellent solution! After lots of exhaustive searches, I’ve finally found a solution different from

    set(handles.figure1,'position',get(0,'ScreenSize'));

    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!

  7. Bob says:

    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

    [javaHandlePanel matlabHandlePanel] = javacomponent(jPanel,[400 200 500 500],figureHandle);
    set(matlabHandlePanel,'units','normalized');

    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

    [javaHandleText matlabHandleText] = javacomponent(jTitle,[100 100 200 200],matlabHandlePanel);
    set(matlabHandleText,'units','normalized');

    I have tried this solution but it is not working :(

    Thanks in advance to everyone

    Bob

  8. Pingback: Customizing menu items part 2 | Undocumented Matlab

  9. Troykapoika says:

    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

  10. Brian says:

    Very nice. Any suggestions on maximizing/minimizing the entire MATLAB base window? I tried

    jframe = get(0,'JavaFrame');

    but it gives the following error.

    Error using hg.root/get
    The name 'JavaFrame' is not an accessible property for an instance of class 'root'.

    I’m in R2012b on Linux.

  11. Bibo says:

    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!

  12. Pingback: Anonymous

  13. Pingback: ScreenCapture utility | Undocumented Matlab

  14. Igor says:

    >> 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.

  15. AKazak says:

    MATLAB R2013a for

    FigurejFrame = get(handle(gcf),'JavaFrame');
    com.mathworks.hg.peer.FigurePeer@cdbd96

    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:

      >> FigurejFrame = get(handle(gcf),'JavaFrame')
      FigurejFrame = 
      com.mathworks.hg.peer.FigurePeer@cdbd96
    • AKazak says:

      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()

    • AKazak says:

      Is there a way to wait until figure window is fully rendered before calling setMaximized()?

    • AKazak says:

      This helped to achieve desired behavior.

      drawnow;
      pause(0.1);

      Thank you!

  16. Pingback: Rich-contents log panel | Undocumented Matlab

  17. Ayantha says:

    Hi Yair,
    I put the following code in output function of my gui

    jFrame = get(handle(gcf),'JavaFrame');
    jFrame.setMaximized(true);   % to maximize the figure

    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.

    • Ayantha says:

      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.

  18. Terence says:

    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”.”

    • Yair Altman says:

      @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.

  19. dubbel j says:

    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?

    % minimize all other figures (if any)
    a = get(0,'children');    % is this the proper way to get the figures ???
    for n = 1: numel(a);
        fig = get(figure(a(n)),'JavaFrame');
        set(fig,'minimized',1);
    end

    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:

      allFigs = findall(0,'type','figure');
      for figIdx = 1 : numel(allFigs)
          try set(get(handle(allFigs(figIdx)),'JavaFrame'), 'minimized',true); catch, end
      end
    • dubbel j says:

      Thanks, yours works.

      and figured out what my fault was:

       fig = get((a(n)),'JavaFrame');

      instead off:

       fig = get(figure(a(n)),'JavaFrame');

      so now both methods work :)

  20. Luis Vieira da Silva says:

    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:

    hfig=figure(...
      'Name','Topas' ,...
      'NumberTitle','off', ...
      'Resize','on',...
      'Units','pixels',...
      'Position',pos_fen,...
      'tag','main_fig',...
      'Menubar','none',...
      'Toolbar','none');
    drawnow;pause(0.1);
    jFrame = get(hfig,'JavaFrame');
    jFrame.setMaximized(true); 
    drawnow;pause(0.1);
    set(hfig,'Resize','off')

    Thanks in advance

    • @Luis – simply switch the order of the actions:

      set(hfig,'Resize','off');
      try
         jFrame.fHG1Client.setMaximized(true);  % HG1
      catch
         jFrame.fHG2Client.setMaximized(true);  % HG2
      end
      drawnow; pause(0.1);
    • Luis Vieira da Silva says:

      Thanks a lot, Yair, it works fine

Leave a Reply

Your email address will not be published. Required fields are marked *

*

<pre lang="matlab">
a = magic(3);
sum(a)
</pre>