Icons – Undocumented Matlab https://undocumentedmatlab.com Charting Matlab's unsupported hidden underbelly Fri, 20 Oct 2017 09:57:44 +0000 en-US hourly 1 https://wordpress.org/?v=4.4.1 Rich-contents log panelhttps://undocumentedmatlab.com/blog/rich-contents-log-panel https://undocumentedmatlab.com/blog/rich-contents-log-panel#comments Wed, 18 Sep 2013 14:00:16 +0000 http://undocumentedmatlab.com/?p=4180
 
Related posts:
  1. Spicing up Matlab uicontrol tooltips Matlab uicontrol tooltips can be spiced-up using HTML and CSS, including fonts, colors, tables and images...
  2. Aligning uicontrol contents Matlab uicontrols can often be customized using plain HTML/CSS, without need for advanced Java. ...
  3. Multi-line uitable column headers Matlab uitables can present long column headers in multiple lines, for improved readability. ...
  4. Images in Matlab uicontrols & labels Images can be added to Matlab controls and labels in a variety of manners, documented and undocumented. ...
 
]]>
I often include a log panel in Matlab applications that process data. By sending messages to the log panel, I can avoid msgbox popups and Command Window messages that interfere with the regular workflow. In Matlab, such log panels typically use a simple listbox or editbox control. The problem with this is that all text messages in the log panel look the same. Matlab does not have a documented way to highlight specific messages or words. Well, this has never stopped us before, has it? :-)

The listbox solution

I have often noted in past articles that most Matlab uicontrols support HTML formatting. We can use a listbox control for our log panel, and use HTML formatting for the various log messages, based on their severity or content. For example:

Listbox with HTML'ed items

Listbox with HTML colored items

uicontrol('Style','list', 'Position',[10,10,70,70], 'String', ...
   {'<html><font color="red">Hello</font></html>', 'world', ...
    '<html><font style="font-family:impact;color:green"><i>What a', ...   % note: </i></font></html> are not needed
    '<html><font color="blue" face="Comic Sans MS">nice day!</font>'});   % note: </html> is not needed

Rich listboxes such as this are very easy to set up and use. As I just showed, all it takes is sending an HTML string to a regular listbox. The down-side is that listboxes only display single-line messages, so if our message is too long we need to manually split it into separate listbox lines, which is rather inconvenient. Using HTML <br/> does not work since the allocated line height remains unchanged. We can fix this by playing around with the underlying Java object‘s RowHeight property, but that again is rather inconvenient.

The editbox solution

Instead of a listbox, I often use a multi-line editbox. Unfortunately, HTML is not as-easy to use in multi-line editbox contents, but as I have shown before, it is indeed possible and actually quite powerful. In fact, I am using such an editbox-based log panel’s in my online presentation at the MATLAB Computational Finance Virtual Conference tomorrow (Thursday Sep 19, 2013 at 2pm EST / 8pm CEST, see details below):

Real-time trading system demo in Matlab (click to zoom)

Real-time trading system demo in Matlab (click to zoom)

We can see in the screenshot that some log messages (the red warning message) can span multiple lines. Moreover, the panels can be interactively dragged/resized, making the multi-line log messages “flow” based on available space. So using an editbox is preferable to a listbox. The solution implemented in the demo is quite simple:

First we define the logging utility function (the icon filenames may need to be changed based on your Matlab release):

function logMessage(jEditbox,text,severity)
   % Ensure we have an HTML-ready editbox
   HTMLclassname = 'javax.swing.text.html.HTMLEditorKit';
   if ~isa(jEditbox.getEditorKit,HTMLclassname)
      jEditbox.setContentType('text/html');
   end
 
   % Parse the severity and prepare the HTML message segment
   if nargin < 3,  severity='info';  end
   switch lower(severity(1))
      case 'i',  icon = 'greenarrowicon.gif'; color='gray';
      case 'w',  icon = 'demoicon.gif';       color='black';
      otherwise, icon = 'warning.gif';        color='red';
   end
   icon = fullfile(matlabroot,'toolbox/matlab/icons',icon);
   iconTxt =['<img src="file:///',icon,'" height=16 width=16/>'];
   msgTxt = ['&nbsp;<font color=',color,'>',text,'</font>'];
   newText = [iconTxt,msgTxt];
   endPosition = jEditbox.getDocument.getLength;
   if endPosition>0, newText=['<br />' newText];  end
 
   % Place the HTML message segment at the bottom of the editbox
   currentHTML = char(jEditbox.getText);
   jEditbox.setText(strrep(currentHTML,[60 '/body>'],newText));
   endPosition = jEditbox.getDocument.getLength;
   jEditbox.setCaretPosition(endPosition); % end of content
end

Next, we initialize the log panel editbox and store the editbox’s underlying Java component (jEditbox) using the findjobj utility:

% Prepare the log editbox
hLogPanel = uicontrol('style','edit', 'max',5, 'Parent',hLeftBottomPanel, 'Units','norm', 'Position',[0,0.2,1,0.8], 'Background','w');
 
% Get the underlying Java editbox, which is contained within a scroll-panel
jScrollPanel = findjobj(hLogPanel);
try
    jScrollPanel.setVerticalScrollBarPolicy(jScrollPanel.java.VERTICAL_SCROLLBAR_AS_NEEDED);
    jScrollPanel = jScrollPanel.getViewport;
catch
    % may possibly already be the viewport, depending on release/platform etc.
end
jEditbox = handle(jScrollPanel.getView,'CallbackProperties');

Now, we can use this logging utility function to log messages in our application. For example:

logMessage(jEditbox, 'a regular info message...');
logMessage(jEditbox, 'a warning message...', 'warn');
logMessage(jEditbox, 'an error message!!!', 'error');
logMessage(jEditbox, 'a regular message again...', 'info');

Rich editbox contents (a log file)

Rich editbox contents (a log file)

HTML editboxes are normally editable, images included. In actual applications, we usually wish to prevent editing the displayed log. To do this, we simply call jEditbox.setEditable(false). Similarly, it is easy to set-up a Matlab callback-function to handle hyperlink clicks in the log panel (unlike what we might think, this is not handled automatically by the HTML processing engine):

% Prevent user editing in the log-panel
jEditbox.setEditable(false);
 
% Set-up a Matlab callback function to handle hyperlink clicks
set(jEditbox,'HyperlinkUpdateCallback',@linkCallbackFcn);

About the MATLAB Computational Finance Virtual Conference and my presentation

The MATLAB Computational Finance Virtual Conference is a one-day (Thursday Sep 19, 2013) event of hour-long presentations by industry professionals that showcase real-world examples demonstrating how financial-industry researchers and developers can excel at their jobs, improve their research and business processes, reduce costs, and mitigate risks by using Matlab. Registration to the conference is free and it’s a virtual conference, so there’s no need for a tie and jacket and you’re welcome to join…

MATLAB Computational Finance Conference 2013

My presentation on “A Real-Time Trading System in MATLAB“, is scheduled for 2pm EST / 8pm CEST. Following a half-hour presentation, I will answer audience questions online. The presentation slides can be downloaded here. Here is the recorded presentation video:

The demo system’s user interface showcases the hidden visualization and interactivity potential of Matlab for tracking order executions and charting financial time-series in real time. The undocumented features used in the demo include:

So, even if you’re not interested in real-time financial trading with Matlab, you might find it interesting to see the neat things that Matlab can do using a Java API interface and a few undocumented GUI tricks (such as the rich-contents log that I explained above).

The demo source code is provided here (tradingDemo.m and supporting files). Note that this is provided as-is, free of charge but without any warranty or support. You would naturally need IB-Matlab and an Interactive Brokers account to run it. But you can reuse parts of the source code in your Matlab programs even without an IB account or IB-Matlab.

]]>
https://undocumentedmatlab.com/blog/rich-contents-log-panel/feed 15
Images in Matlab uicontrols & labelshttps://undocumentedmatlab.com/blog/images-in-matlab-uicontrols-and-labels https://undocumentedmatlab.com/blog/images-in-matlab-uicontrols-and-labels#comments Wed, 17 Oct 2012 18:00:57 +0000 http://undocumentedmatlab.com/?p=3177
 
Related posts:
  1. Rich-contents log panel Matlab listboxes and editboxes can be used to display rich-contents HTML-formatted strings, which is ideal for log panels. ...
  2. Spicing up Matlab uicontrol tooltips Matlab uicontrol tooltips can be spiced-up using HTML and CSS, including fonts, colors, tables and images...
  3. Multi-line tooltips Multi-line tooltips are very easy to set up, once you know your way around a few undocumented hiccups....
  4. Multi-line uitable column headers Matlab uitables can present long column headers in multiple lines, for improved readability. ...
 
]]>
A couple of weeks ago, a reader here asked how to integrate images in Matlab labels. I see quite a few queries about this, so I wanted to take today’s opportunity to explain how this can be done, and how to avoid common pitfalls.

In fact, there are two main methods of displaying images in Matlab GUI – the documented method, and the undocumented one:

The documented method

Some Matlab uicontrols (buttons, radio and checkboxes) have the CData property that can be used to load and display an image. For example:

imgData = imread('myImage.jpg');   % or: imread(URL)
hButton = uicontrol('CData',imgData, ...);

While label uicontrols (uicontrol(‘style’,’text’, …)) also have the CData property, it has no effect on these controls. Instead, we can create an invisible axes that displays the image using the image function.

The undocumented method

web-based images

I’ve already written extensively about Matlab’s built-in support for HTML in many of its controls. The supported HTML subset includes the <img> tag, and can therefore display images. For example:

htmlStr = '<html><b>Logo</b>: <img src="https://undocumentedmatlab.com/images/logo_68x60.png"/></html>';
hButton = uicontrol('Position',[10,10,120,70], 'String',htmlStr, 'Background','white');

uicontrol with HTML image

uicontrol with HTML image

local images

Note that the image src (filename) needs to be formatted in a URL-compliant format such as 'http://www.website.com/folder/image.gif' or 'file:/c:/folder/subfolder/img.png'. If we try to use a non-URL-format filename, the image will not be rendered, only a placeholder box:

uicontrol('Position',..., 'String','<html><img src="img.gif"/></html>');  %bad
uicontrol('Style','list', ... 'String',{...,'<html><img src="img.gif"/></html>'});  %bad

Ill-specified HTML images in Matlab uicontrols Ill-specified HTML images in Matlab uicontrols

Ill-specified HTML images in Matlab uicontrols

Instead, we need to use correct URI syntax when specifying local images, which means using the 'file:/' protocol prefix and the '/' folder separator:

>> iconsFolder = fullfile(matlabroot,'/toolbox/matlab/icons/');
>> iconUrl = strrep(['file:/' iconsFolder 'matlabicon.gif'],'\','/');
>> str = ['<html><img src="' iconUrl '"/></html>']
str =
<html><img src="file:/C:/Program Files/MATLAB/ ..... /icons/matlabicon.gif"/></html>
 
>> uicontrol('Position',..., 'String',str);
>> uicontrol('Style','list', ... str});

Correctly-specified HTML images in Matlab uicontrols Correctly-specified HTML images in Matlab uicontrols

Correctly-specified HTML images in Matlab uicontrols

A similar pitfall exists when trying to integrate images in GUI control tooltips. I already discussed this issue here.

You can use HTML to resize the images, using the <img> tag’s width, height attributes. However, beware that enlarging an image might introduce pixelization effects. I discussed image resizing here – that article was in the context of menu-item icons, but the discussion of image resizing also applies in this case.

images in text labels

As for text labels, since text-style uicontrols do not unfortunately support HTML, we can use the equivalent Java JLabels, as I have explained here. Here too, we need to use the 'file:/' protocol prefix and the '/' folder separator if we want to use local files rather than internet files (http://…).

Java customizations

Using a uicontrol’s underlying Java component, we can customize the displayed image icon even further. For example, we can specify a different icon for selected/unselected/disabled/hovered/pressed/normal button states, as I have explained here. In fact, we can even specify a unique icon that will be used for the mouse cursor when it hovers on the control:

Custom cursor Custom cursor

Custom uicontrol cursors

]]>
https://undocumentedmatlab.com/blog/images-in-matlab-uicontrols-and-labels/feed 28
Customizing menu items part 3https://undocumentedmatlab.com/blog/customizing-menu-items-part-3 https://undocumentedmatlab.com/blog/customizing-menu-items-part-3#comments Wed, 09 May 2012 18:00:05 +0000 http://undocumentedmatlab.com/?p=2909
 
Related posts:
  1. Customizing menu items part 2 Matlab menu items can be customized in a variety of useful ways using their underlying Java object. ...
  2. Blurred Matlab figure window Matlab figure windows can be blurred using a semi-transparent overlaid window - this article explains how...
  3. Minimize/maximize figure window Matlab figure windows can easily be maximized, minimized and restored using a bit of undocumented magic powder...
  4. Date selection components The JIDE package, pre-bundled in Matlab, contains several GUI controls for selecting dates - this article explains how they can be used...
 
]]>
In the past weeks I’ve shown how Matlab menus can be customized in a variety of undocumented manners, using HTML, pure Matlab, and Java. Today I conclude this mini-series with an article that explains how to use the underlying Java object to customize menu item icons. Menu customizations are explored in depth in section 4.6 of my book.

A reminder: accessing the underlying Java object

Matlab menus (uimenu) are basically simple wrappers for the much more powerful and flexible Java Swing JMenu and JMenuItem on which they are based. Many important functionalities that are available in Java menus are missing from the Matlab uimenus.

Getting the Java reference for the figure window’s main menu is very easy:

jFrame = get(handle(hFig),'JavaFrame');
try
    % R2008a and later
    jMenuBar = jFrame.fHG1Client.getMenuBar;
catch
    % R2007b and earlier
    jMenuBar = jFrame.fFigureClient.getMenuBar;
end

There are many customizations that can only be done using the Java handle: setting icons, several dozen callback types, tooltips, background color, font, text alignment, and so on. etc. Interested readers may wish to get/set/inspect/methodsview/uiinspect the jSave reference handle and/or to read the documentation for JMenuItem. Today’s article will focus on icon customizations.

Setting simple menu item icons

Many of Matlab’s icons reside in either the [matlabroot ‘/toolbox/matlab/icons/’] folder or the [matlabroot ‘/java/jar/mwt.jar’] file (a JAR file is simply a zip file that includes Java classes and resources such as icon images). Let us create icons from the latter, to keep a consistent look-and-feel with the rest of Matlab (we could just as easily use our own external icon files):

% External icon file example
jSave.setIcon(javax.swing.ImageIcon('C:\Yair\save.gif'));
 
% JAR resource example
jarFile = fullfile(matlabroot,'/java/jar/mwt.jar');
iconsFolder = '/com/mathworks/mwt/resources/';
iconURI = ['jar:file:/' jarFile '!' iconsFolder 'save.gif'];
iconURI = java.net.URL(iconURI);  % not necessary for external files
jSave.setIcon(javax.swing.ImageIcon(iconURI));

Note that setting a menu item’s icon automatically re-aligns all other items in the menu, including those that do not have an icon (an internal bug that was introduced in R2010a causes a misalignment, as shown below):

Menu item with a custom Icon (R2009b)

Menu item with a custom Icon (R2009b)

   
...and the same in R2010a onward

...and the same in R2010a onward

Checkmark icon

The empty space on the left of the menu is reserved for the check mark. Each Matlab menu item is check-able, since it is an object that extends the com.mathworks.mwswing.MJCheckBoxMenuItem class. I have not found a way to eliminate this empty space, which is really unnecessary in the File-menu case (it is only actually necessary in the View and Tools menus). Note that if an icon is set for the item, both the icon and the checkmark will be displayed, side by side.

The check mark is controlled by the State property of the Java object (which accepts logical true/false values), or the Checked property of the Matlab handle (which accepts the regular ‘on’/’off’ string values):

% Set the check mark at the Matlab level
set(findall(hFig,'tag','figMenuFileSave'), 'Checked','on');
 
% Equivalent - set the checkmark at the Java level
jSave.setState(true);

State = true, Icon = [ ]

State = true, Icon = [ ]

   
State = true, Icon = custom

State = true, Icon = custom

Customizing menu icons

Icons can be customized: modify the gap between the icon and the label with the IconTextGap property (default = 4 [pixels]); place icons to the right of the label by setting HorizontalTextPosition to jSave.LEFT (=2), or centered using jSave.CENTER (=0). Note that the above-mentioned misalignment bug does not appear in these cases:

jSave.setHorizontalTextPosition(jSave.LEFT)

jSave.setHorizontalTextPosition
(jSave.LEFT)

   
jSave.setHorizontalTextPosition(jSave.CENTER)

jSave.setHorizontalTextPosition
(jSave.CENTER)

Note how the label text can be seen through (or on top of) the icon when it is centered. This feature can be used to create stunning menu effects as shown below. Note how the width and height of the menu item automatically increased to accommodate my new 77×31 icon size (icons are normally sized 16×16 pixels):

Overlaid icon (HorizontalTextPosition = CENTER)

Overlaid icon (HorizontalTextPosition = CENTER)

To resize an icon programmatically before setting it in a Java component, we can use the following example:

myIcon = fullfile(matlabroot,'/toolbox/matlab/icons/matlabicon.gif');
imageToolkit = java.awt.Toolkit.getDefaultToolkit;
iconImage = imageToolkit.createImage(myIcon);
iconImage = iconImage.getScaledInstance(32,32,iconImage.SCALE_SMOOTH);
jSave.setIcon(javax.swing.ImageIcon(iconImage));

Remember when rescaling images, particularly small ones with few pixels, that it is always better to shrink than to enlarge images: enlarging a small icon image might introduce a significant pixelization effect:

16x16 icon image resized to 32x32

16x16 icon image resized to 32x32

Separate icons can be specified for a different appearance during mouse hover (RolloverIcon; requires RolloverEnabled=1), item click/press (PressedIcon), item selection (SelectedIcon, RolloverSelectedIcon, DisabledSelectedIcon), and disabled menu item (DisabledIcon). All these properties are empty ([]) by default, which applies a predefined default variation (image color filter) to the main item’s Icon. For example, let us modify DisabledIcon:

myIcon = 'C:\Yair\Undocumented Matlab\Images\save_disabled.gif';
jSaveAs.setDisabledIcon(javax.swing.ImageIcon(myIcon));
jSaveAs.setEnabled(false);

Enabled, main Icon

Enabled, main Icon

   
Disabled, default Icon variation

Disabled, default Icon variation

   
Disabled, custom DisabledIcon

Disabled, custom DisabledIcon

Note the automatic graying of disabled menu items, including their icon. This effect can also be achieved programmatically using the static methods in com.mathworks.mwswing.IconUtils: changeIconColor(), createBadgedIcon(), createGhostedIcon(), and createSelectedIcon(). When we use a non-default custom DisabledIcon, it is used instead of the gray icon variant.

This concludes my mini-series of customizing menus in Matlab. If you have used any nifty customization that I have not mentioned, please post a comment about it below.

Ken & MikeIn an unrelated note, I would like to extend good wishes to Mike Katz, who has left the MathWorks mobile development team to join Kinvey a few days ago. Mike has been with MathWorks since 2005 and has been responsible for maintaining the official MATLAB Desktop blog, together with Ken Orr. I’m not sure yet which direction the Desktop blog will take, and by whom, but in any case it won’t be the same. You’re both missed, Mike & Ken!

 

]]>
https://undocumentedmatlab.com/blog/customizing-menu-items-part-3/feed 36
Uitab colors, icons and imageshttps://undocumentedmatlab.com/blog/uitab-colors-icons-images https://undocumentedmatlab.com/blog/uitab-colors-icons-images#comments Wed, 10 Nov 2010 18:00:01 +0000 http://undocumentedmatlab.com/?p=1955
 
Related posts:
  1. Figure toolbar components Matlab's toolbars can be customized using a combination of undocumented Matlab and Java hacks. This article describes how to access existing toolbar icons and how to add non-button toolbar components....
  2. Customizing uitree nodes – part 1 This article describes how to customize specific nodes of Matlab GUI tree controls created using the undocumented uitree function...
  3. Customizing uitree nodes – part 2 This article shows how Matlab GUI tree nodes can be customized with checkboxes and similar controls...
  4. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
 
]]>
A few months ago I published a post about Matlab’s semi-documented tab-panel functionality, where I promised a follow-up article on tab customizations. A reader of this blog asked a related question earlier today, so I decided it’s about time I fulfilled this promise.

As with most Matlab controls, the underlying Java component enables far greater customization than possible using plain Matlab. Today I will show three specific customizations. We start with a basic tab group, and get the underlying Java component:

% Prevent an annoying warning msg
warning off MATLAB:uitabgroup:OldVersion
 
% Prepare a tab-group consisting of two tabs
hTabGroup = uitabgroup; drawnow;
tab1 = uitab(hTabGroup, 'title','Panel 1');
a = axes('parent', tab1); surf(peaks);
tab2 = uitab(hTabGroup, 'title','Panel 2');
uicontrol(tab2, 'String','Close', 'Callback','close(gcbf)');
 
% Get the underlying Java reference (use hidden property)
jTabGroup = getappdata(handle(hTabGroup),'JTabbedPane');

Foreground & background tab colors

We can set the tab font color using setForeground() and setForegroundAt(), or via HTML. Note that setForegroundAt() overrides anything set by setForeground(). Also remember that Java uses 0-based indexing so tab #1 is actually the second tab:

% Equivalent manners to set a red tab foreground:
jTabGroup.setForegroundAt(1,java.awt.Color(1.0,0,0)); % tab #1
jTabGroup.setTitleAt(1,'<html><font color="red"><i>Panel 2');
jTabGroup.setForeground(java.awt.Color.red);

Unfortunately, the corresponding setBackgroundAt(tabIndex,color) method has no visible effect, and the Matlab-extended tabs keep their white/gray backgrounds. A similar attempt to modify the tab’s BackgroundColor property fails, since Matlab made this property unmodifiable (=’none’). A simple solution is to use a CSS background:

% Equivalent manners to set a yellow tab background:
jTabGroup.setTitleAt(0,'<html><div style="background:#ffff00;">Panel 1');
jTabGroup.setTitleAt(0,'<html><div style="background:yellow;">Panel 1');

uitabgroup with non-default forground and background tab colors and fonts

uitabgroup with non-default forground and background tab colors and fonts

We can set the foreground text color using the CSS color directive. Similarly, we can also set a background gradient image for the tabs, using the CSS background-image directive. Which leads us to our next customization:

Icon images

Icons and sub-components can be added to the tabs. Unfortunately, for some reason that I do not fully understand, jTabGroup.setIconAt() has no apparent effect. The solution is to set our own custom control as the requested tab, and add our icon (or other customizations) to it. Here is a simple example:

% Add an icon to tab #1 (=second tab)
icon = javax.swing.ImageIcon('C:\Yair\save.gif');
jLabel = javax.swing.JLabel('Tab #2');
jLabel.setIcon(icon);
jTabGroup.setTabComponentAt(1,jLabel);	% Tab #1 = second tab
 
% Note: icon is automatically grayed when label is disabled
jLabel.setEnabled(false);
jTabGroup.setEnabledAt(1,false);  % disable only tab #1

tab with a custom icon (enabled)
tab with a custom icon (enabled)

tab with a custom icon (enabled & disabled)

Close buttons

Now let’s try a more complex example, of adding a close (‘x’) button to one of the tabs. Generalizing this code snippet is left as an exercise to the reader:

% First let's load the close icon
jarFile = fullfile(matlabroot,'/java/jar/mwt.jar');
iconsFolder = '/com/mathworks/mwt/resources/';
iconURI = ['jar:file:/' jarFile '!' iconsFolder 'closebox.gif'];
icon = javax.swing.ImageIcon(java.net.URL(iconURI));
 
% Now let's prepare the close button: icon, size and callback
jCloseButton = handle(javax.swing.JButton,'CallbackProperties');
jCloseButton.setIcon(icon);
jCloseButton.setPreferredSize(java.awt.Dimension(15,15));
jCloseButton.setMaximumSize(java.awt.Dimension(15,15));
jCloseButton.setSize(java.awt.Dimension(15,15));
set(jCloseButton, 'ActionPerformedCallback',@(h,e)delete(tab2));
 
% Now let's prepare a tab panel with our label and close button
jPanel = javax.swing.JPanel;	% default layout = FlowLayout
set(jPanel.getLayout, 'Hgap',0, 'Vgap',0);  % default gap = 5px
jLabel = javax.swing.JLabel('Tab #2');
jPanel.add(jLabel);
jPanel.add(jCloseButton);
 
% Now attach this tab panel as the tab-group's 2nd component
jTabGroup.setTabComponentAt(1,jPanel);	% Tab #1 = second tab

tab with an attached close button

tab with an attached close button

Next week’s article will conclude the series on Matlab’s uitab. Any particular customization you are interested in? Please do post a comment.

Addendum Oct 3 2014: the uitab and uitabgroup functions have finally become fully supported and documented in Matlab version 8.4 (R2014b). However, the Java-based customizations shown in this article are still unsupported and undocumented, although they remain practically unchanged from what I’ve described in this article, four years earlier.

]]>
https://undocumentedmatlab.com/blog/uitab-colors-icons-images/feed 32
Figure toolbar componentshttps://undocumentedmatlab.com/blog/figure-toolbar-components https://undocumentedmatlab.com/blog/figure-toolbar-components#comments Thu, 27 Aug 2009 16:31:36 +0000 http://undocumentedmatlab.com/?p=541
 
Related posts:
  1. Uitab colors, icons and images Matlab's semi-documented tab panels can be customized using some undocumented hacks...
  2. Customizing uitree nodes – part 2 This article shows how Matlab GUI tree nodes can be customized with checkboxes and similar controls...
  3. Customizing uitree This article describes how to customize Matlab GUI tree controls created using the undocumented uitree function...
  4. Customizing uitree nodes – part 1 This article describes how to customize specific nodes of Matlab GUI tree controls created using the undocumented uitree function...
 
]]>
Toolbars are by now a staple of modern GUI design. An unobtrusive list of small icons enables easy access to multiple application actions without requiring large space for textual descriptions. Unfortunately, the built-in documented support for the Matlab toolbars is limited to adding icon buttons via the uipushtool and uitoggletool functions, and new toolbars containing them via the uitoolbar function. In this post I will introduce several additional customizations that rely on undocumented features.

This article will only describe figure toolbars. However, much of the discussion is also relevant to the desktop (Command Window) toolbars and interested users can adapt it accordingly.

Accessing toolbar buttons – undo/redo

Let’s start by adding undo/redo buttons to the existing figure toolbar. I am unclear why such an elementary feature was not included in the default figure toolbar, but this is a fact that can easily be remedied. In another post I describe uiundo, Matlab’s semi-documented support for undo/redo functionality, but for the present let’s assume we already have this functionality set up.

First, let’s prepare our icons, which are basically a green-filled triangle icon and its mirror image:

% Load the Redo icon
icon = fullfile(matlabroot,'/toolbox/matlab/icons/greenarrowicon.gif');
[cdata,map] = imread(icon);
 
% Convert white pixels into a transparent background
map(find(map(:,1)+map(:,2)+map(:,3)==3)) = NaN;
 
% Convert into 3D RGB-space
cdataRedo = ind2rgb(cdata,map);
cdataUndo = cdataRedo(:,[16:-1:1],:);

Now let’s add these icons to the default figure toolbar:

% Add the icon (and its mirror image = undo) to the latest toolbar
hUndo = uipushtool('cdata',cdataUndo, 'tooltip','undo', 'ClickedCallback','uiundo(gcbf,''execUndo'')');
hRedo = uipushtool('cdata',cdataRedo, 'tooltip','redo', 'ClickedCallback','uiundo(gcbf,''execRedo'')');

Undo/redo buttons

Undo/redo buttons

In the preceding screenshot, since no figure toolbar was previously shown, uipushtool added the undo and redo buttons to a new toolbar. Had the figure toolbar been visible, then the buttons would have been added to its right end. Since undo/redo buttons are normally requested near the left end of toolbars, we need to rearrange the toolbar buttons:

hToolbar = findall(hFig,'tag','FigureToolBar');
%hToolbar = get(hUndo,'Parent');  % an alternative
hButtons = findall(hToolbar);
set(hToolbar,'children',hButtons([4:end-4,2,3,end-3:end]));
set(hUndo,'Separator','on');

Undo/redo buttons in their expected positions

Undo/redo buttons in their expected positions

We would normally preserve hUndo and hRedo, and modify their Tooltip and Visible/Enable properties in run-time, based on the availability and name of the latest undo/redo actions:

% Retrieve redo/undo object
undoObj = getappdata(hFig,'uitools_FigureToolManager');
if isempty(undoObj)
   undoObj = uitools.FigureToolManager(hFig);
   setappdata(hFig,'uitools_FigureToolManager',undoObj);
end
 
% Customize the toolbar buttons
latestUndoAction = undoObj.CommandManager.peekundo;
if isempty(latestUndoAction)
   set(hUndo, 'Tooltip','', 'Enable','off');
else
   tooltipStr = ['undo' latestUndoAction.Name];
   set(hUndo, 'Tooltip',tooltipStr, 'Enable','on');
end

We can easily adapt the method I have just shown to modify/update existing toolbar icons: hiding/disabling them etc. based on the application needs at run-time.

Adding non-button toolbar components – undo dropdown

A more advanced customization is required if we wish to present the undo/redo actions in a drop-down (combo-box). Unfortunately, since Matlab only enables adding uipushtools and uitoggletools to toolbars, we need to use a Java component. The drawback of using such a component is that it is inaccessible via the toolbar’s Children property (implementation of the drop-down callback function is left as an exercise to the reader):

% Add undo dropdown list to the toolbar
jToolbar = get(get(hToolbar,'JavaContainer'),'ComponentPeer');
if ~isempty(jToolbar)
   undoActions = get(undoObj.CommandManager.UndoStack,'Name');
   jCombo = javax.swing.JComboBox(undoActions(end:-1:1));
   set(jCombo, 'ActionPerformedCallback', @myUndoCallbackFcn);
   jToolbar(1).add(jCombo,5); %5th position, after printer icon
   jToolbar(1).repaint;
   jToolbar(1).revalidate;
end
 
% Drop-down (combo-box) callback function
function myUndoCallbackFcn(hCombo,hEvent)
   itemIndex = get(hCombo,'SelectedIndex');  % 0=topmost item
   itemName  = get(hCombo,'SelectedItem');
   % user processing needs to be placed here
end

Undo dropdown list

Undo dropdown list

Note that the javax.swing.JComboBox constructor accepts a cell-array of strings (undoActions in the snippet above). A user-defined dropdownlist might be constructed as follows (also see a related CSSM thread):

...
dropdownStrings = {'here', 'there', 'everywhere'};
jCombo = javax.swing.JComboBox(dropdownStrings);
set(jCombo, 'ActionPerformedCallback', @myUndoCallbackFcn);
jToolbar(1).addSeparator;
jToolbar(1).add(jCombo);  % at end, following a separator mark
jToolbar(1).repaint;
jToolbar(1).revalidate;
...

A similar approach can be used to add checkboxes, radio-buttons and other non-button controls.

In next week’s post I will describe how the toolbar can be customized using undocumented functionality to achieve a non-default background, a floating toolbar (“palette”) effect and other interesting customizations. If you have any specific toolbar-related request, I’ll be happy to hear in the comments section below.

]]>
https://undocumentedmatlab.com/blog/figure-toolbar-components/feed 48
Setting system tray popup messageshttps://undocumentedmatlab.com/blog/setting-system-tray-popup-messages https://undocumentedmatlab.com/blog/setting-system-tray-popup-messages#comments Tue, 31 Mar 2009 23:09:25 +0000 http://undocumentedmatlab.com/?p=130
 
Related posts:
  1. Setting system tray icons System-tray icons can be programmatically set and controlled from within Matlab, using new functionality available since R2007b....
  2. Modifying Matlab’s Look-and-Feel Matlab's entire Look-and-Feel (PLAF, or L&F) can be modified at the control or application level - this article shows how...
  3. Uitab colors, icons and images Matlab's semi-documented tab panels can be customized using some undocumented hacks...
  4. Customizing menu items part 3 Matlab menu items can easily display custom icons, using just a tiny bit of Java magic powder. ...
 
]]>
Continuing my previous post about setting system-tray icons, I will now show how to set informational popup messages next to these icons.

Asynchronous informational messages can be presented next to the sys-tray icon, in a fashion similar to what we came to expect from modern programs. This could be used to indicate some unexpected event that was detected, or the end of a complex calculation phase. The message title, text and severity icon are all customizable.

Unfortunately, the Java method used to display messages, java.awt.TrayIcon.displayMessage(), expects an object of type java.awt.TrayIcon.MessageType, which is an enumeration within the TrayIcon class. However, Matlab’s dot-notation does not recognize what should have been the following correct notation, so we need to resort to Java reflection:

>> trayIcon.displayMessage('title','info msg',TrayIcon.MessageType.INFO);
??? No appropriate method or public field MessageType for class java.awt.TrayIcon

>> trayIconClasses = trayIcon.getClass.getClasses;
>> trayIconClasses(1)
ans =
class java.awt.TrayIcon$MessageType	<= hurray!!!
>> MessageTypes = trayIconClasses(1).getEnumConstants
MessageTypes =
java.awt.TrayIcon$MessageType[]:
    [java.awt.TrayIcon$MessageType]	<= 1: ERROR
    [java.awt.TrayIcon$MessageType]	<= 2: WARNING
    [java.awt.TrayIcon$MessageType]	<= 3: INFO
    [java.awt.TrayIcon$MessageType]	<= 4: NONE
>> trayIcon.displayMessage('title','info msg',MessageTypes(3));

systray INFO message

and another example, now with a WARNING icon:

systray WARNING message

If the title string is left empty, then neither title nor the severity icon will be displayed. The message can still be manually dismissed by clicking within its boundaries:


systray messages without a title (hence also without a severity icon)
systray messages without a title (hence also without a severity icon)

Informational popup messages are automatically aligned and positioned by the system. Messages are automatically dismissed by the system after some time, if not dismissed by the user first. The exact time is determined by system and user activity and other such external factors. Informational messages replace one another, if the previous message has still not been cleared by the user.

I have created a utility function called SYSTRAY, which is a convenience function that facilitates the setup and update of system tray icons and messages. SYSTRAY (with source code) can be downloaded from the File Exchange.

I would be happy to hear if and how you’re using the new system-tray functionality in your application – let me know below.

]]>
https://undocumentedmatlab.com/blog/setting-system-tray-popup-messages/feed 21
Setting system tray iconshttps://undocumentedmatlab.com/blog/setting-system-tray-icons https://undocumentedmatlab.com/blog/setting-system-tray-icons#comments Tue, 24 Mar 2009 20:47:54 +0000 http://undocumentedmatlab.com/?p=67
 
Related posts:
  1. Setting system tray popup messages System-tray icons and messages can be programmatically set and controlled from within Matlab, using new functionality available since R2007b....
  2. Modifying Matlab’s Look-and-Feel Matlab's entire Look-and-Feel (PLAF, or L&F) can be modified at the control or application level - this article shows how...
  3. Uitab colors, icons and images Matlab's semi-documented tab panels can be customized using some undocumented hacks...
  4. Customizing menu items part 3 Matlab menu items can easily display custom icons, using just a tiny bit of Java magic powder. ...
 
]]>
Java 1.6, included in Matlab releases since Matlab 7.5 (R2007b), enables programmatic access to system tray icons on such systems that support this functionality (Windows, Linux and possibly others).  If the SystemTray object indicates that it isSupported(), then a TrayIcon can be added, along with an associated tooltip and popup menu:

sysTray = java.awt.SystemTray.getSystemTray;
if (sysTray.isSupported)
   myIcon = fullfile(matlabroot,'/toolbox/matlab/icons/matlabicon.gif');
   iconImage = java.awt.Toolkit.getDefaultToolkit.createImage(myIcon);
   trayIcon = java.awt.TrayIcon(iconImage, 'initial tooltip');
   trayIcon.setToolTip('click this icon for applicative context menu');
end

sample system tray icon

sample system tray icon

The icon image can be made to automatically resize to the system-tray dimensions, using the trayIcon.setImageAutoSize(true) method (by default the icon image will maintain its original size, getting cropped or appearing small as the case may be).

Of course, after initial setup, all the sys-tray icon’s properties (icon image, popup, tooltip etc.) can be modified with convenient set methods (setImage(), setPopupMenu(), setTooltip()) or via Matlab’s set() function.

Icon popup menus are very similar in concept to Matlab uicontextmenus. Unfortunately, they need to be programmed separately since Java does not accept uicontextmenu handles. This is actually quite easy, as the following code snippet shows:

% Prepare the context menu
menuItem1 = java.awt.MenuItem('action #1');
menuItem2 = java.awt.MenuItem('action #2');
menuItem3 = java.awt.MenuItem('action #3');

% Set the menu items' callbacks
set(menuItem1,'ActionPerformedCallback',@myFunc1);
set(menuItem2,'ActionPerformedCallback',{@myfunc2,data1,data2});
set(menuItem3,'ActionPerformedCallback','disp(''action #3...'')');

% Disable one of the menu items
menuItem2.setEnabled(0);        % or: set(menuItem2,'Enabled','off');

% Add all menu items to the context menu (with internal separator)
jmenu = java.awt.PopupMenu;
jmenu.add(menuItem1);
jmenu.add(menuItem2);
jmenu.addSeparator;
jmenu.add(menuItem3);

% Finally, attach the context menu to the icon
trayIcon.setPopupMenu(jmenu);    % or: set(trayIcon,'PopupMenu',jmenu);

Tray icon context (right-click) menu

Tray icon context (right-click) menu

Unfortunately, neither the icon tooltip nor its popup menu supports HTML. The reason is that SystemTray is actually not part of Swing at all. The system-tray functionality resides in the java.awt package, and does not inherit javax.swing.JLabel’s (and Matlab uicontrols) support for HTML.

I have created a utility function called SYSTRAY, which is a convenience function that facilitates the setup and update of system tray icons. SYSTRAY (with source code) can be downloaded from the File Exchange.

In a separate post, I shall detail how informational pop-up messages can be attached to system-tray icons. This requires a bit of Java-hacking, so is beyond the scope of a single blog post.

Please note the new TODO page, which details my future posts. I would be happy to hear your requests for new topics, or telling me which topics you’d like to see earlier than others.

Addendum (May 15, 2009): A kind reader today left a comment on another post of this blog with a solution for some reported Java exceptions when using systray in Matlab R2008b onward.

]]>
https://undocumentedmatlab.com/blog/setting-system-tray-icons/feed 15