Modifying Matlab’s Look-and-Feel

A couple of days ago, a reader of this blog posted a comment, asking whether it is possible to change Matlab’s Desktop color scheme, and its general UI look. Instead of providing a short answer, I will use the opportunity to answer in a full article. So this is for you, Egon :-)

Matlab’s underlying Look-and-Feel

One of Matlab’s great advantages is cross-platform compatibility. Generally speaking, Matlab applications written on Windows will work as-is on Macintosh and Linux.

Java has similar cross-platform compatibilities, but enables much greater control over the look-and-feel (L&F or PLAF) of application GUI. In a nutshell, L&Fs affect the appearance and behavior of menus, controls, color schemes etc., using a properties plug-in architecture. Java programmers can choose to use either a platform-independent L&F (called the Metal L&F), or a platform-specific L&F. The benefit of using Metal is that the application looks essentially the same on all Java-supported platforms; the drawback is that they do not look like native applications on any platform…

Metal L&F   Motif L&F   Windows L&F

Metal, Motif & Windows L&F

Matlab, whose GUI is based on Java (not surprising to readers of this website), has chosen to use a platform-specific L&F on each of the platforms on which it is supported. So, Matlab on Windows looks like a native Windows application, whereas on Macs it looks similar to Mac apps (notwithstanding the well-known X11 migration issues). Of course, this means that Windows Matlab looks and behaves differently from Mac/Linux Matlabs. Note that the differences only affect the Desktop, tools/utilities (Editor etc.) and the general L&F – it does not affect the displayed plots. In practice, the differences are visible but easily understandable.

Changing the L&F

We can get the list of available L&Fs on our system as follows (below is the list on my Windows system):

>> lafs = javax.swing.UIManager.getInstalledLookAndFeels
lafs =
javax.swing.UIManager$LookAndFeelInfo[]:
    [javax.swing.UIManager$LookAndFeelInfo]
    [javax.swing.UIManager$LookAndFeelInfo]
    [javax.swing.UIManager$LookAndFeelInfo]
    [javax.swing.UIManager$LookAndFeelInfo]
    [javax.swing.UIManager$LookAndFeelInfo]
 
>> for lafIdx = 1:length(lafs),  disp(lafs(lafIdx));  end
javax.swing.UIManager$LookAndFeelInfo[Metal javax.swing.plaf.metal.MetalLookAndFeel]
javax.swing.UIManager$LookAndFeelInfo[Nimbus com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel]
javax.swing.UIManager$LookAndFeelInfo[CDE/Motif com.sun.java.swing.plaf.motif.MotifLookAndFeel]
javax.swing.UIManager$LookAndFeelInfo[Windows com.sun.java.swing.plaf.windows.WindowsLookAndFeel]
javax.swing.UIManager$LookAndFeelInfo[Windows Classic com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel]

We can change the L&F to any of the installed L&Fs, as follows:

javax.swing.UIManager.setLookAndFeel('javax.swing.plaf.metal.MetalLookAndFeel');

Although not listed in the installed L&Fs, Matlab also enables access to a 3rd-party L&F called Plastic3D by www.jgoodies.com. Plastic3D L&F generates slick stylish GUI:

javax.swing.UIManager.setLookAndFeel('com.jgoodies.looks.plastic.Plastic3DLookAndFeel')

Plastic3D L&F

Plastic3D L&F

The JIDE class library by www.jidesoft.com, which is bundled with Matlab, and specifically its jide-common.jar file, contains a separate set of 3rd-party L&Fs: Aqua, Eclipse (Metal & Windows variants), Office2003, VSNet (Metal & Windows variants) and Xerto. Unfortunately, in Matlab releases starting around 2009, JIDE stopped including full L&F classes in jide-common.jar, and started using L&F extensions using their com.jidesoft.plaf.LookAndFeelFactory class. I have not been able to use this class properly, but readers are welcome to try (please tell me if you succeed).

External L&Fs can also be downloaded and then used in Matlab. For example: Alloy, Synthetica and many others.

The current and standard L&Fs can be retrieved by using the respective static methods javax.swing.UIManager.getLookAndFeel() and getSystemLookAndFeelClassName().

Matlab also has a utility class com.mathworks.mwswing.plaf.PlafUtils that contains static methods that query the current L&F: isPlasticLookAndFeel(), isAquaLookAndFeel(), isMetalLookAndFeel(), isMotifLookAndFeel() and isWindowsLookAndFeel(). For some reason there is no method for the new (R2010a+) Nimbus L&F.

Nimbus L&F offers great potential for a cross-platform vectorized appearance, the ability to customize/skin pretty much every aspect of the visual appearance and component behavior, replacing Swing’s Synth L&F which was used for such customizations in earlier Matlab/Java releases. Nimbus is pre-installed as a non-default L&F in Matlab R2010a (7.10) onward, because it seems that most designers who target a single platform still prefer the native L&F.

Component-specific L&F

You can also modify the L&F of specific components, not just the entire Matlab. To do this, simply modify the L&F immediately before creating your GUI component, and restore the original L&F afterward (note how you can use either the L&F class name or its class reference):

% Update the current L&F
originalLnF = javax.swing.UIManager.getLookAndFeel;  %class
newLnF = 'javax.swing.plaf.metal.MetalLookAndFeel';  %string
javax.swing.UIManager.setLookAndFeel(newLnF);
 
% Create GUI using the modified L&F
hFig = figure(...);
hComponent = uicontrol(...);
jComponent = javacomponent(...);
 
% Ensure that the controls are fully-rendered before restoring the L&F
drawnow; pause(0.05);
 
% Restore the original L&F
javax.swing.UIManager.setLookAndFeel(originalLnF);

Components can update their L&F to the current L&F using their jComponent.updateUI() method. Components that are not specifically updated by invoking their updateUI() method will retain their existing (original) L&F – the L&F which was active when the components were created or last updated.

Fine-grained L&F property control

The default settings for the L&F can be retrieved using the static method javax.swing.UIManager.getDefaults(), which returns an enumeration of the thousand or so default settings:

>> defaults = javax.swing.UIManager.getDefaults;
>> propValues = defaults.elements; propKeys = defaults.keys;
>> while propKeys.hasMoreElements
     key = propKeys.nextElement;
     value = propValues.nextElement;
     disp([char(key) ' = ' evalc('disp(value)')]);
   end
 
com.sun.java.swing.plaf.windows.WindowsLabelUI = class com.sun.java.swing.plaf.windows.WindowsLabelUI
... (~1000 other property settings)
SplitPane.dividerSize =      5
DockableFrameTitlePane.stopAutohideIcon = javax.swing.ImageIcon@1f4e4c0
FormattedTextField.caretBlinkRate =    500
Table.gridColor = javax.swing.plaf.ColorUIResource[r=128,g=128,b=128]

Specific settings can be modified by using javax.swing.UIManager.put(key,newValue).

Have you found any useful L&F or property that you are using in your application? If so, please share them in the comments section below.

Categories: Desktop, GUI, Low risk of breaking in future versions

Tags: , , ,

Bookmark and SharePrint Print

54 Responses to Modifying Matlab’s Look-and-Feel

  1. In a single word: “wow!”. Thank you very much, this helps me forward a lot, as I’m trying to get MATLAB to look a bit like a GTK application on Linux.

    But unfortunately MATLAB throws a lot of errors when changing the LAF (from the default Plastic3D to GTK+ or anything else for that matter). Some parts of the desktop actually change a bit; other parts just stay the same (looking a bit like the Frankenstein monster). When I find a solution for this, I will surely let you know.

    • Egon
      Changing the L&F does cause problems with Java exceptions being thrown. To change the entire desktop, set the L&F then invoke

      f=com.mathworks.mde.desk.MLDesktop.getInstance.getMainFrame();
      javax.swing.SwingUtilities.updateComponentTreeUI(f);

      The problem with changing the L&F may relate to missing extensions or defaults added by MATLAB at start up. For the JIDE classes that Yair mentions you need to invoke

      com.jidesoft.plaf.LookAndFeelFactory.installJideExtension();

      after setting the L&F.

  2. mattdash says:

    This is very cool. Plastic3d looks great, but nimbus gives me all kinds of exceptions whenever i click something and makes the matlab desktop completely unusable. But it seems to work with my GUI… though it has some transparency issues with the buttons so I think i’ll avoid it altogether for now… hopefully it gets better support in the future. If anyone gets it fully working i’d love to hear about it.

    For changing the l&f of a single component… if I do:

    originalLnF = javax.swing.UIManager.getLookAndFeel; 
    newLnF = 'javax.swing.plaf.metal.MetalLookAndFeel'; 
    javax.swing.UIManager.setLookAndFeel(newLnF);
     
    hFig = figure;
    hComponent = uicontrol('style','pushbutton','position',[50 80 100 20])
    jComponent = javacomponent(javax.swing.JButton,[50 50 100 20]);
     
    javax.swing.UIManager.setLookAndFeel(originalLnF);

    I get metal for the jbutton and my default l&f for the uicontrol button, which i’m guessing is how it’s supposed to work (as opposed to metal for both). But if i run just the first 3 lines, it screws up my matlab desktop too… is the trick to change it back to the default before calling drawnow?

    • @Matt – the issue you see with the uicontrol button is simply due to the fact that the button has not completed its onscreen rendering before the originalLnF has been returned (see my EDT article).

      To fix this, simply place a drawnow command before you restore the originalLnF. You will then also be able to see what a Metal-based figure and menu-bar looks like.

    • mattdash says:

      Ah, thanks, I see how that works now. But I’m still confused about when using javax.swing.UIManager.setLookAndFeel affects the matlab desktop and when it only affects an individual figure. I was expecting to see the desktop flash to metal when drawnow was called, then flash back to the default. Based on the behavior described above I’m inferring that drawnow only affects figure windows and not the main desktop, which doesnt quickly flash to metal because setLookAndFeel() is called again to switch it back to the default look and feel before it gets a chance to update its appearance. Does that sound correct?

    • @Matt – yes, that is correct. To force a repaint of the main desktop, you can do the following (based on Malcolm’s comment above):

      f=com.mathworks.mde.desk.MLDesktop.getInstance.getMainFrame();
      javax.swing.SwingUtilities.updateComponentTreeUI(f);
      f.repaint;
  3. Sherif Elnabarawy says:

    I can’t import third party L&F in matlab ! it keeps telling me the same error when trying to set another L&F other than the few default ones installed , anybody can help ?

    ??? Java exception occurred:
    java.lang.ClassNotFoundException: com.birosoft.liquid.LiquidLookAndFeel
    	at java.net.URLClassLoader$1.run(Unknown Source)
    	at java.security.AccessController.doPrivileged(Native Method)
    	at java.net.URLClassLoader.findClass(Unknown Source)
    	at java.lang.ClassLoader.loadClass(Unknown Source)
    	at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    	at java.lang.ClassLoader.loadClass(Unknown Source)
    	at java.lang.ClassLoader.loadClassInternal(Unknown Source)
    	at java.lang.Class.forName0(Native Method)
    	at java.lang.Class.forName(Unknown Source)
    	at javax.swing.SwingUtilities.loadSystemClass(Unknown Source)
    	at javax.swing.UIManager.setLookAndFeel(Unknown Source)
    • @Sherif – try to add the L&F class/JAR files to your static Java classpath (edit classpath.txt), then restart Matlab and retest

    • Sherif Elnabarawy says:

      thx Yair :) it worked , but is there another way to change the L&F in runtime and build a GUI and then restore the default L&F ?
      it didn’t work when i added the JAR files to the dynamic classpath !

  4. Sherif Elnabarawy says:

    i want to add the files to the dynamic classpath bec. i want to add them by code automatically in the beginning of the m file not manually by the user !

    • @Sherif – Matlab’s dynamic Java classpath is known to cause problems in all sorts of Java-related aspects. You can try using the dynamic classpath, but if you encounter errors your best choice is to update the static classpath. You can add Matlab code that does this automatically (better ask for user confirmation before you do this, of course)

    • Sherif Elnabarawy says:

      thx again :) .. now it works well ..
      but again as usual another problem , what about standalone compilation ?!
      i couldn’t even run the compiled file :S
      any ideas ?!
      Thanks a lot again :)

    • @Sherif – I suggest a two-step debugging process:
      1. Remove the L&F code from your code and check that it now runs properly – if not then your problem probably lies elsewhere
      2. Add the L&F JARs to the compiler’s external files section

      – Yair

  5. Dmitry says:

    Hi, thanks for very interesting article !
    But is there any solution if I would like to execute Matlab with desired LAF from console ?
    Something like on passing parameter swing.defaultlaf=bla.bla.bla to the Java machine that runs Matlab GUI ?

    • @Dmitry – yes – the commands mentioned in the first section of this article can be executed from the Matlab Command Prompt (console).

      -Yair

    • Dmitry says:

      Yair, Thank for reply, but it seems I asked it not entirely correct :)
      I meant how could I start matlab from Linux console with desired predefined LAF ?
      Like standalone Java application can be started with different LAF when you execute it as

      java -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel App

      I’m not sure that it’s possible at all, because it seems matlab uses some native executor utility for starting.

    • @Dima – as far as I know you cannot pass JVM startup options in the Matlab command line
      – Yair

  6. Tal Kenig says:

    Hi Yair.
    I am trying to make my existing Matlab GUI real pretty.
    I am currently experimenting with the LAFs, which is a great improvement, especially since I am using the old uitable. However, as mattdash commented above, the uicontrols do not use the applied LAF. Some of the colors are changed, but, for example, if I compare the uitable scrollbar to the uicontrol scrollbar under the Metal LAF, then the uicontrol scrollbar does not look as nice with the gradient color. Is there any way of making the standard Matlab uicontrols use the new LAF?

    • @Tal – read my reply to Matt’s comment above, particularly the part about using drawnow
      -Yair

    • Tal Kenig says:

      Yair, my situation is not the same, as I never modify the LAF back. I keep it on metal.
      I tried the following:

      javax.swing.UIManager.setLookAndFeel('javax.swing.plaf.metal.MetalLookAndFeel');
      figure;
      hComponent = uicontrol('style','pushbutton','position',[50 50 100 20]);
      jComponent = javacomponent(javax.swing.JButton,[200 50 100 20]);

      The jComponent is really nice with the gradient coloring. The Matlab uicontrol looks plain gray. However, while pressed it does change its color to blue, like the jComponent. So, I get some kind of hybrid behavior. Is there any way around it without converting all of my uicontrols to javacomponents?

      Tal.

    • @Tal – This was an interesting question. I almost gave up…

      Aparently, Matlab uses the non-PLAF-compliant java.awt.Color for its uicontrols’ Background property, rather the more standard PLAF-compliant javax.swing.plaf.ColorUIResource.

      To fix this directly on the uicontrol, use my FindJObj utility as follows:

      jhComponent = findjobj(hComponent);
      oldBgColor = jhComponent.getBackground;
      newBgColor = javax.swing.plaf.ColorUIResource(oldBgColor);
      jhComponent.setBackground(newBgColor);
      jhComponent.repaint;  % force a redraw

      BTW, the same happens with the Font property, which uses java.awt.Font rather than javax.swing.plaf.FontUIResource.

      -Yair

    • Tal Kenig says:

      Yair,
      Many thanks for the educated answer.
      I guess i will create a function that converts all UI colors to plaf colors.
      I still have two related questions:
      1. The findjobj() utility (which is wonderful, btw) returns an empty result when I use it as follows:

      jhComponent = findjobj(hComponent);

      However, if I use it to hunt objects containing specific attributes, such as:

      jhComponent = findjobj('property', {'Text', 'push me'});

      It returns exactly the handle I want.
      However, searching for a handle according to the string attribute is not very robust.
      Is it possible to use the Tag attribute to do so (I tried ‘Tag’ and ‘Name’, which did not work), or another “unique” attribute?

      2. I used the PLAF to modify the appearance of a uitable (I am using your createTable() on Matlab 7.04), which works great, except for the header.
      I tried, for example:

      javax.swing.UIManager.put('TableHeader.background', javax.swing.plaf.ColorUIResource(1,1,1));

      But the table header is left gray.
      However,

      javax.swing.UIManager.put('Table.background', javax.swing.plaf.ColorUIResource(1,1,1));

      Does change the table background.
      So, what am I doing wrong here.
      Many thanks again,
      Tal.

    • @Tal –
      1. Perhaps you forgot to add a drawnow before findjobj? If the control is not fully rendered when you run findjobj, no wonder you get []. Alternately, you can use the ‘class’ property.
      2. I don’t know which property (if any) affects the table header. You can also try to use HTML and CSS backgrounds. I’ll show an example of this in tomorrow’s post

      -Yair

    • Tal Kenig says:

      Yair,
      Thanks again for your comments and replies.
      Regarding the drawnow() – this was not the problem, it is probably my Matlab version.
      Anyway, I wrote a function that applies the PLAF colors to all uicontrols within a figure, using the class option of findjobj, as you suggested.
      I was surprised to find out that in each class, one handle is not returned.
      So, I debugged and I believe you have a bug:
      Line 646 reads:

      if length(foundIdx) > 1 && isequal(handles(1).java, handles(2).getParent)

      Where IMHO, it should read

      if length(foundIdx) > 1 && isequal(handles(foundIdx(1)).java, handles(foundIdx(2)).getParent)

      So here – you got something back from me…
      Many thanks (again)
      Tal.

    • Tal Kenig says:

      Well, Yair
      Thanks to you, I am almost done with my UI.
      The only uicontrol which still defies the PLAF is the slider uicontrol.
      It takes the PLAF colors, but the color is flat not the pretty gradient coloring of the metal LAF.
      Is there any way of forcing it to adhere to the PLAF, or should I replace it with a jscrollbar?

      Tal.

    • @Tal – I always prefer to use JScrollBars rather than the standard slider uicontrol. JScrollBar not only looks visually more appealing than the Matlab slider uicontrol (which looks so Windows95 1990’s-style in my opinion), but also has a more consistent look-and-feel with other Matlab uicontrols, since they are all based more closely on Swing.

      Not to mention the fact that it’s much easier to get to the underlying extra Java functionality (continuous slider callbacks, for example) with a plain-ol’ JScrollBar.

      -Yair

  7. Tarun Jhamnani says:

    Hi Yair,

    I am new to all this stuff. Fantastic work!.
    I know my problem is not completely relevant to the discussion going on here but this is what i want to do.
    I am trying to customize matlab tollbar or simulink model window toolbar with my own icons but not able to do so.
    Please can you help me with this.
    Thanks

  8. Tarun Jhamnani says:

    Hi Yair,
    I actually wanted to add few icons in MATLAb main Frame window or Simulink Model Window not in Figure window.
    Shortcut of certain application.
    Is there any way to do this?

  9. ZOMGxuan says:

    Hey, thanks for this article, it was a great help!! MATLAB’s background color not being the same as the rest of my desktop really irked me, and I had to fix it. Changing the theme to the system look and feel (GTK for me) didn’t work out well, as a lot of exceptions started being thrown, and the desktop didn’t get repainted properly, with lots of glitches and artifacts, so what I did was use the code in the “Fine grained L&F property control” section to scan for all properties that matched the background color I didn’t want, then change them to the background color I wanted. It worked!
    The problem now is that these settings don’t get saved after I close MATLAB. Are they supposed to be saved, or do I have to write a start-up script so that the changes get made every time I start MATLAB?

    • @ZOMGxuan – I’m afraid that you need to write a small start-up script that you can call from within your startup.m file so that it automatically gets executed whenever you start Matlab. It would be nice if you could post this script here in a comment. If it’s too large, you can email it to me and I’ll upload it to this website and post a link here.

    • ZOMGxuan says:

      The script isn’t very long, so I’ll just post it here.

      % Set old and new background color
      oldbgcolor = javax.swing.plaf.ColorUIResource(236/255,233/255,216/255);
      newbgcolor = javax.swing.plaf.ColorUIResource(237/255,237/255,237/255);
       
      % Get default UI properties
      defaults = javax.swing.UIManager.getDefaults;
      propValues = defaults.elements;
      propKeys = defaults.keys;
      while propKeys.hasMoreElements
           key = propKeys.nextElement;
           value = propValues.nextElement;
       
           % Check if value equal to old bg color and replace with new bg color
           if value == oldbgcolor
              javax.swing.UIManager.put(key,newbgcolor);
           end
      end
       
      % Repaint desktop
      f=com.mathworks.mde.desk.MLDesktop.getInstance.getMainFrame();
      javax.swing.SwingUtilities.updateComponentTreeUI(f);
       
      % Clean up
      clear oldbgcolor newbgcolor defaults propKeys propValues key value f;

      Here, my old background color in (r,g,b) is (236, 233, 216), which is the default for the Metal look & feel (and Plastic3D as well, I think). My new background color is (237, 237, 237), which is the same background color that my GTK theme uses. Replace the colors as appropriate. To find out the default background color for a particular look & feel, I had to list out all the key value pairs of UI properties, and look for a color that kept repeating that matched the background color I was seeing (you can check using a color picker online or something). In general, this color should be the same as the value of the MenuBar.background property.

    • @ZOMGxuan – thanks. You might also consider adding the following items to your startup script:

      set(0,'DefaultFigureColor',[237/255, 237/255, 237/255]);
      set(0,'DefaultUicontrolBackgroundColor',[237/255, 237/255, 237/255]);
    • ZOMGxuan says:

      Thanks! Oh, I forgot to mention that running the script causes a bunch of Java exceptions to be thrown, but it doesn’t seem to have any negative impact after that.

  10. Alp says:

    Hi Yair,

    Thanks for the article. When i use findjobj command in GUI(designed with guide) uitabs not shown. I tried to handle GUI components in opening function but it returns empty array even i use pause or drawnow commands. When i put findjobj in another function it captures the handle but in this case uitabs are not shown. Is there any way to correct this?

    Best Wishes,

    • @Alp – I do not have an immediate answer. Solving this will require looking at your application code. I will be happy to help you with this, for a fee to compensate me for my time and expertise. If you are interested, please contact me offline using the email link at the top-right of this page.

  11. Keith says:

    I’m trying to get a gui (figure window with uicontrols and uipanel; I’m turning off the toolbar and menubar for my figure window so I don’t need those) on an apple computers to look “plastic” (i.e. like matlab linux), the reason is to get the spacing to be the same (words that fit in the linux/plastic don’t fit in the apple because they have a check etc in them and I can’t change the colors of some of the apple uicontrols). When I try to reset everything I get all kinds or java exceptions, so I don’t want to change the matlab desktop. Does anyone know the minimum amount of stuff I need to just change the appearance of the uicontrols and uipanels to plastic?

    Which of the following (I grabbed all the ones with com.jgoodies in them plus any others) would I need? (would I need menu items for popup menus or just the menu bar?)

    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticTabbedPaneUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticTabbedPaneUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticPopupMenuUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticPopupMenuUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticTreeUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticTreeUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticButtonUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticButtonUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticMenuUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticMenuUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticTreeUI','class com.jgoodies.looks.plastic.PlasticTreeUI');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticSeparatorUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticSeparatorUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticButtonUI','class com.jgoodies.looks.plastic.PlasticButtonUI');
    javax.swing.UIManager.put('com.jgoodies.looks.common.ExtBasicRadioButtonMenuItemUI','class com.jgoodies.looks.common.ExtBasicRadioButtonMenuItemUI');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticMenuBarUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticMenuBarUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticTextAreaUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticTextAreaUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticOptionPaneUI','class com.jgoodies.looks.plastic.PlasticOptionPaneUI');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticSplitPaneUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticSplitPaneUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticToggleButtonUI','class com.jgoodies.looks.plastic.PlasticToggleButtonUI');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticOptionPaneUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticOptionPaneUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticScrollBarUI','class com.jgoodies.looks.plastic.PlasticScrollBarUI');
    javax.swing.UIManager.put('com.jgoodies.looks.common.ExtBasicCheckBoxMenuItemUI','class com.jgoodies.looks.common.ExtBasicCheckBoxMenuItemUI');
    javax.swing.UIManager.put('Plastic.theme','com.jgoodies.looks.plastic.theme.ExperienceBlue@b0ffb5a');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticComboBoxUI','class com.jgoodies.looks.plastic.PlasticComboBoxUI');
    javax.swing.UIManager.put('class com.jgoodies.looks.common.ExtBasicCheckBoxMenuItemUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.common.ExtBasicCheckBoxMenuItemUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticSplitPaneUI','class com.jgoodies.looks.plastic.PlasticSplitPaneUI');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticToggleButtonUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticToggleButtonUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticMenuBarUI','class com.jgoodies.looks.plastic.PlasticMenuBarUI');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticScrollBarUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticScrollBarUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticPopupMenuUI','class com.jgoodies.looks.plastic.PlasticPopupMenuUI');
    javax.swing.UIManager.put('com.jgoodies.looks.common.ExtBasicPopupMenuSeparatorUI','class com.jgoodies.looks.common.ExtBasicPopupMenuSeparatorUI');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticTextAreaUI','class com.jgoodies.looks.plastic.PlasticTextAreaUI');
    javax.swing.UIManager.put('class com.jgoodies.looks.common.ExtBasicRadioButtonMenuItemUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.common.ExtBasicRadioButtonMenuItemUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticMenuUI','class com.jgoodies.looks.plastic.PlasticMenuUI');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticTabbedPaneUI','class com.jgoodies.looks.plastic.PlasticTabbedPaneUI');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticSeparatorUI','class com.jgoodies.looks.plastic.PlasticSeparatorUI');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticToolBarUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticToolBarUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticComboBoxUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticComboBoxUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticToolBarUI','class com.jgoodies.looks.plastic.PlasticToolBarUI');
    javax.swing.UIManager.put('class com.jgoodies.looks.common.ExtBasicPopupMenuSeparatorUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.common.ExtBasicPopupMenuSeparatorUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('com.jgoodies.looks.plastic.PlasticScrollPaneUI','class com.jgoodies.looks.plastic.PlasticScrollPaneUI');
    javax.swing.UIManager.put('class com.jgoodies.looks.plastic.PlasticScrollPaneUI','public static javax.swing.plaf.ComponentUI com.jgoodies.looks.plastic.PlasticScrollPaneUI.createUI(javax.swing.JComponent)');
    javax.swing.UIManager.put('CheckBox.icon','com.jgoodies.looks.plastic.PlasticIconFactory$CheckBoxIcon@54b4a622');
    javax.swing.UIManager.put('PopupMenu.border','com.jgoodies.looks.plastic.PlasticBorders$PopupMenuBorder@7fec1bd7');
    javax.swing.UIManager.put('SeparatorUI','com.jgoodies.looks.plastic.PlasticSeparatorUI');
    javax.swing.UIManager.put('Tree.collapsedIcon','com.jgoodies.looks.plastic.PlasticIconFactory$CollapsedTreeIcon@4ef5af4e');
    javax.swing.UIManager.put('CheckBoxMenuItemUI','com.jgoodies.looks.common.ExtBasicCheckBoxMenuItemUI');
    javax.swing.UIManager.put('ToggleButtonUI','com.jgoodies.looks.plastic.PlasticToggleButtonUI');
    javax.swing.UIManager.put('MenuItem.checkIcon','com.jgoodies.looks.common.MinimumSizedIcon@65e559ca');
    javax.swing.UIManager.put('Tree.expandedIcon','com.jgoodies.looks.plastic.PlasticIconFactory$ExpandedTreeIcon@512846f7');
    javax.swing.UIManager.put('PopupMenuUI','com.jgoodies.looks.plastic.PlasticPopupMenuUI');
    javax.swing.UIManager.put('ScrollBarUI','com.jgoodies.looks.plastic.PlasticScrollBarUI');
    javax.swing.UIManager.put('TabbedPaneUI','com.jgoodies.looks.plastic.PlasticTabbedPaneUI');
    javax.swing.UIManager.put('CheckBoxMenuItem.checkIcon','com.jgoodies.looks.plastic.PlasticIconFactory$CheckBoxMenuItemIcon@5234c361');
    javax.swing.UIManager.put('ScrollPane.etchedBorder','com.jgoodies.looks.plastic.PlasticBorders$ScrollPaneBorder@35ed0934');
    javax.swing.UIManager.put('ToolBar.border','com.jgoodies.looks.plastic.PlasticBorders$ThinRaisedBorder@666b51eb');
    javax.swing.UIManager.put('TreeUI','com.jgoodies.looks.plastic.PlasticTreeUI');
    javax.swing.UIManager.put('ToolBarUI','com.jgoodies.looks.plastic.PlasticToolBarUI');
    javax.swing.UIManager.put('ButtonUI','com.jgoodies.looks.plastic.PlasticButtonUI');
    javax.swing.UIManager.put('PopupMenu.noMarginBorder','com.jgoodies.looks.plastic.PlasticBorders$NoMarginPopupMenuBorder@7f72f508');
    javax.swing.UIManager.put('RadioButtonMenuItemUI','com.jgoodies.looks.common.ExtBasicRadioButtonMenuItemUI');
    javax.swing.UIManager.put('ToolBarSeparatorUI','com.jgoodies.looks.plastic.PlasticToolBarSeparatorUI');
    javax.swing.UIManager.put('MenuUI','com.jgoodies.looks.plastic.PlasticMenuUI');
    javax.swing.UIManager.put('SplitPaneUI','com.jgoodies.looks.plastic.PlasticSplitPaneUI');
    javax.swing.UIManager.put('SpinnerUI','com.jgoodies.looks.plastic.PlasticSpinnerUI');
    javax.swing.UIManager.put('OptionPaneUI','com.jgoodies.looks.plastic.PlasticOptionPaneUI');
    javax.swing.UIManager.put('Table.scrollPaneBorder','com.jgoodies.looks.plastic.PlasticBorders$ScrollPaneBorder@35ed0934');
    javax.swing.UIManager.put('InternalFrameUI','com.jgoodies.looks.plastic.PlasticInternalFrameUI');
    javax.swing.UIManager.put('MenuItemUI','com.jgoodies.looks.common.ExtBasicMenuItemUI');
    javax.swing.UIManager.put('ComboBoxUI','com.jgoodies.looks.plastic.PlasticComboBoxUI');
    javax.swing.UIManager.put('TextAreaUI','com.jgoodies.looks.plastic.PlasticTextAreaUI');
    javax.swing.UIManager.put('MenuBarUI','com.jgoodies.looks.plastic.PlasticMenuBarUI');
    javax.swing.UIManager.put('ScrollPane.border','com.jgoodies.looks.plastic.PlasticBorders$ScrollPaneBorder@35ed0934');
    javax.swing.UIManager.put('PopupMenuSeparatorUI','com.jgoodies.looks.common.ExtBasicPopupMenuSeparatorUI');
    javax.swing.UIManager.put('RadioButtonMenuItem.checkIcon','com.jgoodies.looks.plastic.PlasticIconFactory$RadioButtonMenuItemIcon@457ed5ff');
    javax.swing.UIManager.put('ScrollPaneUI','com.jgoodies.looks.plastic.PlasticScrollPaneUI');
    javax.swing.UIManager.put('Spinner.border','com.jgoodies.looks.plastic.PlasticBorders$Flush3DBorder@2193f2af');
    javax.swing.UIManager.put('Menu.arrowIcon','com.jgoodies.looks.plastic.PlasticIconFactory$MenuArrowIcon@2e50845b');

    • @Keith – As I mentioned in the main article, you can modify the L&F of specific components, without affecting the Matlab Desktop. To do this, simply modify the L&F immediately before creating your GUI component, and restore the original L&F afterward (note how you can use either the L&F class name or its class reference):

      % Update the current L&F
      originalLnF = javax.swing.UIManager.getLookAndFeel;  %class
      newLnF = 'javax.swing.plaf.metal.MetalLookAndFeel';  %string
      javax.swing.UIManager.setLookAndFeel(newLnF);
       
      % Create GUI using the modified L&F
      hFig = figure(...);
      hComponent = uicontrol(...);
      jComponent = javacomponent(...);
       
      % Restore the original L&F
      javax.swing.UIManager.setLookAndFeel(originalLnF);

      If you modify the main L&F’s property using javax.swing.UIManager.put() as you attempted, it would also affect the corresponding control used in the Desktop, so this will not really help you, even if you do find the specific property to update.

    • Keith says:

      @Yair I tried that, testing on linux setting the L&F to metal creating the gui objects and then switching back to plastic had things look like plastic, I think that the even though the call to create the uicontrols etc went out first, there was a time delay and they weren’t being created until after it switched back to plastic, will drawnow force gui object to be drawn?

    • yes – add a pause(0.1) if drawnow is not enough

  12. Jack says:

    Hey guys, if you’re running Xubuntu like I am with the greybird GTK2 theme, you probably hate that piss-yellow background color.

    Solution: place this into a file called startup.m in /usr/local/matlab/R2011a/toolbox/startup.m (if that’s where matlab is installed, that is) so that this executes on startup.

    % Set old and new background color
    oldbgcolor = javax.swing.plaf.ColorUIResource(236/255,233/255,216/255);
    newbgcolor = javax.swing.plaf.ColorUIResource(206/255,206/255,206/255);
     
    % Get default UI properties
    defaults = javax.swing.UIManager.getDefaults;
    propValues = defaults.elements;
    propKeys = defaults.keys;
    while propKeys.hasMoreElements
         key = propKeys.nextElement;
         value = propValues.nextElement;
     
         % Check if value equal to old bg color and replace with new bg color
         if value == oldbgcolor
            javax.swing.UIManager.put(key,newbgcolor);
         end
    end
     
    set(0,'DefaultFigureColor',[206/255, 206/255, 206/255]);
    set(0,'DefaultUicontrolBackgroundColor',[206/255, 206/255, 206/255]);
    pause(1)
     
    % Repaint desktop
    warning off MATLAB:Java:GenericException 
    f=com.mathworks.mde.desk.MLDesktop.getInstance.getMainFrame();
    javax.swing.SwingUtilities.updateComponentTreeUI(f);
    f.repaint;
     
    % Clean up
    clear oldbgcolor newbgcolor defaults propKeys propValues key value f ans exc;
    warning on MATLAB:Java:GenericException
    clc

    Kudos to both Yair and ZOMGxuan, thank you both for a more professional looking matlab 😀

  13. Peter says:

    Hi Yair, this is very helpful.

    On Mac OS 10.8 (and probably 10.7) the slider component no longer has buttons for moving a single increment. This is problematic for some of our older GUIs. Does anyone know a specific property setting that can be tweaked to get back the slider buttons, or should I just use metal for the whole component?

    To people trying to use GTK LaF, I have some experience with this outside of Matlab and I have found that the GTK LaF has inconsistent behavior compared to others. E.g., user actions that trigger certain callbacks consistently in windows, mac, and metal LaF do not trigger those same callbacks in GTK LaF. This is within a pretty big and messy GUI application, so it’s possible if you stick to less convoluted triggerings you will be fine, but something to be aware of.

    • Peter says:

      Consulting your excellent book, sounds like I may need to use findjobj or create the slider directly from Java? Correct me if I’m wrong. Otherwise I think I’m going to punt and just set to Metal when creating these sliders. Any way to detect what version of Aqua LaF is available so I know whether the revert to Metal is necessary?

    • @Peter – there is no standard way to get the plaf’s version. In some cases it is included in the plaf’s Description, in others it is a property in the Defaults map, in others it is not available at all.

      Re your earlier question on the slider, you could sift through the plaf’s Defaults map, to see whether there is a corresponding property that you can set. You can use Malcolm Lidierth’s excellent MUtilities package to help you with all this.

  14. clktmr says:

    another possibility to change the lookAndFeel is to remove the jgoodies-looks.jar in /usr/local/MATLAB/R2012a/java/jarext and create a symbolic link to the one that is shipped with your distribution:
    sudo ln -s /usr/share/java/jgoodies-looks.jar ./jgoodies-looks.jar

  15. Pingback: JTattoo look-and-feel demo | Undocumented Matlab

  16. Pingback: Can I get Matlab use GTK theme? | Ubuntu InfoUbuntu Info

  17. Pingback: Can I get Matlab use GTK theme? - Tech Forum Network

  18. Pingback: Undocumented button highlighting | Undocumented Matlab

  19. Aim says:

    Hi Yair,

    with the recent upgrade of DEPLOYTOOL, now it is possible to compile the source code in executable file with custom icon.
    Is it possible to set the icon also by compiling the source code by using MCC command?

    Thanks for the answer and for your amazing books

    • @AIM (AIM-120?) – I do not have access to the latest Matlab Compiler, so I’m afraid that I cannot answer this… I suggest that you ask this of MathWorks support.

  20. Kaveh says:

    Hi there!
    Thanks for the article.

    I’m trying to modify L&F style in one of my GUIs, but I’m running into a weird problem. Here’s the problem:
    I update L&F early in my code (before creating the main layout of my GUI), and later on I restore the original one according to what you have suggested in the article. When I run the code for the time, it works perfectly, but if I try to use another L&F style and run the code for the second time, the original L&F style won’t be restored. Do you have any suggestion for fixing that problem?

Leave a Reply

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