- Undocumented Matlab - https://undocumentedmatlab.com -

Button customization

Posted By Yair Altman On April 24, 2009 | 33 Comments

Matlab’s button uicontrols (pushbutton and togglebutton) are basically wrappers for a Java Swing JButton [1] object.
This will be the first in a series of posts showing how Matlab uicontrols can be customized in ways that you may never have thought possible.
Probably the simplest undocumented customization is the control’s acceptance of HTML and CSS Strings [2]:

tooltip = '<html>HTML-aware<br><b>tooltips</b><br><i>supported';
labelTop= '<HTML><center><FONT color="red">Hello</Font> <b>world</b>';
labelBot=['<div style="font-family:impact;color:green"><i>What a</i>'...
          ' <Font color="blue" face="Comic Sans MS">nice day!'];
set(hButton, 'tooltip',tooltip, 'string',[labelTop '<br>' labelBot]);

Button with HTML label and tooltip
Button with HTML label and tooltip

For more powerful customization, we need to access the control’s underlying JList object. We do this by using my FindJObj submission on the File Exchange [3] (which was explained here [4]):

>> jButton = java(findjobj(hButton))
jButton =
com.mathworks.hg.peer.PushButtonPeer$1[,0,0,...]

Now that we have the jButton Java object reference, we can use get and set just like any Matlab handle. To see the list of all available properties, methods and callbacks, we can use my UIINSPECT submission on the File Exchange [5], or use Matlab’s built-in methodsview function.
This post is too short to present all the numerous ways in which the control can be customized with the Java properties and methods. Let’s list some of the more interesting properties:

  • Border – specified the border frame around the button, which is responsible for its 3D appearance. It can be modified to anything from a simple colored borderline to a recurring icon-pattern, as shown here [6]. If set to [] then the button achieves a flat appearance, which can be useful for displaying click-able labels. For example, the blog hyperlink at the bottom of the FindJObj window is a simple button with no border, an HTML label and a callback that opens this blog webpage using the built-in web function:
    Button appearing as a hyperlink label
    Button appearing as a hyperlink label
  • Cursor – this can be used to set a control-specific cursor. For example, in the hyperlink button above, the cursor was set to: java.awt.Cursor(java.awt.Cursor.HAND_CURSOR). In another post I’ll show how to set a custom cursor, like the following Matlab icon:
    Custom cursor
    Custom cursor

    Note: This feature only works on R2013a and earlier; custom cursors are ignored in Matlab R2013b and newer (see here [7]).
  • DisplayedMnemonicIndex – (default=-1) indicates the character position within the text label where the Mnemonic (i.e, keyboard shortcut) should be displayed. Associated property Mnemonic (default=0) indicates the ASCII code of the mnemonic. In the following case, DisplayedMnemonicIndex=3 (remember that Java indices start at 0) and Mnemonic=73 (=’r’):
    Button With mnemonic
    Button With mnemonic
  • Margin, VerticalAlignment, HorizontalAlignment – these properties enable setting the label contents with respect to its borders. For example:
    Top-left with 8-pixel top margin
    Top-left with 8-pixel top margin
  • Icon, DisabledIcon, DisabledSelectedIcon, PressedIcon, RolloverIcon, RolloverSelectedIcon, SelectedIcon – these icons may be set to present a different appearance depending on component state. Associated property IconTextGap (default=4) determines the gap in pixels between the icon and the button text label. Associated properties HorizontalTextPosition and VerticalTextPosition specify the label text’s alignment relative to the label icon. These two properties accept the same SwingConstants values as HorizontalAlignment and VerticalAlignment above. For example, let’s display an icon to the right and upward of the text:
    
    myIcon = fullfile(matlabroot,'/toolbox/matlab/icons/warning.gif');
    jButton.setIcon(javax.swing.ImageIcon(myIcon));
    jButton.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
    jButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    

    Button with text and icon
    Button with text and icon
  • MultiClickThreshhold – (default=0) sets the number of milliseconds between subsequent processed user mouse clicks on the button. Any clicks that occur within the specified number (e.g., fast double-clicks) will be considered by the component as only a single click. The default value of 0 means that all clicks will be processed separately, which is often undesirable in GUI applications. Remember that the value is in milliseconds, not seconds.
  • FlyOverAppearance – boolean flag (default=false); if set, the button appearance is changed to a flat (2D) appearance with a special 3D border effect displayed on mouse hover. This appearance is useful for toolbar buttons, and is an extension by Matlab’s button implementation (does not exist in the standard Swing class).

There are quite a few other useful properties, methods (for example, jButton.doClick() to programmatically click a button) and even some 30 callbacks, detailed in a separate post [8]. The list above is by no way comprehensive – I hope it whet your appetites for exploration using FindJObj and UIINSPECT – it’s a fun ride and the GUI rewards are worth the effort!
Please let me know of any nice customizations in your Matlab applications. Leave a comment below or drop me an email.

Categories: GUI, High risk of breaking in future versions, Icons, Java, UI controls


33 Comments (Open | Close)

33 Comments To "Button customization"

#1 Pingback By Undocumented MATLAB Tips by Yair Altman | blinkdagger On April 28, 2009 @ 18:26

[…] covered. I find the contrast quite refreshing. For instance, in Yair’s most recent post on Button Customization, he discusses the intricacies of what one can accomplish with a simple push button. So if […]

#2 Comment By neurostu On May 12, 2009 @ 13:05

I’m having some problems with setting an ImageIcon on the buttons, here is my code:
[15]

I create a jButton object for each of the three uicontrol buttons I create but whenever I set the icon on one of the three buttons it always sets it to the first of the three.

I’m running matlab 2008b

#3 Comment By Peter Steinberg On June 22, 2011 @ 14:43

This is all very useful. Thanks! One question: do you know how to underline text in a static text element?

#4 Comment By Yair Altman On June 22, 2011 @ 14:57

@Peter – I assume you meant the uicontrol text control, not the axis-based label generated by text (for this you can use tex-formatting).

For text uicontrol customizations, read [16].

#5 Comment By Karthik S On April 27, 2012 @ 12:30

These are excellent tips on customization! How do I automatically resize an icon in the button?

#6 Comment By Yair Altman On April 28, 2012 @ 10:09

@Karthik, you can place a [17] on the button’s Position property and in its callback you could resize the button’s contents.

#7 Comment By Karthik S On April 30, 2012 @ 07:50

Thank Yair. The button is on a GUI. I wanted the image on the button to resize when I resize the GUI. The button resizes automatically with the GUI, but, when I place a listener like you suggested, the callback isnt being executed.

#8 Comment By Yair Altman On April 30, 2012 @ 07:54

@Karthik – simply use your figure’s ResizeFcn property in order to catch GUI resize events

#9 Comment By Karthik S On April 30, 2012 @ 09:21

I’m using the auto Resize option on the main GUI, so I dont think I have explicit control of the GUI’s resizefcn

#10 Comment By Yair Altman On April 30, 2012 @ 09:25

@Karthik – of course you do: every Matlab figure has the ResizeFcn property. It doesn’t matter how you resize the figure, this callback will get invoked.

#11 Comment By vanilou On June 27, 2012 @ 02:23

Hi ! I would like to do a round pushbutton, is that possible in matlab ?

#12 Comment By Yair Altman On June 27, 2012 @ 02:27

Not easily. The simplest way would be to draw a rounded patch that looks like a button on an invisible axes and then monitor click events on this patch.

#13 Comment By vanilou On June 27, 2012 @ 05:25

Ok, thank you !

#14 Comment By Raphael On August 27, 2012 @ 18:37

thanks a lot for these tips Yair !

I was working on adding icons to GUI buttons today and ran into 2 troubles:
– the javax.swing.ImageIcon seems to keep the image in memory. In case of a second execution with the same file path, it would use the copy in memory and not the newer version. Is there a way to force the reloading of the file ?
– Once an icon is used in a gui, none of the properties for the text alignment work anymore. Left, Right, Center: everything is centered and the gui parameters are unresponsive.

Did I forgot something or is that a bug that you’re aware of ?

thanks
Raphael

#15 Comment By Yair Altman On August 28, 2012 @ 00:00

@Raphael – ImageIcon caches files so it will not reload the same image twice. There are alternatives ( [18]) that you can use instead of ImageIcon. This is really a pure Java question for which you should search on pure Java forums.

Regarding alignment, you can use the HorizontalAlinment(), HorizontalTextPosition() methods (and similarly for Vertical*) of the JButton reference. It’s covered in detail in Section 6.1 of my [19].

#16 Comment By Aaron On April 5, 2013 @ 15:38

Hello, Yair.

I’ve frequented your site a lot in the last few months as I’ve gotten into GUI programming in MATLAB. I recently ran into a little problem that I’m trying to work out.

I am trying to create a GUI button with one line of text that is partially left-aligned and partially right-aligned. I was hoping to use CSS within the string field as such:

h = uicontrol('Style','PushButton','Position',[20 20 150 40]);
set(h,'String','

Left Text

Right Text

'); % I know the closing tags are not necessary

However, this creates two separate lines (which are both centered in the push button) despite the float command.

Is it possible to do this at all using HTML/CSS? Or is a JAVA solution needed or, even still, possible?

#17 Comment By Yair Altman On April 6, 2013 @ 09:56

@Aaron – Unfortunately, Java Swing’s support for CSS is not complete. I [20] a similar question on StackOverflow back in 2011 when I saw that <div> splits the text into two lines instead of continuing on the same line. The solution in that case was to use <span> rather than <div>. It might work for your case as well.

#18 Pingback By Undocumented button highlighting | Undocumented Matlab On February 5, 2014 @ 09:02

[…] to modify the button control’s obvious suspect properties:String – the button had an HTML label. One might presume that this caused the highlighting tint, perhaps an HTML image painted […]

#19 Comment By Darin On February 28, 2014 @ 14:13

Hi Yair,

Thanks, this info is very helpful! (Even 3+ years later :)) When I used the code on a pushbutton, it centered the icon… and had the text centered as well. I tried using the IconTextGap property but to no avail. How do you keep the text on the right and the icon on the left? (instead of both icon and text centered?)

Here’s my code…

 S.sharedyaxis = uicontrol('style','push',...
    'units','pix',...
    'HorizontalAlign','left',...
    'string','SYA', ...
    'fontsize',12,'fontweight','bold');

jshared = findjobj(S.sharedyaxis,'nomenu');
icon = javax.swing.ImageIcon('C:\SYA_turnon.gif');
y = java(jshared);
y.setIcon(icon);

#20 Comment By Yair Altman On March 1, 2014 @ 09:37

@Darin –

y.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);

This is covered both in my [19] and my [21].

#21 Comment By Chris On March 7, 2014 @ 10:39

Hi Yair,

thanks for all the great help! I read your instruction of changing the border of a button, but it did’nt work. I want to create a button in a matlab gui with an image as ‘CData’. The buttons position should change with the figure’s position. But the image should not be resized (it is a small image with only few pixels). When resizing the figure, the border of the button becomes visible. To avoid that, I tried to create a borderless button and unfortunately that did’nt work. Here’s my code

button = uicontrol('Style','pushbutton','String','Hello');
jbutton = findjobj(button);
jbutton.border = [];

What am I doing wrong?

Best
Chris

#22 Comment By Yair Altman On March 10, 2014 @ 10:15

@Chris – I’m not sure what happened in your case but why use a button control at all? you can use an invisible axes, similar to my “buttons” in [22].

#23 Comment By Chris On March 13, 2014 @ 10:02

Wow, thanks for the link. Looks great!
I am using a button because I want it to have a tooltip. Is it possible to generate a tooltip for an axes object? I tried with your function findjobj, but I didn’t manage it.
Regards
Chris

#24 Comment By Yair Altman On March 13, 2014 @ 10:51

@Chris – axes are not Java objects, so you cannot use findjobj with them. And no, they don’t have tooltips.

#25 Comment By Chris On March 14, 2014 @ 10:14

OK, thanks.

#26 Comment By Cristiano On June 18, 2015 @ 18:59

Hello, Yair.
The methods you mention is useful,however,when I zoomed the window I found the Icon was overlapped by the String. Finally,If I let a dialog or form have a FIXED size,the problem is solved. I intended to resize dialogs or forms in the Windows without overlapping the Icon, but I didn’t handle it.

 
info_icon_path = fullfile('C:\Users\Zhang\Desktop\icons\ModelAdvisor.png');
info_aSi = uicontrol('Style','PushButton',...   
                 'position',[10,10,120,70],...
                 'TooltipString','',...  
                 'fontsize',10,...      
                 'fontweight','bold',...      
                 'String','Description',...
                 'Enable','on');

jButton_info_nFS = findjobj(info_aSi);              %find Java-Handle of Button
jButton_info_nFS.setIcon(javax.swing.ImageIcon(info_icon_path));    %add image to button
set(jButton_info_nFS,'HorizontalTextPosition',javax.swing.SwingConstants.RIGHT);    %align text
set(jButton_info_nFS,'VerticalTextPosition',javax.swing.SwingConstants.CENTER);   

#27 Comment By Brian On July 1, 2015 @ 02:11

Hello Yair,
Thanks for all your work on this site.

I’ve had a heck of a time trying to figure out how to do a border-less button. I tried using both the null vector ‘[]’ approach and by setting the border directly by using the methods from the border factory class from the link you posted above (see below). However none of these attempts result in a border-less button.

I followed your example of a borderless button from here:
[23]

I just can’t understand why this won’t work here in this simplified example. My simple code looks like this so far:

f=figure('Menubar','none', 'Position',[200 200 300 200]);
p=uipanel(f, 'BackgroundColor', [0 0 1]);
h = uicontrol('parent', p, 'Style','pushbutton', 'String','click', ...
   'Units','normalized', 'Position',[0.3 0.3 0.5 0.5],'BackgroundColor', [0 0 1]);
jh = findjobj(h);
jh.setBorder(javax.swing.BorderFactory.createEmptyBorder()); %attempt 1 does not remove border
jh.border=[];                                                %attempt 2 does not remove border
jh.setBorder([]);                                            %attempt 3 does not remove border
jh.border=javax.swing.BorderFactory.createEmptyBorder();     %attempt 4 does not remove border

I’m using MATLAB 2015a and Windows7. Any way you can provide a simple complete code for a border-less button or edit above?

Thank You!

#28 Comment By Yair Altman On July 7, 2015 @ 11:37

@Brian –

jh.setBorderPainted(false);  % or: jh.BorderPainted=false;

#29 Comment By Kim On November 17, 2020 @ 06:46

Yair, the following didn’t work for me either:

jh.setBorderPainted(false);

Regards,
Kim

#30 Comment By David On April 15, 2016 @ 02:10

Hi Yair,
First of all thanks for this great site.
I have a problem when resizing the button parent window, the icon image dissappears.

f = figure;
b = uicontrol(f);
jButton = java(findjobj(b))
jButton.setIcon(javax.swing.ImageIcon(iconPath))

I am using R2015a and Windows7

#31 Comment By Yair Altman On April 22, 2016 @ 12:59

@David – you can place the relevant setIcon() code in a small function and set the parent’s SizeChangedFcn callback to this function’s handle. This way whenever the parent resizes the icon will get repainted. Add a call to jButton.repaint() after setIcon(), to ensure that it actually gets repainted.

#32 Comment By Jacob On January 21, 2020 @ 01:01

So, I’m having trouble finding information on this.

If I change the border of a button, then change the background color, the border resets. Then I am not able to change the border whatsoever. Is there a way I can change the border and the background? I do not want to be stuck using borderless buttons if I don’t have to

Thanks

#33 Comment By Yair Altman On January 21, 2020 @ 10:31

The default Java Look&Feel for UI buttons paints the border together with the contents, and apparently prevents changing both of them together ( [24]). [25] might possibly help, and of course you could always create and use a custom Java class that inherits JButton. In any case, this is a pure Java Swing issue (not Matlab) so you should search for answers in Java forums.

Cross-reference: [26]


Article printed from Undocumented Matlab: https://undocumentedmatlab.com

URL to article: https://undocumentedmatlab.com/articles/button-customization

URLs in this post:

[1] JButton: http://java.sun.com/docs/books/tutorial/uiswing/components/button.html

[2] acceptance of HTML and CSS Strings: http://undocumentedmatlab.com/blog/html-support-in-matlab-uicomponents/

[3] FindJObj submission on the File Exchange: http://www.mathworks.com/matlabcentral/fileexchange/14317

[4] here: http://undocumentedmatlab.com/blog/findjobj-find-underlying-java-object/

[5] UIINSPECT submission on the File Exchange: http://www.mathworks.com/matlabcentral/fileexchange/17935

[6] as shown here: http://java.sun.com/docs/books/tutorial/uiswing/components/border.html

[7] see here: http://undocumentedmatlab.com/blog/using-java-7-in-matlab-r2013a-and-earlier/#comment-309353

[8] some 30 callbacks, detailed in a separate post: http://undocumentedmatlab.com/blog/uicontrol-callbacks/

[9] Matlab toolstrip – part 4 (control customization) : https://undocumentedmatlab.com/articles/matlab-toolstrip-part-4-control-customization

[10] Toolbar button labels : https://undocumentedmatlab.com/articles/toolbar-button-labels

[11] GUIDE customization : https://undocumentedmatlab.com/articles/guide-customization

[12] Listbox layout customization : https://undocumentedmatlab.com/articles/listbox-layout-customization

[13] Undocumented button highlighting : https://undocumentedmatlab.com/articles/undocumented-button-highlighting

[14] Borderless button used for plot properties : https://undocumentedmatlab.com/articles/borderless-button-used-for-plot-properties

[15] : http://pastebin.com/f1e4b6086

[16] : https://undocumentedmatlab.com/blog/customizing-matlab-labels/

[17] : https://undocumentedmatlab.com/blog/continuous-slider-callback/#Property_Listener

[18] : http://www.coderanch.com/t/346360/GUI/java/Image-icon#1520092

[19] : https://undocumentedmatlab.com/matlab-java-book/

[20] : http://stackoverflow.com/questions/7311235/java-html-css-in-swing-display-inline-not-working

[21] : https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&currency_code=USD&business=altmany@gmail.com&amount=39&item_name=Matlab+uicontrols+customization+report

[22] : https://undocumentedmatlab.com/ib-matlab/real-time-trading-system-demo/

[23] : https://undocumentedmatlab.com/blog/borderless-button-used-for-plot-properties

[24] : https://stackoverflow.com/questions/41990547/change-color-of-jbutton-without-changing-its-shape

[25] : https://undocumentedmatlab.com/articles/modifying-matlab-look-and-feel

[26] : https://undocumentedmatlab.com/articles/customizing-uicontrol-border

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.