Quantcast
Channel: Hidden property – Undocumented Matlab
Viewing all articles
Browse latest Browse all 30

Customizing Matlab uipanels

$
0
0

The major innovation in Matlab release R2014b was the introduction of the new handle-based graphics system (HG2). However, this release also included a few other improvements to graphics/GUI that should not be overlooked. The most notable is that uitabs are finally officially documented/supported, following a decade or being undocumented (well, undocumented in the official sense, since I took the time to document this functionality in this blog and in my Matlab-Java book).

A less-visible improvement occurred with uipanels: Panels are very important containers when designing GUIs. They enable a visual grouping of related controls and introduce order to an otherwise complex GUI. Unfortunately, until R2014b panels were drawn at the canvas level, and did not use a standard Java Swing controls like other uicontrols. This made it impossible to customize uipanels in a similar manner to other GUI uicontrols (example).

In R2014b, uipanels have finally become standard Java Swing controls, a com.mathworks.hg.peer.ui.UIPanelPeer$UIPanelJPanel component that extends Swing’s standard javax.swing.JPanel and Matlab’s ubiquitous com.mathworks.mwswing.MJPanel. This means that we can finally customize it in various ways that are not available in plain Matlab.

We start the discussion with a simple Matlab code snippet. It is deliberately simple, since I wish to demonstrate only the panel aspects:

figure('Menubar','none', 'Color','w');
hPanel = uipanel('Title','Panel title', 'Units','norm', 'Pos',[.1,.1,.6,.7]);
hButton = uicontrol('String','Click!', 'Parent',hPanel);

Standard Matlab uipanel

Standard Matlab uipanel

Notice the default ‘etchedin’ panel border, which I hate (note the broken edges at the corners). Luckily, Swing includes a wide range of alternative borders that we can use. I’ve already demonstrated customizing Matlab uicontrols with Java borders back in 2010 (has it really been that long? wow!). In R2014b we can finally do something similar to uipanels:

The first step is to get the uipanel‘s underlying Java component’s reference. We can do this using my findjobj utility, but in the specific case of uipanel we are lucky to have a direct shortcut by using the panel’s undocumented hidden property JavaFrame and its PrintableComponent property:

>> jPanel = hPanel.JavaFrame.getPrintableComponent
jPanel =
com.mathworks.hg.peer.ui.UIPanelPeer$UIPanelJPanel[,0,0,97x74,...]

Let’s now take a look at the jPanel‘s border:

>> jPanel.getBorder
ans =
com.mathworks.hg.peer.ui.borders.TitledBorder@25cd9b97
 
>> jPanel.getBorder.get
                Border: [1x1 com.mathworks.hg.peer.ui.borders.EtchedBorderWithThickness]
          BorderOpaque: 0
                 Class: [1x1 java.lang.Class]
                 Title: 'Panel title'
            TitleColor: [1x1 java.awt.Color]
             TitleFont: [1x1 java.awt.Font]
    TitleJustification: 1
         TitlePosition: 2

Ok, simple enough. Let’s replace the border’s EtchedBorderWithThickness with something more appealing. We start with a simple red LineBorder having rounded corners and 1px width:

jColor = java.awt.Color.red;  % or: java.awt.Color(1,0,0)
jNewBorder = javax.swing.border.LineBorder(jColor, 1, true);  % red, 1px, rounded=true
jPanel.getBorder.setBorder(jNewBorder);
jPanel.repaint;  % redraw the modified panel

Rounded-corners LineBorder

Rounded-corners LineBorder

Or maybe a thicker non-rounded orange border:

jColor = java.awt.Color(1,0.5,0);
jNewBorder = javax.swing.border.LineBorder(jColor, 3, false);  % orange, 3px, rounded=false
jPanel.getBorder.setBorder(jNewBorder);
jPanel.repaint;  % redraw the modified panel

Another LineBorder example

Another LineBorder example

Or maybe a MatteBorder with colored insets:

jColor = java.awt.Color(0,0.3,0.8);  % light-blue
jNewBorder = javax.swing.border.MatteBorder(2,5,8,11,jColor)  % top,left,bottom,right, color
jPanel.getBorder.setBorder(jNewBorder);
jPanel.repaint;  % redraw the modified panel

MatteBorder with solid insets

MatteBorder with solid insets

MatteBorder can also use an icon (rather than a solid color) to fill the border insets. First, let’s load the icon. We can either load a file directly from disk, or use one of Matlab’s standard icons. Here are both of these alternatives:

% Alternative #1: load from disk file
icon = javax.swing.ImageIcon('C:\Yair\star.gif');
 
% Alternative #2: load a Matlab resource file
jarFile = fullfile(matlabroot,'/java/jar/mlwidgets.jar');
iconsFolder = '/com/mathworks/mlwidgets/graphics/resources/';
iconURI = ['jar:file:/' jarFile '!' iconsFolder 'favorite_hoverover.png'];  % 14x14 px
icon = javax.swing.ImageIcon(java.net.URL(iconURI));

We can now pass this icon reference to MatteBorder‘s constructor:

w = icon.getIconWidth;
h = icon.getIconHeight;
jNewBorder = javax.swing.border.MatteBorder(h,w,h,w,icon)  % top,left,bottom,right, icon
jPanel.getBorder.setBorder(jNewBorder);
jPanel.repaint;  % redraw the modified panel

MatteBorder with icon insets

MatteBorder with icon insets

Additional useful Swing borders can be found in the list of classes implementing the Border interface, or via the BorderFactory class. For example, let’s create a dashed border having a 3-2 ratio between the line lengths and the spacing:

jColor = java.awt.Color.blue;  % or: java.awt.Color(0,0,1);
lineWidth = 1;
relativeLineLength = 3;
relativeSpacing = 2;
isRounded = false;
jNewBorder = javax.swing.BorderFactory.createDashedBorder(jColor,lineWidth,relativeLineLength,relativeSpacing,isRounded);
jPanel.getBorder.setBorder(jNewBorder);
jPanel.repaint;  % redraw the modified panel

StrokeBorder (dashed)

StrokeBorder (dashed)

After seeing all these possibilities, I think you’ll agree with me that Matlab’s standard uipanel borders look pale in comparison.

Have you used any interesting borders in your Matlab GUI? Or have you customized your panels in some other nifty manner? If so, then please place a comment below.

 
Related posts:
  1. Transparent uipanels Matlab uipanels can be made transparent, for very useful effects. ...
  2. Customizing Matlab labels Matlab's text uicontrol is not very customizable, and does not support HTML or Tex formatting. This article shows how to display HTML labels in Matlab and some undocumented customizations...
  3. Customizing uicontrol border Matlab uicontrol borders can easily be modified - this article shows how...
  4. Customizing editboxes Matlab's editbox can be customized in many useful manners...
 

Viewing all articles
Browse latest Browse all 30

Trending Articles