FindJObj – Undocumented Matlab https://undocumentedmatlab.com/blog_old Charting Matlab's unsupported hidden underbelly Tue, 29 Oct 2019 15:26:09 +0000 en-US hourly 1 https://wordpress.org/?v=4.4.1 Faster findjobjhttps://undocumentedmatlab.com/blog_old/faster-findjobj https://undocumentedmatlab.com/blog_old/faster-findjobj#comments Mon, 11 Apr 2016 09:18:14 +0000 https://undocumentedmatlab.com/?p=6376 Related posts:
  1. FindJObj – find a Matlab component’s underlying Java object The FindJObj utility can be used to access and display the internal components of Matlab controls and containers. This article explains its uses and inner mechanism....
  2. FindJObj GUI – display container hierarchy The FindJObj utility can be used to present a GUI that displays a Matlab container's internal Java components, properties and callbacks....
  3. Matlab and the Event Dispatch Thread (EDT) The Java Swing Event Dispatch Thread (EDT) is very important for Matlab GUI timings. This article explains the potential pitfalls and their avoidance using undocumented Matlab functionality....
  4. Minimize/maximize figure window Matlab figure windows can easily be maximized, minimized and restored using a bit of undocumented magic powder...
]]>
My findjobj utility, created in 2007 and updated over the years, has received wide recognition and is employed by numerous Matlab programs, including a few dozen utilities in the Matlab File Exchange. I am quite proud of this utility and find it extremely useful for customizing Matlab controls in many ways that are impossible using standard Matlab properties. I have shown many examples of this in this blog over the past years.

I am happy to announce that I have just uploaded a new version of findjobj to the Matlab File Exchange, which significantly improves the utility’s performance for the most common use-case of a single input and a single output, namely finding the handle of the underlying Java component (peer) of a certain Matlab control:

>> hButton = uicontrol('String','click me!');
 
>> tic, jButton = findjobj(hButton); toc  % old findjobj
Elapsed time is 1.513217 seconds.
 
>> tic, jButton = findjobj(hButton); toc  % new findjobj
Elapsed time is 0.029348 seconds.

The new findjobj is backward-compatible with the old findjobj and with all prior Matlab releases. It is a drop-in replacement that will significantly improve your program’s speed.

The new version relies on several techniques:

First, as I showed last year, in HG2 (R2014 onward), Matlab uipanels have finally become full-featured Java JPanels, that can be accessed and customized in many interesting manners. More to the point here, we can now directly access the underlying JPanel component handle using the uipanel‘s hidden JavaFrame property (thanks to MathWorks for supplying this useful hook!). The new findjobj version detects this and immediately returns this handle if the user specified a uipanel input.

I still do not know of any direct way to retrieve the underlying Java component’s handle for Matlab uicontrols, this has been a major frustration of mine for quite a few years. So, we need to find the containing Java container in which we will recursively search for the control’s underlying Java handle. In the old version of finjobj, we retrieve the containing figure’s JFrame reference and from it the ContentPane handle, and use this handle as the Java container that is recursively searched. This is quite slow when the figure window is heavily-laden with multiple controls. In the new version, we try to use the specified Matlab uicontrol‘s direct parent, which is very often a uipanel. In this case, we can directly retrieve the panel’s JPanel reference as explained above. This results in a must smaller and faster search since we need to recursively search far fewer controls within the container, compared to the figure’s ContentPane.

In addition, I used a suggestion by blog reader Hannes for a faster recursive search that uses the control’s tooltip rather than its size, position and class. Finally, the search order is reversed to search backward from the last child component, since this is the component that will most often contain the requested control peer.

Feel free to download and use the new findjobj version. The code for the fast variant can be found in lines #190-205 and #3375-3415.

Enjoy!

p.s. – as I explained last week, today’s discussion, and in general anything that has to do with Java peers of GUI controls, only relates to the existing JFrame-based figure windows, not to the new web-based uifigure.

]]>
https://undocumentedmatlab.com/blog_old/faster-findjobj/feed 11
Listbox layout customizationhttps://undocumentedmatlab.com/blog_old/listbox-layout-customization https://undocumentedmatlab.com/blog_old/listbox-layout-customization#comments Wed, 13 Nov 2013 20:08:28 +0000 https://undocumentedmatlab.com/?p=4374 Related posts:
  1. Setting line position in an edit-box uicontrol Matlab uicontrols have many useful features that are only available via Java. Here's how to access them....
  2. Setting listbox mouse actions Matlab listbox uicontrol can be modified to detect mouse events for right-click context menus, dynamic tooltips etc....
  3. Customizing listbox & editbox scrollbars Matlab listbox and multi-line editbox uicontrols have pre-configured scrollbars. This article shows how they can be customized....
  4. Continuous slider callback Matlab slider uicontrols do not enable a continuous-motion callback by default. This article explains how this can be achieved using undocumented features....
]]>
I haven’t written on listboxes in a long while, and since I’ve recently posted on related controls (editbox, combo-box), I thought of following up with an article on customizing Matlab listbox layout. By the end of today’s article, you should be able to customize the layout of items within your listbox, such as the following:

Customized listbox layout   Customized listbox layout

Customized listbox layouts


For the following hacks, we need to gain access to the listbox control’s underlying Java component, which is a MathWorks class that extends the standard JList. We can get this component’s reference using the findjobj utility:

>> hListbox = uicontrol('Style','List', 'String',{'item #1','item #2'});
 
>> jScrollPane = java(findjobj(hListbox))
jScrollPane =
com.mathworks.hg.peer.utils.UIScrollPane[...]
 
>> jListbox = jScrollPane.getViewport.getView
jListbox =
com.mathworks.hg.peer.ListboxPeer$UicontrolList[...]

Like multi-line editboxes, listboxes are actually composed of a container (a com.mathworks.hg.peer.utils.UIScrollPane object) that includes three children, as expected from any JScrollPane: a javax.swing.JViewport that contains the ListboxPeer$UicontrolList component, and horizontal/vertical scrollbars. I explained how to customize the scrollbars in an article back in early 2010.

Today we are not interested in the scroll-pane or scollbars, but rather the jListbox component that takes up the view-port’s contents. This component includes many useful properties that we can access and modify, including several that control the layout of the list items:

LayoutOrientation sets the layout of listbox items within the viewport. Possible values include:

  • The default value (jListbox.VERTICAL=0) indicates the regular top-to-bottom arrangement
  • jListbox.VERTICAL_WRAP=1 sets a horizontal item layout, wrapping to a new row as necessary for the maximum number of rows determined by the VisibleRowCount property (default=8)
  • jListbox.HORIZONTAL_WRAP=2 sets a vertical item layout, wrapping to a new column at row number VisibleRowCount

For example:

jListbox.setLayoutOrientation(jListbox.HORIZONTAL_WRAP);
jListbox.setVisibleRowCount(3);
 
set(jListbox, 'LayoutOrientation',2, 'VisibleRowCount',3);  % equivalent alternative

LayoutOrientation = VERTICAL = 0
VisibleRowCount is irrelevant

LayoutOrientation = VERTICAL_WRAP = 1
VisibleRowCount = 3

LayoutOrientation = HORIZONTAL_WRAP = 2
VisibleRowCount = 3

FixedCellHeight and FixedCellWidth hold the listbox’s cells height (default=13 pixels) and width (default=-1). A value of -1 means that the actual size is determined by the default platform-dependent CellRenderer size:


FixedCellHeight = -1
FixedCellWidth = -1

FixedCellHeight = 10
FixedCellWidth = 30

FixedCellHeight = 16
FixedCellWidth = 50

We can use these properties to display a selection matrix of icons. For example, let’s display the icons in Matlab standard icons folder:

% Prepare the list of ImageIcon objects
iconsFolder = fullfile(matlabroot,'toolbox/matlab/icons');
imgs = dir(fullfile(iconsFolder,'*.gif'));
for iconIdx = 1 : length(imgs)
   iconFilename = fullfile(iconsFolder,imgs(iconIdx).name);
   iconFilename = strrep(iconFilename, '\', '/');
   htmlStr{iconIdx} = ['<html><img src="file:/' iconFilename '"/>'];  % no need for </html>
end
 
% Display in a standard one-column listbox
hListbox = uicontrol('style','list', 'string',htmlStr, 'position',[10,10,160,90]);
 
% Modify the listbox layout to display 18x18-pixel cells
jScrollPane = findjobj(hListbox);
jListbox = jScrollPane.getViewport.getView;
jListbox.setLayoutOrientation(jListbox.HORIZONTAL_WRAP)
jListbox.setVisibleRowCount(4)
jListbox.setFixedCellWidth(18)   % icon width=16  + 2px margin
jListbox.setFixedCellHeight(18)  % icon height=16 + 2px margin
jListbox.repaint  % refresh the display

Customized listbox layout

Customized listbox layout

Other interesting things that we can do with listboxes (among others):

  • Customize the scrollbars, as noted above
     
  • Display HTML-formatted list 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

    Listbox with HTML'ed items

    Listbox with HTML colored items

  • Setting dynamic tooltips and right-click context-menus:
    Listbox dynamic tooltip

    Listbox dynamic tooltip

       
    Listbox dynamic context (right-click) menu

    Listbox dynamic context (right-click) menu

Note that while the code above used the underlying Java component, absolutely no knowledge of Java is required to understand it or use it. In fact, the entire code above is pure Matlab, simply setting the component’s properties and calling its methods, and using its inherent support of HTML strings.

Much more advanced customizations are possible at the Java level, especially using a dedicated CellRenderer. Interested readers can find more information about these and other possible customizations in my report on “Advanced Customizations of Matlab Uicontrols“. This 90-page PDF report can be purchased here ($29, please allow 24 hours for delivery by email). The report explains how to customize Matlab’s uicontrols in ways that are simply not possible using documented Matlab properties. This includes treatment of push buttons, toggle buttons, radio buttons, checkboxes, editboxes, listboxes, popup menus (aka combo-boxes/drop-downs), sliders, labels, and tooltips. Much of the information in the report is also available in hard-copy format in chapter 6 of my Matlab-Java programming book.

If you’d like me to personally add similar magic to your GUI, email me to see if I can help.

Advanced listbox CellRenderer customization

Advanced listbox CellRenderer customization

Now tell the truth – doesn’t Matlab’s standard listbox look kinda boring after all this? :-)

]]>
https://undocumentedmatlab.com/blog_old/listbox-layout-customization/feed 14
Customizing editboxeshttps://undocumentedmatlab.com/blog_old/customizing-editboxes https://undocumentedmatlab.com/blog_old/customizing-editboxes#comments Wed, 25 Sep 2013 14:00:26 +0000 https://undocumentedmatlab.com/?p=4212 Related posts:
  1. Uicontrol callbacks This post details undocumented callbacks exposed by the underlying Java object of Matlab uicontrols, that can be used to modify the control's behavior in a multitude of different events...
  2. Setting listbox mouse actions Matlab listbox uicontrol can be modified to detect mouse events for right-click context menus, dynamic tooltips etc....
  3. 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...
  4. GUI integrated HTML panel Simple HTML can be presented in a Java component integrated in Matlab GUI, without requiring the heavy browser control....
]]>
As a natural follow-up to last week’s article about rich-content log panels (multi-line editbox), today I discuss some additional customizations that can be done to Matlab’s editbox control.

Matlab’s dual editbox controls

There are two distinct uicontrols called ‘editbox’ in Matlab: a single-line editbox and a multi-line editbox. Matlab automatically uses the single-line control if the Max property is set to 1 (the default value, backward compatible with early Matlab versions). If Max > 1, the multi-line editbox is used. Today’s article will focus on features shared by both the single-line and multi-line editbox controls.

Beware of a possible pitfall using Matlab’s editbox controls: when switching styles, including switching between the single-line and multi-line editbox versions, Matlab replaces the underlying Java component with a new component that has default properties. Therefore, if we need any customizations to the uicontrol, then we should ensure that they are done after setting the final uicontrol style, otherwise they will be discarded.

Underlying Java object

As discussed in many prior articles, the first step in customization is to get access to the Matlab control’s underlying Java control. This is done using the findjobj utility:

% Prepare the log editbox
hEditbox = uicontrol('Style','edit', 'String','Matlab', ...);
 
% Get the underlying Java editbox
jEditbox = findjobj(hLogPanel);
 
try
    % Multi-line editboxes are contained within a scroll-panel
    jEditbox = handle(jEditbox.getViewport.getView, 'CallbackProperties');
catch
    % probably a single-line editbox
end

Borders

As I have explained long ago, all uicontrol borders can be customized using the underlying jEditbox handle’s Border property:

% Create a new border
lineColor = java.awt.Color(1,0,0);  % =red
thickness = 3;  % pixels
roundedCorners = true;
newBorder = javax.swing.border.LineBorder(lineColor,thickness,roundedCorners);
 
% Override the default control's border
jEditbox.Border = newBorder;  % or: set(jEditbox,'Border',newBorder) or: jEditbox.setBorder(newBorder)
 
% Remove the border altogether
jEditbox.Border = [];
 
% Redraw the modified control after we have changed its appearance
jEditbox.repaint;

editbox with regular border

editbox with regular border

   
editbox with custom border

editbox with custom border

   
editbox with no border

editbox with no border


Much more complex and interesting borders can be created in much the same way. Interested readers are referred to the official documentation of Java Borders or any decent Swing textbook.

Text selection

Several jEditbox properties control the text-selection functionality:

  • SelectionStart, SelectionEnd control the characters within the displayed text that are selected (typically with some shaded background color). A value of 0 means the first character, 1 means the second character etc. Setting SelectionStart=0 and SelectionEnd=intmax selects the entire text. We can also use jEditbox.select(selectionStart,selectionEnd). For example:
    set(jEditbox, 'SelectionStart',1, 'SelectionEnd',5);
    jEditbox.select(1,5)  % equivalent alternative

    Setting the selected text

    Setting the selected text

  • SelectionColor, SelectedTextColor change the foreground and background colors of the selected text. These properties are overridden whenever the editbox gains focus, so we need to be override them in the editbox’s FocusGainedCallback:
    cbStr = ['set(gcbo,''SelectionColor'',java.awt.Color.red,' ...
                   '''SelectedTextColor'',java.awt.Color.blue)'];
    set(jEditbox, 'FocusGainedCallback', cbStr);

    Non-standard selection colors and FocusGainedCallback

    Non-standard selection colors, FocusGainedCallback

  • SelectedText is a read-only property holding the text currently selected, between the SelectionStart and SelectionEnd positions. Associated property Text holds the entire text within the editbox. Note that both these properties hold a java.lang.String object, which should be cast to a Matlab string via Matlab’s built-in char function, unless we use Matlab’s get function (which does this conversion for us automatically):
    str = char(jEditbox.getSelectedText);
    str = get(jEditbox,'SelectedText');  % equivalent alternative

Customizing the input caret

The Caret property, which is common to all Java Swing data-entry components, references a javax.swing.text.DefaultCaret object that controls the text caret appearance (this is naturally relevant only for editable editboxes).

The caret object has its own properties that can be customized. For example: BlinkRateRate, Visible and UpdatePolicy. The caret’s StateChangedCallback is invoked whenever the caret position is updated.

Some additional caret-related properties can be set using jEditbox properties: CaretColor and CaretPosition (which uses 0-based, like SelectionStart and SelectionEnd above). Here is an example that modifies the default caret color to something a bit more lively:

% Set the caret color to red
jEditbox.setCaretColor(java.awt.Color(1.0,0,0));
jEditbox.setCaretColor(java.awt.Color.red);	% an alternative

Red CaretColor

Red CaretColor

Behavior

Several properties of the jEditbox handle control the editbox behavior beyond what is available by the Matlab uicontrol:

  • Editable – (default=true) a boolean flag indicating whether or not the editbox text can be modified. Note that the Matlab HG handle (hEditbox) only allows setting the Enable property (its jEditbox Java counterpart property is called Enabled), but not to set an enabled yet uneditable control – this can only be done using the Java Editable property.
  • DisabledTextColor controls the text color (default=gray) when the editbox is disabled.
  • DragEnabled – (default=false) a boolean flag indicating whether the editbox contents can be mouse-dragged externally as a DND source (for example, onto an editor, command line or any DND target). The DropMode, DropLocation, DropTarget and TransferHandler properties enable the editbox act as a DND target, accepting externally-dragged data as input sources.
  • FocusAccelerator – (default=char(0)) sets the keyboard accelerator sequence that will cause the receiving text component to get the focus. The accelerator will be the key combination of the <Alt> key and the specified character, converted to upper-case. Any previous key accelerator setting, including menu-bar accelerators, will be superseded. A char(0) key has the effect of turning off the focus accelerator. By default, there is no focus accelerator key (i.e., an accelerator of \0=char(0)). For example, let us set the accelerator to <Alt>-E, overriding the menu-bar’s default accelerator for the Edit menu:
    >> jEditbox.setFocusAccelerator('e');
    >> jEditbox.getFocusAccelerator		% let us check...
    ans =
    E	% 'e' converted to 'E', meaning an Alt-E accelerator

Additional editbox behavior can be customized using the dozens of callback functions that jEditbox exposes. These callbacks enable modifying the appearance and behavior of the editbox based on events such as mouse movements (into/over/out-of), focus gain/loss, key-clicks (that enable input data validation) etc. I plan to describe a data input-validation function based on these callbacks, using some of the customizations shown above, in next week’s article.

Available report – “Advanced Customizations of Matlab Uicontrols”

Interested readers can find more information about these and other possible customizations in my report on “Advanced Customizations of Matlab Uicontrols“. This 90-page PDF report can be purchased here ($29, please allow 24 hours for delivery by email). The report explains how to customize Matlab’s uicontrols in ways that are simply not possible using documented Matlab properties. This includes treatment of push buttons, toggle buttons, radio buttons, checkboxes, editboxes, listboxes, popup menus (aka combo-boxes/drop-downs), sliders, labels, and tooltips. Much of the information in the report is also available in hard-copy format in chapter 6 of my Matlab-Java programming book.

]]>
https://undocumentedmatlab.com/blog_old/customizing-editboxes/feed 9
Variables Editor scrollinghttps://undocumentedmatlab.com/blog_old/variables-editor-scrolling https://undocumentedmatlab.com/blog_old/variables-editor-scrolling#comments Wed, 11 Sep 2013 10:35:27 +0000 https://undocumentedmatlab.com/?p=4161 Related posts:
  1. Customizing Workspace context-menu Matlab's Workspace table context-menu can be configured with user-defined actions - this article explains how....
  2. Disabling menu entries in deployed docked figures Matlab's standard menu items can and should be removed from deployed docked figures. This article explains how. ...
  3. Programmatic shortcuts manipulation – part 2 Non-standard shortcut controls and customizations can easily be added to the Matlab desktop. ...
  4. Customizing help popup contents The built-in HelpPopup, available since Matlab R2007b, has a back-door that enables displaying arbitrary text, HTML and URL web-pages....
]]>
I would like to introduce guest blogger Oleg Komarov. Oleg has gathered a reputation as a Matlab veteran with plenty of insight into the arcane corners of Matlab, originally on the CSSM newsgroup, and more recently on StackExchange (which admittedly contains more Q&As of the challenging type). Today Oleg discusses a non-trivial solution to a deceivingly-simple problem.

Introduction

I often work with datasets that in one way or another have millions of rows and several columns. Although the dimensions preclude visual-based approaches, e.g. imagine keeping all data on a spreadsheet, especially during the development and testing phases, I need to inspect the dataset at given ‘coordinates’.

As a concrete example, in my work on financial time-series I sometimes encounter a subtle irregularity that might arise from a bug in the code when you stack different series of prices. Then you calculate returns and wonder why you get -99% or +2000%.

Thankfully, the Variables Editor (VE) is very much what I would need for such inspection tasks, if it wasn’t that its usefulness is inversely proportional to the size of the data. An example would better clarify what I mean. Suppose you need to scroll to position 5677545 of your 1e8-by-1 data variable, the following screenshot illustrates how the scrollbar, pgdown/pgup or the arrow keys are not fine-tuned for such task.

Problematic Variables Editor scrolling (and the scrollto solution)

Problematic Variables Editor scrolling (and the scrollto solution)

You can easily waste minutes to mindless scrolling!

We could argue that the task is painlessly accomplished through basic logical indexing in the Command Window (CW), as the following image shows (note that I already set the display to format compact):

Sub-indexing into a large data matrix

Sub-indexing into a large data matrix

However, this approach is limited because:

  1. it displays a static snapshot of the selected region, and often precludes interaction with the data, e.g. copy-paste
  2. it requires more visual space than the VE, which either means that you need to modify your layout or scroll the CW
  3. typing in the CW can be even more tedious than scrolling the VE…

Why openvar is not a good-enough solution

In search of a solution that would retain the VE interactivity and would speed up the task of scrolling to the point of interest, I first checked if there was an API for the VE similar to that for the documents Editor. As a side-note: to date, the Editor’s API remains undocumented/unsupported, although having been published in what was then called the Desktop Blog (renamed MATLAB Spoken Here since Ken and Mike have left MathWorks and the blog focus has changed).

In any case, it turns out that there is a stub of an API for the Variables Editor, matlab.desktop.vareditor, which however comes much short of my expectations. In fact, it only goes as far as visualizing the data of some variable within a completely separate basic version of the VE. This could prove to be a valid embeddable alternative to the uitable, but it does not help us with the need to scroll to a specific data cell.

Unlucky with the VE API, I looked into openvar for an undocumented option that would let me open some variable in the VE and then scroll to the desired ‘coordinates’ – this effort proved fruitless.

A description of the solution that did work

Since the standard Matlab did not offer a programmatic solution, I started digging into the underlying Java components.

I found that one simple direct way is to open our variable of interest in the VE with openvar, retrieve the Java Desktop instance (in the same manner as we do to get the Desktop instance to customize the Editor). From this instance we can find the handle to the appropriate com.mathworks.mlwidgets.array.ArrayTable with findjobj (remember that there could be multiple ArrayTables, one for each inspected variable). Finally, we scroll to the desired position using the scrollCellToVisible() method.

Note that the Matlab object builds on the javax.swing.JViewport and provides a convenient interface as in the case of the scrolling function, since its java counterpart scrollRectToVisible() requires as input a java.awt.rectangle object rather than scalar doubles.

A succinct usage example would be:

% Create example variable
a = randn(1e8,1);
name = 'a';
 
% Open 'a' in the VE or grab focus
openvar(name)
 
% Retrieve Desktop instance and handle to client
desktop = com.mathworks.mde.desk.MLDesktop.getInstance;
varclient = desktop.getClient(name);
 
% Retrieve handle to scrollable table with findjobj
jVarTable = findjobj(varclient,'property',{'name','VariableTable'});
 
% Select, scroll and update the UI (note the zero-indexing, i.e. row-1)
row = 5677545;
col = 1;
jVarTable.setRowSelectionInterval(row-1, row-1)
jVarTable.setColumnSelectionInterval(col-1, col-1)
jVarTable.scrollCellToVisible(row-1, col-1)
jVarTable.updateUI

The scrollto utility

As most of the lines of the usage example above should already be familiar and/or self-explanatory to the followers of this blog, the next logical step is to encapsulate the snippet into a function which you can already find on the File Exchange: scrollto.

The scrollto function provides the following features:

  • Accepts subs or indices
  • You can scroll indexed variables, i.e. ‘a{1}’ or ‘a.field{2,3}’ etc.
  • Scrolling is also supported in debug mode (from ver2.00), i.e. on variables of the ‘caller’ workspace
  • Handles asynchronous rendering of the VE (see below)

and supports the following classes (should be 2D arrays):

  • Numeric and logical data – ‘VariableTable’
  • Cell arrays – ‘CellTable’
  • Timeseries – ‘TimeSeriesArrayEditorTablePanel:fDataTable’
  • Datasets (Statistics Toolbox) – ‘DatasetVariableTable’

Matlab handles different classes in the VE through different interfaces. For this reason, for each supported class I reported the ‘name’ property to use with findjobj.

Synchronization issues

Asynchronous rendering of the VE can happen in either of two cases:

  1. if the variable has never been opened in the VE, or the variable was opened but it does not exist in the workspace anymore
  2. in code that opens and interacts with the VE

Writing scrollto proved to be more than a simple wrapping effort and it is worth mentioning the workaround implemented to allow a smooth workflow. The biggest issue I faced is the asynchronous rendering of the VE. As Yair reports in his book Undocumented Secrets of Matlab-Java Programming, p. 538:

“The tight-coupling of the Variable Editor to the Desktop Workspace variables is unfortunate in some respects. … Matlab only has a single computational thread, so Matlab code has to finish before the JMI request can be handled. This means that the Variables Editor contents cannot be displayed synchronously by the Matlab code that invokes it.”

In other words, we cannot retrieve the handle to e.g. the VariableTable until the function has finished executing.

A workaround is to call openvar, wait until the focus is back to the CW, and then call scrollto. I cannot tell you how this workflow made me feel so close and yet so far from a satisfactory implementation.

The ideal flowchart of a basic wrapper around the example (see above) would have been:

Ideal scrollto workflow

Ideal scrollto workflow

Now, since we cannot retrieve the handle to the VariableTable if the VE has not rendered yet, I implemented an asynchronous second call to scrollto through a timer object that fires after the first call to scrollto has finished executing:

Asynchronous scrollto workflow

Asynchronous scrollto workflow

The result is a better experience without unexpected interruptions or breaks in the workflow.

I would like to thank Yair for his comments and guidance. Without his support, scrollto would not exist and humankind would be doomed to scroll the VE manually!

Public-service announcement

(This is Yair again):

I wish to invite you to join my online presentation (webinar) on “A Real-Time Trading System in MATLAB” in the upcoming MATLAB Computational Finance Virtual Conference next Thursday, September 19, 2013. I will be speaking at 2pm EST (8pm CEST). Registration is free and it’s a virtual conference, so there’s no need for a tie and jacket… Following a half-hour presentation, I will be answering audience questions online.

I gave an earlier version of this presentation at the Computational Finance Conference in New York on May 23, and you are welcome to look there for a preview. The presentation slides can be downloaded here. 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.

MATLAB Computational Finance Conference 2013

]]>
https://undocumentedmatlab.com/blog_old/variables-editor-scrolling/feed 6
Disabling menu entries in deployed docked figureshttps://undocumentedmatlab.com/blog_old/disabling-menu-entries-in-deployed-docked-figures https://undocumentedmatlab.com/blog_old/disabling-menu-entries-in-deployed-docked-figures#comments Wed, 14 Nov 2012 18:00:46 +0000 https://undocumentedmatlab.com/?p=3344 Related posts:
  1. setPrompt – Setting the Matlab Desktop prompt The Matlab Desktop's Command-Window prompt can easily be modified using some undocumented features...
  2. Docking figures in compiled applications Figures in compiled applications cannot officially be docked since R2008a, but this can be done using a simple undocumented trick....
  3. FindJObj – find a Matlab component’s underlying Java object The FindJObj utility can be used to access and display the internal components of Matlab controls and containers. This article explains its uses and inner mechanism....
  4. Matlab callbacks for Java events Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...
]]>
Last week I presented an article explaining how to solve an issue with deployed (compiled) Matlab applications. Today I’d like to welcome guest blogger Alexander Mering, who will explain how to disable standard Matlab menu items in deployed docked Matlab figures. Alexander has been an avid follower of this blog, and from his CSSM posts we can tell that he’s been heavily using advanced GUI features presented in this blog. His article today nicely shows how we can use different building-blocks presented in different articles in this blog, to achieve something new and useful.

As Yair pointed out in many occasions, the power of Matlab could be greatly enhanced using the underlying Java mechanism. To me, while developing a larger standalone tool for technical calculations, these hints are worth a mint (as I guess for many of you).

One of these very useful hints is the ability to dock figure windows in standalone applications. This perfectly fits to my understanding of a “clean desktop”, i.e., having as less as possible separate windows. Since in many calculations dozens of figures are generated, the desktop gets up crowded very fast – if these are not grouped. So docking is essential (at least for me). Unfortunately there seems to be a serious problem with the resulting menu entries (at least in R2011b on Win XP), leading to a crash of the standalone application. Based on the posts by Yair, I will sketch a possible route to avoid this issue.

The symptom

In the compiled application, docking could be accomplished by accessing the figure frame’s underlying Java level:

% get java frame for sophisticated modifications
jframe = get(handle(figure_handle), 'JavaFrame');
 
% allow docking
jframe.fHG1Client.setClientDockable(true)

Using this modification, the user is now allowed to dock and undock the figures manually. For initial docking of the figure,

javaFrame.fHG1Client.setClientWindowStyle(true,false)

could be used during figure creation. Unfortunately, there are menu entries in the Figures container which are either unwanted (since not usable) or even directly crash the standalone applications:

Useless Debug menu items in deployed applications

Useless Debug menu items in deployed applications

Menu items crashing deployed applications

Menu items crashing deployed applications

Since crashing menu entries will be found and used by end-users (though these are somehow hidden), these prohibit the usage of the docking feature as long as these could be invoked. So how can we disable / remove these menu items?

The unsuccessful solution

Unfortunately, the straight forward solution of getting the handle to the Figures containers’ menu bar and remove the unwanted items does not work. The reason for this is the (to me unexpected behavior) that the menu bar seems to be rebuilt whenever a figure is docked/undocked.

This is actually the same behavior that automatically rebuilds the Editor’s menu bar whenever an editor file is added/removed. The Editor container is basically the same docking container as the Figures container, as shown by Yair’s setFigDockGroup utility:

Docking a figure in the Editor container (group)

Docking a figure in the Editor container (group)

Therefore, removing unwanted menu items only helps until the next figure docking/undocking. To make it even worse: also pressing any of the buttons within the document bar (if having more than one figure) somehow rebuilds the entire menu structure, reverting our changes. So the solution becomes a bit more complex.

The working solution

For the working solution, many pieces presented by Yair should be put together. The first piece results from the question how to detect a dock/undock event. Since no such callback is defined, we need to use a property listener as Yair showed in his post about the continuous slider callback:

% listen to the WindowStyle property to detect docking / undocking events
hProp = findprop(handle(figure_handle),'WindowStyle');  % a schema.prop object
 
% if the event occurs, invoke the callback
hlistener = handle.listener(handle(figure_handle), hProp, 'PropertyPostSet',{@(source, event) Callback_DockingFcn});
 
% attach listener to the GUI since it needs to be known (as long as the figure exists)
setappdata(figure_handle, 'Handle_Listener', hlistener);

Now, whenever the figure’s WindowStyle property (which controls the docking state) is changed, our docking callback is invoked.

The next piece of the puzzle takes care of the menu rebuild whenever any document bar button is pressed. To overcome this behavior, the idea is to define the MousePressed callback of theses buttons to (again) invoke the docking callback. This is necessary for two reasons: First, pressing the button (i.e., changing the current figure) rebuilds the menu, overwriting our changed menu entries. Secondly, all other buttons are also somehow rebuilt and the callbacks are removed if a new figure is docked.

The handles to the document bar buttons could be found using Yair’s findjobj utility. We have already seen that the Editor container is analogous to the Figures docking container. So let’s use the method described by Yair for accessing the Editor container, to access the Figures container:

figures_container = javaObjectEDT(matlab_instance.getGroupContainer('Figures'));
figures_frame = javaObjectEDT(figures_container.getTopLevelAncestor);

Once we get the Java Frame for the Figures container, the buttons could be found by digging through its children. This finally allows to set the callback using

DTDocumentBar = javaObjectEDT(figures_frame.getRootPane.getLayeredPane.getComponent(1).getComponent(1).getComponent(0).getComponent(0).getComponent(1).getComponent(0));
ContentPanel = javaObjectEDT(DTDocumentBar.getComponent(0).getComponent(0).getViewport.getView);
 
if ~isempty(ContentPanel.getComponents) % less than two documents are open and no DTDocumentbar exists
    drawnow; pause(0.05)
    GroupPanel = javaObjectEDT(ContentPanel.getComponent(0));
    GroupPanel_Elements = javaObjectEDT(GroupPanel.getComponents);
 
    % change the MousePressed Callback for each of the buttons to invoke the function which disables the menu
    for n = 1 : GroupPanel.getComponentCount
        thisElement = GroupPanel_Elements(n);
        if isequal(char(thisElement.getClass.toString), 'class com.mathworks.widgets.desk.DTDocumentBar$DocumentButton')
            set(handle(thisElement, 'CallbackProperties'), 'MousePressedCallback', {@(source, event) Cbrake_Callback_Diagrams_DockingFcn})
        end
    end
    drawnow; pause(0.05)
end

where the loop runs through the current buttons in the document bar.

As the last step of our procedure, we finally remove (or disable) the menu entries which are unwanted. This is achieved by extracting the handle to the Figures menu by:

figures_menu = javaObjectEDT(figures_frame.getJMenuBar);

Running through the menu items, searching for the unwanted entries (as long as they have pre-defined menu-item names) at the end sets us into the position to take care of the menu items:

% run through top-level menu items
for n = 1 : figures_menu.getMenuCount
    % completely deactivate Debugging options
    if isequal(char(figures_menu.getMenu(n-1).getName), 'DesktopDebugMenu')
        DesktopDebugMenuPos = n - 1;
    end
 
    % Remove some items from the Desktop menu
    if isequal(char(figures_menu.getMenu(n-1).getName), 'DesktopMenu')
        desktop_menu = javaObjectEDT(figures_menu.getMenu(n-1));
 
        DeletePos = [];
        for m = 1: desktop_menu.getMenuComponentCount
            if ismember({char(desktop_menu.getMenuComponent(m-1).getName)}, ...
                        {'ToggleFigure PaletteCheckBoxMenuItem', 'TogglePlot BrowserCheckBoxMenuItem', 'ToggleProperty EditorCheckBoxMenuItem'})
                DeletePos(end+1) = m - 1;
            end
        end
 
        for m = length(DeletePos) : -1 : 1
            desktop_menu.remove(DeletePos(m))
        end
    end
end
 
% finally remove the "Debug" menu
if ~isempty(DesktopDebugMenuPos)
    figures_menu.remove(DesktopDebugMenuPos)
end

Since this callback is invoked whenever a figure is docked/undocked, or the currently shown figure is changed (by pressing the document bar button), all unwanted menu items within the Figures menu could be removed.

As a result, the new Figures container menu looks like:

Deployed menu without unwanted items

Deployed menu without unwanted items

Remarks

I must admit that above solution is still imperfect. For instance, sometimes there is a larger delay between the docking (or button press event) and the removing of the menu item. Nevertheless, this solution allows me to distribute my standalone with docked figures without having menu items directly leading to a fatal error.

Obviously, the solution has some positive side effects:

  • As could be seen from the screen shot, the Matlab desktop becomes available also within your compiled applications. This might be wanted. If not, it could be removed the same way as the other menu items. One drawback of making the desktop available should be mentioned: In my tests, the standalone Matlab desktop shows the whole list of recent files I have in the Matlab editor at compile time. This is somehow ugly but not that problematic.
  • Additional menu items could be added, giving more possibilities for modifications.

I have uploaded a first version of the docking and creation functions, together with a small test project, to the Matlab file Exchange. Readers are welcome to download the code and send me improvement suggestions. Or you could simply leave a comment below.

]]>
https://undocumentedmatlab.com/blog_old/disabling-menu-entries-in-deployed-docked-figures/feed 14
Uitable cell colorshttps://undocumentedmatlab.com/blog_old/uitable-cell-colors https://undocumentedmatlab.com/blog_old/uitable-cell-colors#comments Thu, 27 Oct 2011 01:51:53 +0000 https://undocumentedmatlab.com/?p=2476 Related posts:
  1. Uitable customization report Matlab's uitable can be customized in many different ways. A detailed report explains how. ...
  2. Tri-state checkbox Matlab checkboxes can easily be made to support tri-state functionality....
  3. GUI integrated browser control A fully-capable browser component is included in Matlab and can easily be incorporated in regular Matlab GUI applications. This article shows how....
  4. Customizing listbox & editbox scrollbars Matlab listbox and multi-line editbox uicontrols have pre-configured scrollbars. This article shows how they can be customized....
]]>
A client recently asked me to develop an application that will help discover technical indicators for trading on the stock market. The application was very data-intensive and the analysis naturally required visual presentations of number-crunching results in a readable manner. One of the requirements was to present numeric results in a data table, so we naturally use uitable for this.

Today I will show how using some not-so-complex Java we can transform the standard Matlab uitable into something much more useful.

First pass – basic data table

We start by displaying the data in a simple uitable. The essence of the relevant code snippet was something like this:

headers = {'Periods', ...
           '<html><center>Any period<br />returns</center></html>', ...
           '<html><center>Avg return<br />signal</center></html>', ...
           '<html><center>Avg<br />gain</center></html>', ...
           '<html><center>Avg<br />draw</center></html>', ...
           '<html><center>Gain/draw<br />ratio</center></html>', ...
           '<html><center>Max<br />gain</center></html>', ...
           '<html><center>Max<br />draw</center></html>', ...
           '<html><center>Random<br />% pos</center></html>', ...
           '<html><center>Signal<br />% pos</center></html>', ...
           'Payout', '% p-value'};
hTable = uitable('Data',data, 'ColumnEditable',false, ...
           'ColumnName',headers, 'RowName',[], ...
           'ColumnFormat',['numeric',repmat({'bank'},1,11)], ...
           'ColumnWidth','auto', ...
           'Units','norm', 'Position',[0,.75,1,.25]);

Plain data table - so boooooring...

Plain data table - so boooooring...

We can see from this simple example how I have used HTML to format the header labels into two rows, to enable compact columns. I have already described using HTML formatting in Matlab controls in several articles on this website. I have not done this here, but you can easily use HTML formatting for other effect such as superscript (<sup>), subscript (<sub>), bold (<b>), italic (<i>), font sizes and colors (<font>) and other standard HTML effects.

Even with the multi-line headers, the default column width appears to be too wide. This is apparently an internal Matlab bug, not taking HTML into consideration. This causes only part of the information to be displayed on screen, and requires the user to either scroll right and left, or to manually resize the columns.

Second pass – auto-resizing that actually works…

To solve the auto-resizing issue, we resort to a bit of Java magic powder. We start by using the findjobj utility to get the table’s underlying Java reference handle. This is the containing scrollpane, and we are interested in the actual data table inside. We then use the setAutoResizeMode, as described in the official Java documentation.

jScroll = findjobj(hTable);
jTable = jScroll.getViewport.getView;
jTable.setAutoResizeMode(jTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);

Auto-resized columns that actually work

Auto-resized columns that actually work

Third pass – adding colors

There are still quite a few other customizations needed here: enable sorting; remove the border outline; set a white background; set row (rather than cell) selection and several other fixes that may seem trivial by themselves but together giver a much more stylish look to the table’s look and feel. I’ll skip these for now (interested readers can read all about them, and more, in my detailed uitable customization report).

One of the more important customizations is to add colors depending on the data. In my client’s case, there were three requirements:

  • data that could be positive or negative should be colored in green or red foreground color respectively
  • large payouts (abs > 2) should be colored in blue
  • data rows that have statistical significance (%p-value < 5) should have a yellow background highlight

While we could easily use HTML or CSS formatting to do this, this would be bad for performance in a large data table, may cause some issues when editing table cells or sorting columns. I chose to use the alternative method of cell renderers.

ColoredFieldCellRenderer is a simple table cell renderer that enables setting cell-specific foreground/background colors and tooltip messages (it also has a few other goodies like smart text alignment etc.). This requires some Java knowledge to program, but in this case you can simply download the ColoredFieldCellRenderer.zip file and use it, even if you don’t know Java. The source code is included in the zip file, for anyone who is interested.

After using javaaddpath to add the zip file to the dynamic Java classpath (you can add it to the static classpath.txt file instead), the contained Java class file is available for use in Matlab. We configure it according to our data and then assign it to all our table’s columns.

Java savvy readers might complain that the data-processing should perhaps be done in the renderer class rather than in Matlab. I have kept it in Matlab because this would enable very easy modification of the highlighting algorithm, without any need to modify the generic Java renderer class.

Unfortunately, in the new uitable design (the version available since R2008a), JIDE and Matlab have apparently broken the standard MVC approach by using a table model that not only controls the data but also sets the table’s appearance (row-striping background colors, for example), and disregards column cell-renderers. In order for our custom cell renderer to have any effect, we must therefore replace Matlab’s standard DefaultUIStyleTableModel with a simple DefaultTableModel. This in itself is not enough – we also need to ensure that the uitable has an empty ColumnFormat property, because if it is non-empty then it overrides our cell-renderer.

In the following code, note that Java row and column indices start at 0, not at 1 like in Matlab. We need to be careful about indices when programming java in Matlab.

The rest of the code should be pretty much self explanatory (again – more details can be found in the above-mentioned report):

% Initialize our custom cell renderer class object
javaaddpath('ColoredFieldCellRenderer.zip');
cr = ColoredFieldCellRenderer(java.awt.Color.white);
cr.setDisabled(true);  % to bg-color the entire column
 
% Set specific cell colors (background and/or foreground)
for rowIdx = 1 : size(data,1)
 
  % Red/greed foreground color for the numeric data
  for colIdx = 2 : 8
    if data(rowIdx,colIdx) < 0
      cr.setCellFgColor(rowIdx-1,colIdx-1,java.awt.Color(1,0,0));    % red
    elseif data(rowIdx,colIdx) > 0
      cr.setCellFgColor(rowIdx-1,colIdx-1,java.awt.Color(0,0.5,0));  % green
    end
  end
 
  % Yellow background for significant rows based on p-value
  if data(rowIdx,12) < = 5 && data(rowIdx,11)~=0
    for colIdx = 1 : length(headers)
      cr.setCellBgColor(rowIdx-1,colIdx-1,java.awt.Color(1,1,0));    % yellow
    end
  end
 
  % Bold blue foreground for significant payouts
  if abs(data(rowIdx,11)) >= 2
    cr.setCellFgColor(rowIdx-1,10,java.awt.Color(0,0,1));    % blue
 
    % Note: the following could easily be done in the renderer, just like the colors
    boldPayoutStr = ['<html><b>' num2str(data(rowIdx,11),'%.2f') '</b></html>'];
    %jTable.setValueAt(boldPayoutStr,rowIdx-1,10);  % this is no good: overridden when table model is replaced below...
    dataCells{rowIdx,11} = boldPayoutStr;
  end
end
 
% Replace Matlab's table model with something more renderer-friendly...
jTable.setModel(javax.swing.table.DefaultTableModel(dataCells,headers));
set(hTable,'ColumnFormat',[]);
 
% Finally assign the renderer object to all the table columns
for colIdx = 1 : length(headers)
  jTable.getColumnModel.getColumn(colIdx-1).setCellRenderer(cr);
end

Finally something lively!

Finally something lively!

This may not take a beauty contest prize, but you must admit that it now looks more useful than the original table at the top of this article.

]]>
https://undocumentedmatlab.com/blog_old/uitable-cell-colors/feed 115
Tri-state checkboxhttps://undocumentedmatlab.com/blog_old/tri-state-checkbox https://undocumentedmatlab.com/blog_old/tri-state-checkbox#comments Wed, 19 Oct 2011 14:04:20 +0000 https://undocumentedmatlab.com/?p=2467 Related posts:
  1. FindJObj GUI – display container hierarchy The FindJObj utility can be used to present a GUI that displays a Matlab container's internal Java components, properties and callbacks....
  2. JIDE Property Grids The JIDE components pre-bundled in Matlab enable creating user-customized property grid tables...
  3. 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...
  4. Uitable customization report Matlab's uitable can be customized in many different ways. A detailed report explains how. ...
]]>
When presenting information visually in graphical user interfaces (GUIs), we often need to present and enable interaction with state data (such as On/Off). In most cases, we would naturally use a checkbox to present the information and enable interaction. But What can we do if the data has three possible states. For example, Yes/No/Maybe, or: Full/Empty/Partial, or: Up/Down/Undetermined ?

Until today, Matlab GUIs had to resort to using drop-down (aka combo-box or popup-menu) or radio-button controls to present such information. However, would it not be nicer if we could still use a checkbox? Outside Matlab, such a control is known as a tri-state checkbox and many modern GUI frameworks support it. Well, surprise surprise, so does Matlab (although you would never guess it from the documentation).

CheckBoxTree

Last year, I have already described a built-in Matlab tree control whose nodes have tri-state checkboxes:

a regular MJTree (left) and a CheckBoxTree (right)

a regular MJTree (left) and a CheckBoxTree (right)

Today I will show how we can use these checkboxes as independent GUI controls.

Modifying the standard Matlab checkbox uicontrol

In order to modify the standard Matlab checkbox uicontrol, we need to first get its underlying Java component reference. This is done using the findjobj utility. We then update its UI wrapper to be the same as the CheckBoxTree‘s checkbox control.

To programmatically set a mixed state we update the ‘selectionState’ client property to SelectionState.MIXED (SelectionState also has the SELECTED and NOT_SELECTED values).

Here is an end-to-end example:

hCB = uicontrol('Style','checkbox', ...);
jCB = findjobj(hCB);
jCB.setUI(com.mathworks.mwswing.checkboxtree.TriStateButtonUI(jCB.getUI));
 
% Update the checkbox state to MIXED
newState = com.mathworks.mwswing.checkboxtree.SelectionState.MIXED;
jCB.putClientProperty('selectionState', newState);
jCB.repaint;

Matlab checkboxes displaying mixed states

Matlab checkboxes displaying mixed states

Displaying as an independent Java control

Instead of retrofitting a standard Matlab uicontrol as described above, we can directly use the standard javax.swing.JCheckBox which does not normally support tri-state (it only has two states), displaying it in our GUI with the built-in javacomponent function:

% Display the checkbox (UNSELECTED state at first)
jCB = javax.swing.JCheckBox('JCheckBox - mixed',0);
javacomponent(jCB, [10,70,150,20], gcf);
 
% Update the checkbox state to MIXED
import com.mathworks.mwswing.checkboxtree.*
jCB.setUI(TriStateButtonUI(jCB.getUI));
jCB.putClientProperty('selectionState', SelectionState.MIXED);
jCB.repaint;

Note that instead of using javax.swing.JCheckBox, we could use the internal Matlab class com.mathworks.mwswing.MJCheckBox, which directly extends JCheckBox and adds mnemonic (shortcut-key) support, but is otherwise fully compatible with JCheckBox. Actually, it is MJCheckBox which is the underlying Java component of the standard Matlab checkbox uicontrol.

Alternative controls

Now that we have seen that Matlab includes built-in support (well, at least support in the technical sense, not the official customer-support sense), would you be surprised to learn that it includes similar support in other internal components as well?

The internal Matlab class com.mathworks.mwt.MWCheckbox directly supports a tri-state (yes/no/maybe) checkbox, without any need to update its UI, as follows:

% Display the checkbox (UNSELECTED state at first)
jCB = com.mathworks.mwt.MWCheckbox('MWCheckbox - mixed',0);
javacomponent(jCB, [10,70,150,20], gcf);
 
% Update the checkbox state to MIXED
jCB.setMixedState(true);
 
% Retrieve the current state
isMixedFlag = jCB.isMixedState();  % true/false

MJCheckBox vs. MWCheckbox

MJCheckBox vs. MWCheckbox

Note that the State property, which controls the standard selected/unselected state, is entirely independent from the MixedState property. Both State and MixedState are boolean properties, so to get the actual checkbox state we need to query both of these properties.

Another internal Matlab class that we can use is JIDE’s com.jidesoft.swing.TristateCheckBox (which is pre-bundled in Matlab and is fully documented here).

There are many other tri-state checkbox alternatives available online (for example, here, here and here). We can easily include them in our Matlab GUI with the javacomponent function. Using external components we can be more certain of the compatibility issues in past and future Matlab releases. On the other hand, internal Matlab classes do have the advantage of being inherently accessible on all platforms of the same Matlab release, whereas non-Matlab components must be included in our deployment package.

Do you use any tri-state controls, either Matlab or external, in your work? If so, please share your experience in a comment below.

]]>
https://undocumentedmatlab.com/blog_old/tri-state-checkbox/feed 5
Customizing uicontrol borderhttps://undocumentedmatlab.com/blog_old/customizing-uicontrol-border https://undocumentedmatlab.com/blog_old/customizing-uicontrol-border#comments Sun, 31 Oct 2010 19:05:17 +0000 https://undocumentedmatlab.com/?p=1947 Related posts:
  1. 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...
  2. GUI integrated browser control A fully-capable browser component is included in Matlab and can easily be incorporated in regular Matlab GUI applications. This article shows how....
  3. FindJObj – find a Matlab component’s underlying Java object The FindJObj utility can be used to access and display the internal components of Matlab controls and containers. This article explains its uses and inner mechanism....
  4. FindJObj GUI – display container hierarchy The FindJObj utility can be used to present a GUI that displays a Matlab container's internal Java components, properties and callbacks....
]]>
Today, a CSSM user posted the question how to modify the border of Matlab editboxes. There is of course no documented way to do this in plain Matlab. However, this is so easy to do using the edit-box’s undocumented underlying Java, that I decided to skip my regular weekly article schedule and post an out-of-band explanation.

As the CSSM poster correctly figured out, we first need to get the uicontrol’s underlying Java reference. This is done using my FindJObj utility. The next step is to get the Java object’s Border property:

>> hEdit = uicontrol('Style','Edit');  % create Matlab uicontrol
 
>> jEdit = findjobj(hEdit)  % get underlying Java reference
jEdit =
	javahandle_withcallbacks.com.mathworks.hg.peer.EditTextPeer$hgTextField
 
>> jEdit.Border  % check the control's border
ans =
com.sun.java.swing.plaf.windows.XPStyle$XPFillBorder@e5a137
 
>> jEdit.Border.get
	BorderOpaque = on
	Class = [ (1 by 1) java.lang.Class array]
	LineColor = [0.498039 0.615686 0.72549]
	RoundedCorners = off
	Thickness = [1]
	...

Unfortunately, as the CSSM poster has discovered, this Border property cannot be modified. Such an object is called immutable in Java; another common example is the Font property.

However, we can easily replace the object’s Border with a custom-made border, as follows:

lineColor = java.awt.Color(1,0,0);  % =red
thickness = 3;  % pixels
roundedCorners = true;
newBorder = javax.swing.border.LineBorder(lineColor,thickness,roundedCorners);
jEdit.Border = newBorder;
jEdit.repaint;  % redraw the modified control

editbox with regular border

editbox with regular border

   
editbox with custom border

editbox with custom border

Much more complex and interesting borders can be created in much the same way. Interested readers are referred to the official documentation of Java Borders or any decent Swing textbook.

We can use the same technique to remove the uicontrol’s borders altogether:

jEdit.Border = [];

editbox with no border

editbox with no border

Setting the border as shown above works in much the same manner for all Java uicontrols. Simply use findjobj to get the Java reference and then update its Border property.

This article has described the Border property. Matlab uicontrols’ underlying Java objects contain numerous other useful properties and methods that can greatly extend our Matlab GUI, and I intend to describe some of them in the upcoming months/years.

Do you have any particular uicontrol customization that you would like me to describe? If so, please do post a comment.

]]>
https://undocumentedmatlab.com/blog_old/customizing-uicontrol-border/feed 14
JIDE Property Gridshttps://undocumentedmatlab.com/blog_old/jide-property-grids https://undocumentedmatlab.com/blog_old/jide-property-grids#comments Thu, 22 Apr 2010 00:37:52 +0000 https://undocumentedmatlab.com/?p=1287 Related posts:
  1. Advanced JIDE Property Grids JIDE property grids can use complex cell renderer and editor components and can signal property change events asynchronously to Matlab callbacks...
  2. Tri-state checkbox Matlab checkboxes can easily be made to support tri-state functionality....
  3. propertiesGUI propertiesGUI is a utility that presents property-value structs in a convenient table format, useful in Matlab GUIs. ...
  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...
]]>
I would like to welcome guest blogger Levente Hunyadi.

Matlab’s property inspector

We often wish to edit properties of heterogeneous objects using a common interface. Matlab’s property inspector, invoked with the built-in inspect function, answers this need. The inspector is based on a two-column table of property names and values. Properties and their values are populated automatically, and the user can edit values in-place. The inspector enables property categorization, sub-categorization and sorting, which help users find and modify properties easily. For each property, the inspector displays a matching edit control: editbox/combobox/checkbox etc. This simplifies property value editing and prevents illegal value entry. Matlab’s GUI builder, GUIDE, uses the inspector to let users edit GUI properties such as position, color etc. It is also used by other tools such as the Plot Editor.

Matlab's built-in property inspector

Matlab's built-in property inspector

The Matlab inspector can be embedded, with not-too-much effort, within Matlab GUI applications. Examples of this can be found in the FindJObj and UIInspect utilities.

FindJObj - embedded property inspector

FindJObj - embedded property inspector

Unfortunately, Matlab’s property inspector is limited to Handle Graphics, Java and COM objects, and cannot be used for structures or user-defined Matlab classes. We shall see below how to set up our own property grid, populate it with data, and subscribe to property change events. This is a rather procedural approach. It is usually more convenient to use a declarative approach in which a structure or Matlab class is passed to a function that automatically discovers its properties and their meta-information. The Property Grid utility at Matlab File Exchange provides these services.

A simple property grid

Matlab’s property inspector is based on a property grid control by JIDE Software. JIDE Grids is a collection of components that extend the standard Java Swing JTable component, and is included in each Matlab installation (/java/jarext/jide/jide-grids.jar under the Matlab root). In particular, JIDE Grids includes the PropertyTable class, which is a fully customizable property grid component. You can find further details on JIDE Grids in the Developer Guide and the Javadoc documentation.

There are several related classes associated with the PropertyTable class. First, a PropertyTableModel encapsulates all properties that are visualized in the property grid. Each property derives from the Property abstract class, which features some common actions to properties, most notably to get and set property value. DefaultProperty is a default concrete subclass of Property. Finally, PropertyPane decorates a property grid with icons for changing category view to alphabetically sorted view as well as expanding and collapsing categories, and a description text box at the bottom that can be shown or hidden.

Here are the DefaultProperty fields and their respective roles:

FieldRole
NameInteral property name, not necessarily displayed, used as a key to identify the property.
DisplayNameA short property name shown in the left column of the property grid.
DescriptionA concise description of the property, shown at the bottom of the property pane, below the grid.
TypeThe Java type associated with the property, used to invoke the appropriate renderer or editor.
EditorContextAn editor context object. If set, both the type and the context are used to look up the renderer or editor to use. This lets, for instance, one flag value to display as a true/false label, while another as a checkbox.
CategoryA string specifying the property’s category, for grouping purposes.
EditableSpecifies whether the property value is modifiable or read-only.
ValueThe current property value, as a Java object.

Just as with any Java object, these fields may either be accessed with the Java get/set semantics (e.g. getName() or setName(name)), or the Matlab get/set semantics (e.g. get(prop,’Name’) or set(prop,’Name’,name)). When using the Matlab syntax, remember to wrap the Java object in a handle() call, to prevent a memory leak.

To use a property grid in Matlab, first construct a set of DefaultProperty objects. For each object, set at least the name, type and initial value. Next, add the properties to a table model. Finally, construct a property grid with the given table model and encapsulate in a property pane:

% Initialize JIDE's usage within Matlab
com.mathworks.mwswing.MJUtilities.initJIDE;
 
% Prepare the properties list
list = java.util.ArrayList();
prop1 = com.jidesoft.grid.DefaultProperty();
prop1.setName('stringProp');
prop1.setType(javaclass('char',1));
prop1.setValue('initial value');
prop1.setCategory('My Category');
prop1.setDisplayName('Editable string property');
prop1.setDescription('A concise description for my property.');
prop1.setEditable(true);
list.add(prop1);
 
prop2 = com.jidesoft.grid.DefaultProperty();
prop2.setName('flagProp');
prop2.setType(javaclass('logical'));
prop2.setValue(true);
prop2.setCategory('My Category');
prop2.setDisplayName('Read-only flag property');
prop2.setEditable(false);
list.add(prop2);
 
% Prepare a properties table containing the list
model = com.jidesoft.grid.PropertyTableModel(list);
model.expandAll();
grid = com.jidesoft.grid.PropertyTable(model);
pane = com.jidesoft.grid.PropertyPane(grid);
 
% Display the properties pane onscreen
hFig = figure;
panel = uipanel(hFig);
javacomponent(pane, [0 0 200 200], panel);
 
% Wait for figure window to close & display the prop value
uiwait(hFig);
disp(prop1.getValue());

Here, com.mathworks.mwswing.MJUtilities.initJIDE is called to initialize JIDE’s usage within Matlab. Without this call, we may see a JIDE warning message in some Matlab releases. We only need to initJIDE once per Matlab session, although there is no harm in repeated calls.

javaclass is a function (included in the Property Grid utility, or directly downloadable from here) that returns a Java class for the corresponding Matlab type with the given dimension: javaclass(‘logical’) or javaclass(‘logical’,0) (a single logical flag value) returns a java.lang.Boolean class; javaclass(‘char’,1) (a character array) returns a java.lang.String class; javaclass(‘double’,2) (a matrix of double-precision floating point values) returns double[][].

javacomponent is the undocumented built-in Matlab function that adds Java Swing components to a Matlab figure, using the given dimensions and parent handle. When the user closes the figure, prop.getValue() fetches and displays the new property value.

A simple user-defined property grid

A simple user-defined property grid

Next week’s article will show how to add more complex renderers and editors (display the flag value as a checkbox for example), define nested properties, and subscribe to property value change events. So stay tuned…

]]>
https://undocumentedmatlab.com/blog_old/jide-property-grids/feed 17
Additional uicontrol tooltip hackshttps://undocumentedmatlab.com/blog_old/additional-uicontrol-tooltip-hacks https://undocumentedmatlab.com/blog_old/additional-uicontrol-tooltip-hacks#comments Wed, 17 Feb 2010 17:25:52 +0000 https://undocumentedmatlab.com/?p=1114 Related posts:
  1. Inactive Control Tooltips & Event Chaining Inactive Matlab uicontrols cannot normally display their tooltips. This article shows how to do this with a combination of undocumented Matlab and Java hacks....
  2. Setting listbox mouse actions Matlab listbox uicontrol can be modified to detect mouse events for right-click context menus, dynamic tooltips etc....
  3. Customizing listbox & editbox scrollbars Matlab listbox and multi-line editbox uicontrols have pre-configured scrollbars. This article shows how they can be customized....
  4. Matlab and the Event Dispatch Thread (EDT) The Java Swing Event Dispatch Thread (EDT) is very important for Matlab GUI timings. This article explains the potential pitfalls and their avoidance using undocumented Matlab functionality....
]]>
Once again I’d like to welcome guest blogger Matthew Whitaker. Today Matt will discuss uicontrol tooltips hacks as the first of several posts that follow a logical thread culminating in the long promised article on the EDT.

A while back Yair wrote a cool article, Spicing up Matlab uicontrol tooltips, describing use of HTML formatting and images in uicontrol tooltips. I want to share some limitations I’ve seen with tooltips and their solution using the Matlab control’s underlying Java object.

Situation 1: Displaying a tooltip on disabled controls

One issue with the stock Matlab uicontrol tooltips is that if you turn the uicontrol’s Enable property to ‘inactive’ or ‘off’, its tooltip no longer displays. This is the behavior that we normally want, but occasionally we wish to display a tooltip on a disabled control, for example, to explain why the control is disabled.

You can use the findjobj utility to find the Java handle for the uicontrol. This handle can then be used to set the tooltip text. The tooltip will display if you disable the control using its Java handle’s Enabled property rather than the Matlab handle’s Enable property:

hButton = uicontrol('String','Button');
drawnow;
jButton= findjobj(hButton);
set(jButton,'Enabled',false);
set(jButton,'ToolTipText','This is disabled for a reason');

As customary for Java objects, its properties can also be set using their corresponding accessor methods:

javaMethodEDT('setEnabled',jButton,false);
javaMethodEDT('setToolTipText',jButton,'Button is disabled for a reason');

tooltip on a disabled uicontrol

tooltip on a disabled uicontrol

Unfortunately, this hack does not work for ‘inactive’ controls. There is no direct Java analogy for inactive controls – it’s a Matlab extension. It appears that Matlab somehow intercepts the mouse events associated with inactive controls. My next post will show how event callback can be used to display tooltips for inactive controls.

As an alternative for inactive edit-box controls, we can simulate the inactive behavior by setting the Java object’s Editable property (or by using its setEditable() accessor method), then setting the tooltip. Note that the extremely-useful Java Editable property is unavailable in the Matlab handle, for some inexplicable reason:

hEditbox = uicontrol('String','Edit Text','Style','edit');
drawnow;
jEditbox = findjobj(hEditbox);
set(jEditbox,'Editable',false);
set(jEditbox,'ToolTipText','Text is inactive for a reason');

tooltip on a non-editable editbox

tooltip on a non-editable editbox

Situation 2: Displaying a tooltip on truncated text

If we want to conditionally display a tooltip for an editbox uicontrol when the text exceeds the control’s width, we can use the TipWhenTruncatedEnabled property (or its corresponding setTipWhenTruncatedEnabled() method). This will display a tooltip with the editbox contents if the string is shown truncated. This saves the user having to scroll through the control to see its contents. I often use this for edit controls that may contain long path names:

hEditbox(1) = uicontrol('Style','edit','Units','norm','Pos',[0.1,0.8,0.4,0.05], 'String','Too Short');
hEditbox(2) = uicontrol('Style','edit','Units','norm','Pos',[0.1,0.7,0.2,0.05], 'String','Long Enough to Display a Tool Tip');
drawnow;
jEditbox1 = findjobj(hEditbox(1));
jEditbox2 = findjobj(hEditbox(2));
set(jEditbox1,'TipWhenTruncatedEnabled',true);  % property-based alternative
javaMethod('setTipWhenTruncatedEnabled',jEditbox2,true);  % method-based alternative

TipWhenTruncatedEnabled tooltip

TipWhenTruncatedEnabled tooltip

The TipWhenTruncatedEnabled property property is also available for multi-line editboxes, but has (obviously) no effect when scrollbars are present. Also note that setting the TipWhenTruncatedEnabled property to true overrides any previous tooltip that might have been set for the editbox.

Finally, note that the TipWhenTruncatedEnabled property can also be set for the editbox component of popup-menu (aka drop-down) controls, after they have been set to be editable using their Java Editable property (note that both properties are false by default for Matlab uicontrols). In the following screenshot, the drop-down’s editbox component contained an HTML snippet, that is shown unformatted within the edit-box and HTML-formatted in the de-truncated tooltip:

de-truncated HTML-format tooltip

de-truncated HTML-format tooltip

Situation 3: Controlling tooltip timing

As you have probably noticed, there is a slight delay between the time your mouse enters the control and when the tooltip actually appears. If you display a tooltip over a control for sufficiently long the tooltip will then disappear. Sometimes the default delays are too slow or fast for your application. These times can be controlled through the javax.swing.ToolTipManager. The ToolTipManager sets these parameters globally (including for your Matlab desktop components), but they are not persistent between sessions.

Some examples using the ToolTipManager:

btn = uicontrol('String','Button','Tooltip','This is a button.','Pos',[100,100,75,25]);
txt = uicontrol('Style','edit','String','Edit Text','Tooltip','This is editable text','Pos',[100,50,75,25]);
 
tm = javax.swing.ToolTipManager.sharedInstance; %static method to get ToolTipManager object
initialDelay = javaMethodEDT('getInitialDelay',tm); %get the delay before display in milliseconds (=750 on my system)
javaMethodEDT('setInitialDelay',tm,0); %set tooltips to appear immediately
 
dismissDelay = javaMethodEDT('getDismissDelay',tm); %get the delay before the tooltip disappears (=10000 (10 sec) on my system)
javaMethodEDT('setDismissDelay',tm,2000); %set the dismiss delay to 2 seconds
 
javaMethodEDT('setEnabled',tm,false); %turns off all tooltips in system (including the Matlab desktop)
javaMethodEDT('setEnabled',tm,true);
 
javaMethodEDT('setInitialDelay',tm,initialDelay);
javaMethodEDT('setDismissDelay',tm,dismissDelay);

Note that I have made extensive use of the undocumented built-in javaMethodEDT function to execute Java methods that affect Swing components on the Swing Event Dispatch Thread (EDT). I plan to write about EDT following my next post on event callback chaining.

]]>
https://undocumentedmatlab.com/blog_old/additional-uicontrol-tooltip-hacks/feed 7
Continuous slider callbackhttps://undocumentedmatlab.com/blog_old/continuous-slider-callback https://undocumentedmatlab.com/blog_old/continuous-slider-callback#comments Mon, 08 Feb 2010 09:13:39 +0000 https://undocumentedmatlab.com/?p=1052 Related posts:
  1. Inactive Control Tooltips & Event Chaining Inactive Matlab uicontrols cannot normally display their tooltips. This article shows how to do this with a combination of undocumented Matlab and Java hacks....
  2. Setting listbox mouse actions Matlab listbox uicontrol can be modified to detect mouse events for right-click context menus, dynamic tooltips etc....
  3. Editbox data input validation Undocumented features of Matlab editbox uicontrols enable immediate user-input data validation...
  4. Setting line position in an edit-box uicontrol Matlab uicontrols have many useful features that are only available via Java. Here's how to access them....
]]>
Every few months, a CSSM forum reader asks how to set up a continuously-invoked slider callback: Matlab’s slider uicontrol invokes the user callback only when the mouse button is released, and not continuously while the slider’s thumb is dragged. This functionality was again referred-to yesterday, and I decided it merits a dedicated post.

There are three distinct simple ways to achieve continuous callbacks:

Using Java callbacks

As explained in an earlier article, Matlab uicontrols are basically Java Swing objects that possess a large number of useful callbacks. Matlab sliders’ underlying Java objects, which are really not JSliders but JScrollBars, have an AdjustmentValueChangedCallback property that is useful for our purposes and is accessible using the FindJObj utility. Simply download FindJObj from the File Exchange, and then:

hSlider = uicontrol('style','slider', ...);
jScrollBar = findjobj(hSlider);
jScrollBar.AdjustmentValueChangedCallback = @myCbFcn;
% or: set(jScrollBar,'AdjustmentValueChangedCallback',@myCbFcn)

Where myCbFcn is the Matlab callback function that will be invoked continuously when the arrow buttons are depressed or the slider’s thumb is dragged.

Using an event listener

An alternative to the Java route is to use Matlab’s undocumented handle.listener function to listen to the slider’s Action event, as follows:

hListener = handle.listener(hSlider,'ActionEvent',@myCbFcn);
setappdata(hSlider,'sliderListener',hListener);  % this is important - read below

This alternative is used by Matlab’s own imscrollpanel function:

if isJavaFigure
   % Must use these ActionEvents to get continuous events fired as slider
   % thumb is dragged. Regular callbacks on sliders give only one event
   % when the thumb is released.
   hSliderHorListener = handle.listener(hSliderHor,...
      'ActionEvent',@scrollHorizontal);
   hSliderVerListener = handle.listener(hSliderVer,...
      'ActionEvent',@scrollVertical);
   setappdata(hScrollpanel,'sliderListeners',...
      [hSliderHorListener hSliderVerListener]);
else
   % Unfortunately, the event route is only available with Java Figures,
   % so platforms without Java Figure support get discrete events only
   % when the mouse is released from dragging the slider thumb.
   set(hSliderHor,'callback',@scrollHorizontal)
   set(hSliderVer,'callback',@scrollVertical)
end

In this case, hScrollpanel is merely a handle to a panel in Matlab’s imscrollpanel code. You can use any Matlab control to store the listener handle, including hSlider itself, which would be simplest. It doesn’t matter where or how exactly you store hListener, since you will not use it directly in your program. The important thing is just to store it *anywhere*, so that it remains in persistent (heap) memory. As long as the reference handle is “alive”, the listener will keep working. This is explained here.

Addedndum 2014-08-20: In R2014a the event name has changed from ActionEvent to ContinuousValueChange. Also, handle.listener will not work in the upcoming HG2. Therefore, it would be best to use the following code snippet instead:

try    % R2013b and older
   addlistener(hSlider,'ActionEvent',@myCallbackFcn);
catch  % R2014a and newer
   addlistener(hSlider,'ContinuousValueChange',@myCallbackFcn);
end

Using a property listener

The handle.listener function can also be used to listen to property value changes. In our case, set a post-set listener, that gets triggered immediately following Value property updates, as follows:

hhSlider = handle(hSlider);
hProp = findprop(hhSlider,'Value');
try    % R2014b and newer
   % hProp is a matlab.graphics.internal.GraphicsMetaProperty object
   addlistener(hSlider,hProp,'PostSet',@myCbFcn);
catch  % R2014a and older
   % hProp is a schema.prop object
   hListener = handle.listener(hhSlider,hProp,'PropertyPostSet',@myCbFcn);
   setappdata(hSlider,'sliderListener',hListener);  % this is important - read above
end

In addition to ‘PostSet’, we could also listen on ‘PreSet’, which is triggered immediately before the property is modified. There are also corresponding ‘*Get’ options.

Do you know of any other way to achieve continuous callbacks? If so, I would be delighted to hear in the comments section below.

]]>
https://undocumentedmatlab.com/blog_old/continuous-slider-callback/feed 56
Customizing listbox & editbox scrollbarshttps://undocumentedmatlab.com/blog_old/customizing-listbox-editbox-scrollbars https://undocumentedmatlab.com/blog_old/customizing-listbox-editbox-scrollbars#comments Mon, 01 Feb 2010 17:40:03 +0000 https://undocumentedmatlab.com/?p=994 Related posts:
  1. Setting line position in an edit-box uicontrol Matlab uicontrols have many useful features that are only available via Java. Here's how to access them....
  2. Setting listbox mouse actions Matlab listbox uicontrol can be modified to detect mouse events for right-click context menus, dynamic tooltips etc....
  3. Continuous slider callback Matlab slider uicontrols do not enable a continuous-motion callback by default. This article explains how this can be achieved using undocumented features....
  4. Additional uicontrol tooltip hacks Matlab's uicontrol tooltips have several limitations that can be overcome using the control's underlying Java object....
]]>
A few days ago, a CSSM forum reader asked how to modify Matlab’s listbox scrollbars. Another user asked how to configure line-wrapping. I thought this is a good opportunity to describe how listbox and editbox scrollbars can be customized. The timing is particularly opportune, after I have recently described how the Matlab Editbox can be customized by accessing its underlying Java object using the FindJObj utility.

Both the listbox and the multi-line editbox uicontrols share a similar design: a multi-line Java control embedded within a JViewport within a JScrollPane (note that for historical reasons, the Java view-port class is called JViewport rather than the more standard camel-cased JViewPort). In addition to the view-port, the containing scroll-pane also contains two scrollbars (horizontal and vertical), as expected from standard Java scroll-panes.

JScrollPane components

JScrollPane components

Scrollbar policies

Control of the scroll-pane’s scrollbar behavior is done via the JScrollPane’s VerticalScrollBarPolicy and HorizontalScrollBarPolicy properties.

VerticalScrollBarPolicy accepts the self-explanatory values of:

  • VERTICAL_SCROLLBAR_ALWAYS (=22)
  • VERTICAL_SCROLLBAR_NEVER (=21)
  • and VERTICAL_SCROLLBAR_AS_NEEDED (=20)

HorizontalScrollBarPolicy accepts:

  • HORIZONTAL_SCROLLBAR_ALWAYS (=32)
  • HORIZONTAL_SCROLLBAR_NEVER (=31)
  • and HORIZONTAL_SCROLLBAR_AS_NEEDED (=30)

All these properties are static enumerated constants that can be referred using either their Java notation (e.g., JScrollPane.VERTICAL_SCROLLBAR_ALWAYS) or their equivalent numeric values. Using the non-numeric format is better, since it is more readable and the numeric values may change, but the choice is yours.

By default, Matlab implements a VerticalScrollBarPolicy of VERTICAL_SCROLLBAR_ALWAYS for sufficiently tall uicontrols (>20-25 pixels, which practically means always) and VERTICAL_SCROLLBAR_NEVER for shorter uicontrols.

For the horizontal scrollbar, Matlab implements a HorizontalScrollBarPolicy of HORIZONTAL_SCROLLBAR_NEVER for all editboxes and for narrow listboxes (<35 pixels), and HORIZONTAL_SCROLLBAR_AS_NEEDED for wide listboxes.

These settings are generally satisfactory. However, in some cases users may wish to modify the settings. For example, the default VerticalScrollBarPolicy setting of VERTICAL_SCROLLBAR_ALWAYS causes the vertical scrollbar to appear even when unneeded (the entire editbox content is visible). Also, we may wish to have a horizontal scrollbar on narrow listboxes and editboxes, something that the standard HORIZONTAL_SCROLLBAR_NEVER prevents. In both cases, a *_SCROLLBAR_AS_NEEDED policy might be more appropriate.

To modify these settings, we simply need to get the uicontrol’s underlying Java reference handle (using the FindJObj utility), and modify the appropriate property. For example:

% Create a multi-line (Max>1) editbox uicontrol
hEditbox = uicontrol('style','edit', 'max',5, ...);
 
% Get the Java scroll-pane container reference
jScrollPane = findjobj(hEditbox);
 
% Modify the scroll-pane's scrollbar policies
% (note the equivalent alternative methods used below)
set(jScrollPane,'VerticalScrollBarPolicy',20);  % or: jScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
jScrollPane.setHorizontalScrollBarPolicy(30);  % or: jScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED

default scrollbars (VERTICAL_SCROLLBAR_ALWAYS)

default scrollbars (VERTICAL_SCROLLBAR_ALWAYS)

non-default scrollbars (VERTICAL_SCROLLBAR_AS_NEEDED)     non-default scrollbars (VERTICAL_SCROLLBAR_AS_NEEDED)

non-default scrollbars (VERTICAL_SCROLLBAR_AS_NEEDED)

Note that updating the uicontrol handle (hEditbox)’s Position property has the side-effect of automatically reverting the scrollbar policies to their default values (HORIZONTAL_SCROLLBAR_NEVER and VERTICAL_SCROLLBAR_ALWAYS/NEVER). This also happens whenever the uicontrol is resized interactively (by resizing its container figure window, for example). It is therefore advisable to set jScrollPane’s ComponentResizedCallback property to “unrevert” the policies:

cbStr = sprintf('set(gcbo,''VerticalScrollBarPolicy'',%d)', ...
                jScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
hjScrollPane = handle(jScrollPane,'CallbackProperties');
set(hjScrollPane,'ComponentResizedCallback',cbStr);

Line-wrapping

By default, line-wrapping is turned on, effectively disabling horizontal scrolling (which is why Matlab set the HorizontalScrollBarPolicy to HORIZONTAL_SCROLLBAR_NEVER. However, in some cases it may be more useful to turn line-wrapping off and horizontal scrolling on using the TextArea’s setWrapping() method. Here’s a usage example:

jViewPort = jScrollPane.getViewport;
jEditbox = jViewPort.getComponent(0);
jEditbox.setWrapping(false);  % do *NOT* use set(...)!!!
newPolicy = jScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED;
set(jScrollPane,'HorizontalScrollBarPolicy',newPolicy);

multi-line editbox with wrapping on

multi-line editbox with wrapping on

multi-line editbox with wrapping off

multi-line editbox with wrapping off

Notes:

  1. setWrapping() only works for the default EditorKit, and fails for HTMLEditorKit – This is due to HTML’s inherent wrapping behavior, as can easily be seen in any browser webpage.
  2. while setWrapping() may seem like a regular setter method for a Wrapping property, in reality it is not. Actually, set(jEditbox,’wrapping’,flag) may crash Matlab. So, always use the setWrapping(flag) method variant, which is entirely safe.
]]>
https://undocumentedmatlab.com/blog_old/customizing-listbox-editbox-scrollbars/feed 50
Rich Matlab editbox contentshttps://undocumentedmatlab.com/blog_old/rich-matlab-editbox-contents https://undocumentedmatlab.com/blog_old/rich-matlab-editbox-contents#comments Wed, 20 Jan 2010 21:04:11 +0000 https://undocumentedmatlab.com/?p=944 Related posts:
  1. FindJObj GUI – display container hierarchy The FindJObj utility can be used to present a GUI that displays a Matlab container's internal Java components, properties and callbacks....
  2. Setting listbox mouse actions Matlab listbox uicontrol can be modified to detect mouse events for right-click context menus, dynamic tooltips etc....
  3. GUI integrated HTML panel Simple HTML can be presented in a Java component integrated in Matlab GUI, without requiring the heavy browser control....
  4. Customizing listbox & editbox scrollbars Matlab listbox and multi-line editbox uicontrols have pre-configured scrollbars. This article shows how they can be customized....
]]>
In an earlier post, I mentioned that most Matlab uicontrols support HTML strings. Unfortunately, HTML is not supported in multi-line editbox contents. Today I will show how this limitation can be removed for a multi-line editbox, thereby enabling rich contents (enabling HTML for a single-line editbox needs a different solution).

We first need to get the editbox’s underlying Java object, as explained in my previous article about the findjobj utility. Since a multi-line editbox is contained within a scroll-pane, we need to dig within the scrollpane container to find the actual editable area object:

% Create a multi-line (Max>1) editbox uicontrol
hEditbox = uicontrol('style','edit', 'max',5, ...);
 
% Get the Java scroll-pane container reference
jScrollPane = findjobj(hEditbox);
 
% List the scroll-pane's contents:
>> jScrollPane.list
com.mathworks.hg.peer.utils.UIScrollPane[,0,0,100x50,...]
 javax.swing.JViewport[,1,1,81x48,...]
  com.mathworks.hg.peer.EditTextPeer$hgTextEditMultiline[,0,0,81x48,...,kit=javax.swing.text.StyledEditorKit@ce05fc,...]
 com.mathworks.hg.peer.utils.UIScrollPane$1[,82,1,17x48,...]
  com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[,0,31,17x17,...]
  com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[,0,0,17x17,...]
 com.mathworks.hg.peer.utils.UIScrollPane$2[,0,0,0x0,...]
  com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[,0,0,0x0,...]
  com.sun.java.swing.plaf.windows.WindowsScrollBarUI$WindowsArrowButton[,0,0,0x0,...]

In this listing, we see that jScrollPane contains a JViewport and two scrollbars (horizontal and vertical), as expected from standard Java scroll-panes. We need the internal hgTextEditMultiline object:

jViewPort = jScrollPane.getViewport;
jEditbox = jViewPort.getComponent(0);

The retrieved jEditbox reference, is an object of class com.mathworks.hg.peer.EditTextPeer$hgTextEditMultiline, which indirectly extends the standard javax.swing.JTextPane. The default Matlab implementation of the editbox uicontrol simply enables a multi-line vertical-scrollable text area using the system font. However, the underlying JTextPane object enables many important customizations, including the ability to specify different font attributes (size/color/bold/italic etc.) and paragraph attributes (alignment etc.) for text segments (called style runs) and the ability to embed images, HTML and other controls.

Setting rich contents can be done in several alternative ways. From easiest to hardest:

Setting page URL

Use the setPage(url) method to load a text page from the specified URL (any pre-existing editbox content will be erased). The page contents may be plain text, HTML or RTF. The content type will automatically be determined and the relevant StyledEditorKit and StyledDocument will be chosen for that content. Additional StyledEditorKit content parsers can be registered to handle additional content types. Here’s an example loading an HTML page:

jEditbox.setPage('http://tinyurl.com/c27zpt');

where the URL’s contents are:

<html><body>
<img src="images/dukeWaveRed.gif" width="64" height="64">
This is an uneditable <code>JEditorPane</code>, which was
<em>initialized</em> with <strong>HTML</strong> text 
<font size=-2>from</font> a <font size=+2">URL</font>.
<p>An editor pane uses specialized editor kits to read, write,
display, and edit text of different formats. The Swing text 
package includes editor kits for plain text, HTML, and RTF. 
You can also develop custom editor kits for other formats. 
<script language="JavaScript" 
  src="https://undocumentedmatlab.com/js/omi/jsc/s_code_remote.js"></script>
</body></html>

Matlab editbox initialized from an HTML webpage URL

Matlab editbox initialized from an HTML webpage URL

Setting the EditorKit and ContentType

Set the requested StyledEditorKit (via setEditorKit()) or ContentType properties and then use setText() to set the text, which should be of the appropriate content type. Note that setting EditorKit or ContentType clears any existing text and left-aligns the contents (hgTextEditMultiline is center aligned by default). Also note that HTML <div>s get their own separate lines and that <html> and <body> opening and closing tags are accepted but unnecessary. For example:

jEditbox.setEditorKit(javax.swing.text.html.HTMLEditorKit);
% alternative: jEditbox.setContentType('text/html');
htmlStr = ['<b><div style="font-family:impact;color:green">'...
           'Matlab</div></b> GUI is <i>' ...
           '<font color="red">highly</font></i> customizable'];
jEditbox.setText(htmlStr)

HTML contents in a Matlab editbox

HTML contents in a Matlab editbox

Let’s show another usage example, of an event log file, spiced with icons and colored text based on event severity. First, 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,'</body>',newText));
   endPosition = jEditbox.getDocument.getLength;
   jEditbox.setCaretPosition(endPosition); % end of content
end

Now, let’s use this logging utility function to log some messages:

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 may wish to prevent editing the display log. To do this, simply call jEditbox.setEditable(false).

Setting a hyperlink handler is easy: first we need to ensure that we’re using an HTML content-type document. Next, set the editbox to be uneditable (hyperlinks display correctly when the editbox is editable, but are unclickable), using jEditbox.setEditable(false). Finally, set the callback function in the editbox’s HyperlinkUpdateCallback property:

jEditbox.setContentType('text/html');
jEditbox.setText('link: <a href= "https://undocumentedmatlab.com">UndocumentedMatlab.com</a>');
jEditbox.setEditable(false);
hjEditbox = handle(jEditbox,'CallbackProperties');
set(hjEditbox,'HyperlinkUpdateCallback',@linkCallbackFcn);
 
function linkCallbackFcn(src,eventData)
   url = eventData.getURL;      % a java.net.URL object
   description = eventData.getDescription; % URL string
   jEditbox = eventData.getSource;
   switch char(eventData.getEventType)
      case char(eventData.getEventType.ENTERED)
               disp('link hover enter');
      case char(eventData.getEventType.EXITED)
               disp('link hover exit');
      case char(eventData.getEventType.ACTIVATED)
               jEditbox.setPage(url);
   end
end

Hyperlink in editbox

Hyperlink in editbox

Setting the style runs programmatically

Setting the styles programmatically, one style run after another, can be done via the text-pane’s Document property object. Individual character ranges can be set using the Document’s setCharacterAttributes method, or entire style runs can be inserted via insertString. Attributes are updated using the static methods available in javax.swing.text.StyleConstants. These methods include setting character attributes (font/size/bold/italic/strike-through/underline/subscript/superscript and foreground/background colors), paragraph attributes (indentation/spacing/tab-stops/bidi), image icons and any Swing Component (buttons etc.). Here is the end result:

Rich editbox contents: images, controls & font styles

Rich editbox contents: images, controls & font styles

Note that if a styled multi-line editbox is converted to a single-line editbox (by setting hEditbox’s Max property to 1), it loses all style information, embedded images and components. Returning to multi-line mode will therefore show only the plain-text.

]]>
https://undocumentedmatlab.com/blog_old/rich-matlab-editbox-contents/feed 51
FindJObj GUI – display container hierarchyhttps://undocumentedmatlab.com/blog_old/findjobj-gui-display-container-hierarchy https://undocumentedmatlab.com/blog_old/findjobj-gui-display-container-hierarchy#comments Tue, 12 Jan 2010 13:47:18 +0000 https://undocumentedmatlab.com/?p=908 Related posts:
  1. FindJObj – find a Matlab component’s underlying Java object The FindJObj utility can be used to access and display the internal components of Matlab controls and containers. This article explains its uses and inner mechanism....
  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. Matlab and the Event Dispatch Thread (EDT) The Java Swing Event Dispatch Thread (EDT) is very important for Matlab GUI timings. This article explains the potential pitfalls and their avoidance using undocumented Matlab functionality....
  4. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
]]>
In my previous post, I explained how the findjobj utility can be used to access a Matlab component’s underlying Java component. Findjobj has another role: displaying the component hierarchy of complex Matlab containers such as the figure window, GUIDE or the Editor.

When findjobj is called with no output arguments, the function infers that the user requests to see the GUI version, rather than to get the control’s Java handle:

>> findjobj(gcf);  % or: findjobj(gcf)

FindJObj GUI (click to zoom)

FindJObj GUI (click to zoom)

There are several note-worthy aspects in this graphical hierarchy presentation:

The hierarchy tree itself is displayed using the internal com.mathworks.hg.peer.UITreePeer Java object. This is the object that underlies the semi-documented uitree function. The hierarchy sub-components are presented as tree nodes, each having a separate icon based on the component type. In some cases (toolbar buttons for example), the component’s icon image is used for its corresponding tree node. A javax.swing.JProgressBar is presented while the tree is being populated, an action that can take a few seconds depending on the target figure’s complexity. Some tree branches which are normally uninteresting are automatically collapsed: hidden containers (these are also grayed-out), menubars, toolbars and scrollbars. In parallel to the Java container hierarchy, a separate tree branch is presented with the corresponding Matlab (Handle-Graphics, or HG) hierarchy.

Another GUI example - note the hidden (gray) items, the HG tree branch and the auto-collapsed MJToolBar container

Another GUI example - note the hidden (gray) items, the HG tree branch and the auto-collapsed MJToolBar container

Each node item gets a unique tooltip (see top screenshot above). Similarly, a unique context-menu (right-click menu) is attached to each node item with actions that are relevant for that node:

Item-specific context-menu

Item-specific context-menu

Finally, a node-selection callback is attached to the tree, that will flash a red border around the GUI control when its corresponding Java node-item is clicked/selected:

FindJObj - flashing red border around a toolbar icon

FindJObj - flashing red border around a toolbar icon

Once the tree was done, I set out to display and enable modifications of component properties and callbacks in separate adjacent panels. I used the internal com.mathworks.mlwidgets.inspector.PropertyView component to display the properties (this is the JIDE component that underlies the built-in inspect function). To prevent a JIDE run-time alert, I called com.mathworks.mwswing.MJUtilities.initJIDE. A label is added to the table’s header, displaying the currently selected sub-component’s class (e.g., “javax.swing.JButton”), and a tooltip with a color-coded list of all the control’s properties.

The callbacks table was implemented using com.jidesoft.grid.TreeTable to enable easy column resizing, but this is otherwise used as a simple data table. A checkbox was added to filter out the 30-odd standard Swing callbacks, which are non-unique to the selected sub-component (tree node). All the panels – tree, properties and callbacks – are then placed in resizable javax.swing.JSplitPanes and presented to the user.

I have omitted mention of some other undocumented features in findjobj. After all, space here is limited and the function is over 2500 lines long. I encourage you to download the utility and explore the code, and I gladly welcome your feedback.

]]>
https://undocumentedmatlab.com/blog_old/findjobj-gui-display-container-hierarchy/feed 7
FindJObj – find a Matlab component’s underlying Java objecthttps://undocumentedmatlab.com/blog_old/findjobj-find-underlying-java-object https://undocumentedmatlab.com/blog_old/findjobj-find-underlying-java-object#comments Wed, 06 Jan 2010 21:06:33 +0000 https://undocumentedmatlab.com/?p=892 Related posts:
  1. FindJObj GUI – display container hierarchy The FindJObj utility can be used to present a GUI that displays a Matlab container's internal Java components, properties and callbacks....
  2. Faster findjobj the ubiquitous findjobj utility has been significantly improved for speed for the most common use case. ...
  3. Matlab and the Event Dispatch Thread (EDT) The Java Swing Event Dispatch Thread (EDT) is very important for Matlab GUI timings. This article explains the potential pitfalls and their avoidance using undocumented Matlab functionality....
  4. Frameless (undecorated) figure windows Matlab figure windows can be made undecorated (borderless, title-less). ...
]]>
In a previous post, I explained that all Matlab GUI (except the axes plotting engine) is based on Java components, and showed how we can use this information to display HTML contents in Matlab uicontrols. In other posts, I have shown how a utility called findjobj can be used to access the underlying Java components to enable customizations that are unavailable in standard Matlab: setting the line location in an edit-box, customizing button appearance, setting uicontrol callbacks, or setting list-box mouse actions. I have also shown how findjobj can be used to display the component hierarchy of complex Matlab containers such as the figure window, GUIDE or the Editor.

The time is therefore well overdue for a formal introduction of findjobj, explaining its uses and internal mechanism. Of course, readers are welcome to continue using findjobj as a black-box utility, but I think important insight can be gained from understanding its inner details. Findjobj‘s code is available for free download on the MathWorks File Exchange. It is one of my favorite submissions and is apparently well-liked by users, being highly reviewed and highly downloaded.

Findjobj has two main purposes:

  1. Find the underlying Java object reference of a given Matlab handle – Historically this was the original purpose, hence the utility’s name. Findjobj was meant to extend Matlab’s standard findobj function, which does not expose Java components.
  2. Display a container’s internal components hierarchy in a graphical user interface, to facilitate visualization of complex containers. This was later extended to also display and allow modification of the sub-components’ properties and callbacks.

Today I will focus on the first (programmatic) aspect; next week I will describe the second (GUI) aspect.

Findjobj‘s heart is finding a control’s underlying Java handle. Unfortunately, this is not exposed by Matlab except in very rare cases. As hard as I tried, I could not find a way to directly access the underlying Java-peer handle. I therefore resorted to getting the control’s enclosing Java frame (window) reference, and then working down its sub-components hierarchy until finding the Java object(s) which satisfy the position and/or class criteria. To get the enclosing Java frame (aka TopLevelAncestor), I use the Matlab figure’s undocumented JavaFrame property. Using this property issues a standard warning (since Matlab release R2008a) of becoming obsolete in some future Matlab release. Since it worked so far, I have turned off this warning in findjobj‘s code, but note that this code may well fail in some future Matlab version. If and when JavaFrame does become obsolete, be sure to look in this blog for workarounds…

Traversing the frame’s hierarchy presents several challenges: Main-menu items are accessed using different functions than other Swing components or sub-containers, and are not automatically accessible until first displayed. I have overcome this latter challenge by simulating a menu-open action in case menus should be searched (this is off by default since it takes several seconds and also changes the GUI focus). For “regular” sub-containers, sometimes we need to loop over getComponent(…) and in some other cases over getChildAt(…).

Another challenge was presented by the fact that Java positions start at (0,0) in the top left corner increasing rightward and downward, rather than starting at (1,1) in the bottom left and increasing upward as in Matlab. Moreover, Java positions are always pixel-based and relative to their parent container, which is different from Matlab (if the Matlab units is ‘pixels’ then the value is absolute; if ‘normalized’ then it returns a non-pixel value). To further complicate matters, some Matlab controls have a different size than their Java counterparts: some controls have a 5-pixel margins while others not, some controls are shifted by a pixel or two from their container’s border (for a total offset of up to 7 pixels), while some controls (such as popup-menus) have an entirely different reported size. In theory, we could use the Matlab component’s undocumented PixelBounds property (much faster than getpixelposition), but unfortunately PixelBounds turns out to be unreliable and returns erroneous values in many cases. Finally, different Java containers/components have different ways of returning their position: for some it is a getLocation() method, for others it is getX()/getY() and for others it is the X and Y properties (that sometimes have no corresponding getX()/getY() accessor methods!).

Having finally overcome all these challenges (and quite a few smaller ones, documented within the source code), I have wrapped the algorithm in a function interface that tries to emulate findobj‘s. Using findjobj can now be as easy as:

% Modify the mouse cursor when over the button
hButton = uicontrol('string','click me!');
jButton = findjobj(hButton);
jButton.setCursor(java.awt.Cursor(java.awt.Cursor.HAND_CURSOR))

Modified uicontrol cursor - a Java property

Modified uicontrol cursor - a Java property

…or as complex as:

% Find all non-button controls with the specified label
jControls = findjobj('property',{'text','click me!'}, 'not','class','button');

Space here is limited and findjobj is over 2500 lines long, so I have obviously not covered everything. I encourage you to download the utility and explore the code, and I gladly welcome your feedback.

]]>
https://undocumentedmatlab.com/blog_old/findjobj-find-underlying-java-object/feed 69
GUI integrated HTML panelhttps://undocumentedmatlab.com/blog_old/gui-integrated-html-panel https://undocumentedmatlab.com/blog_old/gui-integrated-html-panel#comments Tue, 15 Dec 2009 12:30:16 +0000 https://undocumentedmatlab.com/?p=865 Related posts:
  1. 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...
  2. Uicontrol callbacks This post details undocumented callbacks exposed by the underlying Java object of Matlab uicontrols, that can be used to modify the control's behavior in a multitude of different events...
  3. Customizing editboxes Matlab's editbox can be customized in many useful manners...
  4. Setting listbox mouse actions Matlab listbox uicontrol can be modified to detect mouse events for right-click context menus, dynamic tooltips etc....
]]>
Last week, I explained how a browser control can be integrated in Matlab GUI applications. Sometimes we only need to display simple HTML, for which a full browser seems like overkill. Moreover, we may wish to edit the displayed contents, which cannot be done using the browser control. The solution is to use a standard Java Swing JEditorPane control, which is an editable HTML-aware control.

Oddly enough, it was only yesterday that Mikhail, a known Matlab Java specialist on the CSSM newsgroup, posted an example for this as answer to a question on the StackOverflow forum (slightly edited for clarity):

mytext = ['<html><body><table border="1">' ...
          '<tr><th>Month</th><th>Savings</th></tr>' ...
          '<tr><td>January</td><td>$100</td></tr>' ...
          '</table></body></html>'];
 
% Create a figure with a scrollable JEditorPane
hfig = figure();
je = javax.swing.JEditorPane('text/html', mytext);
jp = javax.swing.JScrollPane(je);
[hcomponent, hcontainer] = javacomponent(jp, [], hfig);
set(hcontainer, 'units', 'normalized', 'position', [0,0,1,1]);
 
% Turn anti-aliasing on (R2006a, Java 5.0)
java.lang.System.setProperty('awt.useSystemAAFontSettings', 'on');
je.setFont(java.awt.Font('Arial', java.awt.Font.PLAIN, 13));
je.putClientProperty(javax.swing.JEditorPane.HONOR_DISPLAY_PROPERTIES, true);
 
% This only works on Java 1.5 (Matlab R14SP2 to R2007a):
je.putClientProperty(com.sun.java.swing.SwingUtilities2.AA_TEXT_PROPERTY_KEY, true);

Editable HTML-aware JEditorPane

Editable HTML-aware JEditorPane

Mikhail’s code included setting SwingUtilities2’s AA_TEXT_PROPERTY_KEY property for anti-aliased fonts. Unfortunately, SwingUtilities2 was an unsupported and undocumented internal class in Java 1.5 (undocumented/unsupported by Sun, not MathWorks for a change…) and completely disappeared in Java 1.6 (which is bundled with Matlab R2007b onward). Therefore, SwingUtilities2 and its antialias property can only be used on Matlab releases R14SP2 (7.0.4) through R2007a (7.4) – other Matlab versions will throw an error.

Alternately, use JIDE’s AA_TEXT_PROPERTY_KEY (JIDE is bundled with Matlab and this is supported even on new Matlab releases – I will present JIDE in future articles).

property = com.jidesoft.swing.JideSwingUtilities.AA_TEXT_PROPERTY_KEY;
je.putClientProperty(property, true);

Or, simply add the following switch to your java.opt file:

-Dswing.aatext=true

With this switch, you no longer need to set anti-aliasing separately for each component. It is entirely harmless to set this switch even on Matlab/Java versions that do not support it (the switch is simply ignored in these cases).

Note that while JEditorPane’s support for HTML is extensive, it is incomplete. It also does not contain a JavaScript engine or other web-related features we have come to expect in a browser. For the more complex stuff we can use the browser control as explained in last week’s article.

Matlab’s own multi-line editbox uicontrol uses JEditorPane (or actually its derived-class JTextPane) as an underlying component. This means that the simple-looking Matlab editbox is actually a powerful HTML-aware component. In order to use these hidden undocumented features we need the editbox’s underlying JTextPane handle. This is done using the FindJObj utility, which will be described in my next article. Following that, I will show how to customize Matlab’s dull-looking editbox into something much more powerful. Here’s a sample, to help you stay tuned:

HTML contents in a regular Matlab editbox

HTML contents in a regular Matlab editbox

]]>
https://undocumentedmatlab.com/blog_old/gui-integrated-html-panel/feed 3
Customizing Matlab labelshttps://undocumentedmatlab.com/blog_old/customizing-matlab-labels https://undocumentedmatlab.com/blog_old/customizing-matlab-labels#comments Wed, 11 Nov 2009 23:06:01 +0000 https://undocumentedmatlab.com/?p=734 Related posts:
  1. Inactive Control Tooltips & Event Chaining Inactive Matlab uicontrols cannot normally display their tooltips. This article shows how to do this with a combination of undocumented Matlab and Java hacks....
  2. GUI integrated browser control A fully-capable browser component is included in Matlab and can easily be incorporated in regular Matlab GUI applications. This article shows how....
  3. GUI integrated HTML panel Simple HTML can be presented in a Java component integrated in Matlab GUI, without requiring the heavy browser control....
  4. FindJObj GUI – display container hierarchy The FindJObj utility can be used to present a GUI that displays a Matlab container's internal Java components, properties and callbacks....
]]>
As I was deliberating the topic of my weekly article, a new CSSM newsreader thread arrived today to immediately conclude the debate: The CSSM poster asked how Matlab labels can be modified to display non-ASCII characters such as the ∀ or β math symbols.

As you may recall, unlike axes text labels that support Tex/Latex, and unlike other uicontrols like buttons or listboxes that support HTML, text labels (uicontrol(‘Style’,’text’,…)) do not support text formatting or special symbols.

In the above-mentioned thread, Matt Whitaker, a longstanding CSSM contributor and a Matlab-Java veteran gave a solution that shows how seemingly difficult questions sometimes have simple solutions right beneath our noses. His solution was to simply replace the uicontrol label with a Java JLabel:

%show the 'for all' and 'beta' symbols
labelStr = '<html>&#8704;&#946; <b>bold</b> <i><font color="red">label</html>';
jLabel = javaObjectEDT('javax.swing.JLabel',labelStr);
[hcomponent,hcontainer] = javacomponent(jLabel,[100,100,40,20],gcf);

Math symbols and HTML support in a Java JLabel

Math symbols and HTML support in a Java JLabel

Note that the standard Matlab text uicontrol itself is very limited in the amount of customization it supports, even when accessing its underlying Java object using the FindJObj utility. This underlying Java object is a com.mathworks.hg.peer.utils.MultilineLabel extension of Swing’s bland javax.swing.JComponent. In fact, aside from some font and color customizations (also available via the Matlab HG properties), the most useful properties that are accessible only via the Java object are few. These include Border, HorizontalAlignment, VerticalAlignment and LineWrap. This is a very short list compared to the long list of corresponding undocumented properties in the other uicontrols.

]]>
https://undocumentedmatlab.com/blog_old/customizing-matlab-labels/feed 12
Accessing the Matlab Editorhttps://undocumentedmatlab.com/blog_old/accessing-the-matlab-editor https://undocumentedmatlab.com/blog_old/accessing-the-matlab-editor#comments Mon, 19 Oct 2009 18:00:20 +0000 https://undocumentedmatlab.com/?p=671 Related posts:
  1. Non-textual editor actions The UIINSPECT utility can be used to expand EditorMacro capabilities to non-text-insertion actions. This is how:...
  2. EditorMacro – assign a keyboard macro in the Matlab editor EditorMacro is a new utility that enables setting keyboard macros in the Matlab editor. this post details its inner workings....
  3. EditorMacro v2 – setting Command Window key-bindings The EditorMacro utility was extended to support built-in Matlab Editor and Command-Window actions and key-bindings. This post describes the changes and the implementation details....
  4. R2009b keyboard bindings The new Matlab release R2009b includes the ability to customize keyboard bindings for the editor and Command Window. However, there are still some uses for the EditorMacro utility and its...
]]>
Matlab’s built-in editor, like most other Matlab GUI, is Java-based. As such, it can easily be accessed programmatically. ImageAnalyst, a well-respected member of the Matlab community and a frequent CSSM (newsgroup) and FEX (File Exchange) contributor, recently asked whether it is possible to retrieve the name of the Editor’s currently edited file. The answer is that this is very easy, but I decided to use this opportunity to show how other interesting things can be done with the Editor.

Before we start, it should be made clear that this entire article relies on MathWorks internal implementation of the Editor and Desktop, which may change without prior notice in future Matlab releases. The code below appears to work under Matlab 6 & 7, but users who rely on forward compatibility should be aware of this warning.

We start by retrieving the Editor handle. This can be done in a number of ways. The easiest is via the Matlab desktop:

try
    % Matlab 7
    desktop = com.mathworks.mde.desk.MLDesktop.getInstance;
    jEditor = desktop.getGroupContainer('Editor').getTopLevelAncestor;
    % we get a com.mathworks.mde.desk.MLMultipleClientFrame object
catch
    % Matlab 6
    % Unfortunately, we can't get the Editor handle from the Desktop handle in Matlab 6:
    %desktop = com.mathworks.ide.desktop.MLDesktop.getMLDesktop;
 
    % So here's the workaround for Matlab 6:
    openDocs = com.mathworks.ide.editor.EditorApplication.getOpenDocuments;  % a java.util.Vector
    firstDoc = openDocs.elementAt(0);  % a com.mathworks.ide.editor.EditorViewContainer object
    jEditor = firstDoc.getParent.getParent.getParent;
    % we get a com.mathworks.mwt.MWTabPanel or com.mathworks.ide.desktop.DTContainer object
end

Now that we have the Editor handle, let’s retrieve its currently open (active) file name from the Editor’s title:

title = jEditor.getTitle;
currentFilename = char(title.replaceFirst('Editor - ',''));

The entire list of open file names can be retrieved in several ways:

% Alternative #1:
edhandle = com.mathworks.mlservices.MLEditorServices;
allEditorFilenames = char(edhandle.builtinGetOpenDocumentNames);
 
% Alternative #2:
openFiles = desktop.getWindowRegistry.getClosers.toArray.cell;
allEditorFilenames = cellfun(@(c)c.getTitle.char,openFiles,'un',0);

At the top-level Editor-window level, we can prevent its resizing, update its status bar, modify its toolbar/menu-bar, control docking and do other similar fun things:

% Actions via built-in methods:
jEditor.setResizable(0);
jEditor.setStatusText('testing 123...');
jEditor.setTitle('This is the Matlab Editor');
 
% Equivalent actions via properties:
set(jEditor, 'Resizable', 'off');
set(jEditor, 'StatusText', 'testing 123...');
set(jEditor, 'Title', 'This is the Matlab Editor');

Actually, the jEditor handle has over 300 invokable methods and close to 200 properties that we can get/set. Perhaps the easiest way to find interesting things we can programmatically do with the Editor handle, is to use my UIInspect utility on the File Exchange:

uiinspect(jEditor);  % or: jEditor.uiinspect
Matlab Editor methods, callbacks and properties as seen by uiinspect (click to zoom)

Matlab Editor methods, callbacks and properties as seen by uiinspect
(click to zoom)

The Editor handle is actually a container for many internal panels (toolbars etc.) and documents. The entire object hierarchy can be seen with another of my File Exchange utilities, FindJObj:

findjobj(jEditor);  % or: jEditor.findjobj
Matlab Editor object hierarchy as seen by findjboj (click to zoom)

Matlab Editor object hierarchy as seen by findjboj (click to zoom)

We can modify text within the open Editor documents, and instrument these document to handle event callbacks. To see how, I refer users to my EditorMacro utility on the Matlab File Exchange.

If you find some other nifty and/or useful things that can be done using the Editor handle, please post them in the comments section below.

]]>
https://undocumentedmatlab.com/blog_old/accessing-the-matlab-editor/feed 50
Detecting window focus eventshttps://undocumentedmatlab.com/blog_old/detecting-window-focus-events https://undocumentedmatlab.com/blog_old/detecting-window-focus-events#comments Wed, 09 Sep 2009 20:49:51 +0000 https://undocumentedmatlab.com/?p=584 Related posts:
  1. Enable/disable entire figure window Disabling/enabling an entire figure window is impossible with pure Matlab, but is very simple using the underlying Java. This article explains how....
  2. Transparent Matlab figure window Matlab figure windows can be made fully or partially transparent/translucent or blurred - this article explains how...
  3. Minimize/maximize figure window Matlab figure windows can easily be maximized, minimized and restored using a bit of undocumented magic powder...
  4. Setting status-bar text The Matlab desktop and figure windows have a usable statusbar which can only be set using undocumented methods. This post shows how to set the status-bar text....
]]>
A CSSM reader recently asked whether it is possible to detect window focus events (specifically, the focus-gain event) asynchronously, so that such events can trigger a callback without necessitating a polling thread to constantly monitor the windows state.

The user correctly mentioned the fact that although mouse-clicks within the window frame can be detected using the documented figure callback WindowButtonDownFcn, there are other methods by which a window can gain focus: keyboard (<Alt>-<Tab> on Windows, for example), clicking the window frame edge etc. These methods are all undetected by WindowButtonDownFcn.

This problem is, to the best of my knowledge, insoluble using standard documented Matlab. However, there is indeed a simple solution using undocumented/unsupported Matlab features. The solution relies on the fact that all Matlab windows are basically Java Swing objects, and these objects have dozens of standard callback hooks that can be utilized (Matlab only exposes a few callbacks). The list of standard Swing callbacks was detailed in my earlier article about uicontrol callbacks, which is also relevant for Java window frames.

In this specific case, we are interested in FocusGainedCallback. This callback is invoked for the figure Frame’s AxisComponent (a part of the Frame that will be explained in another article). For each of our monitored figure windows, we set this callback to a predefined Matlab function. We may also wish to set its companion FocusLostCallback.

Here’s the resulting code snippet (hFig is our Matlab figure handle):

% Prepare the figure
hFig = figure;  % etc. - prepare the figure
 
% Get the underlying Java reference
warning off MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame
jFig = get(hFig, 'JavaFrame');
jAxis = jFig.getAxisComponent;
 
% Set the focus event callback
set(jAxis,'FocusGainedCallback',{@myMatlabFunc,hFig});
% perhaps also set the FocusLostCallback here

Whenever any of the monitored figures now gets focus, by whichever means, the user-defined Matlab function myMatlabFunc() will be invoked. This function should be defined as follows:

function myMatlabFunc(jAxis, jEventData, hFig)
   % do whatever you wish with the event/hFig information
end

Extra input parameters can be added during callback setup and definition, as follows:

set(jAxis,'FocusLostCallback',{@myMatlabFunc,hFig,data1,data2})
...
function myMatlabFunc(jAxis, jEventData, hFig, data1, data2)
   % do whatever you wish with the event/hFig/data information
end

A very similar technique can detect other windowing events (maximization/minimization/movement etc.). Depending on the case, you may need to use jFig.fFigureClient.getWindow instead of jFig.getAxisComponent. The list of available callbacks for each of these objects can be seen using a simple set(jFig.getAxisComponent) command, or via my UIInspect or FindJObj utilities on the Matlab File Exchange.

Note that all this relies on the undocumented hidden figure property JavaFrame, which issues a standing warning (since Matlab release R2008a) of becoming obsolete in some future Matlab release. Since it worked so far, I have turned off this warning in the code above, but note that this code may well fail in some future Matlab version. If and when JavaFrame does become obsolete, be sure to look in this blog for workarounds…

Addendum Aug 21, 2015: In in HG2 (R2014b onward), setting the Focus events (FocusGained, FocusLost etc.) on the AxisComponent does not work. Instead, we can simply set the callbacks on the AxisComponent’s direct child, as follows:

set(jAxis.getComponent(0),'FocusGainedCallback',{@myMatlabFunc,hFig});
]]>
https://undocumentedmatlab.com/blog_old/detecting-window-focus-events/feed 41
Figure toolbar customizationshttps://undocumentedmatlab.com/blog_old/figure-toolbar-customizations https://undocumentedmatlab.com/blog_old/figure-toolbar-customizations#comments Wed, 02 Sep 2009 16:00:14 +0000 https://undocumentedmatlab.com/?p=564 Related posts:
  1. Detecting window focus events Matlab does not have any documented method to detect window focus events (gain/loss). This article describes an undocumented way to detect such events....
  2. Setting status-bar text The Matlab desktop and figure windows have a usable statusbar which can only be set using undocumented methods. This post shows how to set the status-bar text....
  3. Setting status-bar components Matlab status-bars are Java containers in which we can add GUI controls such as progress-bars, not just simple text labels...
  4. 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....
]]>
Last week, I described how to access existing Matlab figure toolbar icons and how to add non-button toolbar components. Today, I describe how the toolbar itself can be customized using undocumented functionality and properties.

All the important undocumented customizations can only be accessed via the toolbar’s Java handle, which is retrieved so:

hToolbar = findall(hFig,'tag','FigureToolBar');
jToolbar = get(get(hToolbar,'JavaContainer'),'ComponentPeer');

One interesting functionality is enabling a floating toolbar, via jToolbar.setFloatable(1). The toolbar can then be dragged from its docked position at the top of the figure menu, becoming enclosed in an independent floating window (a non-modal javax.swing.JDialog child of the parent figure, to be exact). Since this toolbar window has a very small initial size and no name, a simple immediate fix is required:

% Modify Java toolbar properties
jToolbar.setFloatable(1);
hjToolbar = handle(jToolbar,'CallbackProperties');
set(hjToolbar,'AncestorAddedCallback',@dockUndockCallbackFcn);
 
% Sample dockUndockCallbackFcn function
function dockUndockCallbackFcn(hjToolbar, eventdata)
   if hjToolbar.isFloating
      jToolbarWin = hjToolbar.getTopLevelAncestor;
      jToolbarWin.setTitle('Toolbar');
      %jToolbarWin.setResizable(1); %if you wish manual resize
      jToolbarWin.setPreferredSize(java.awt.Dimension(380,57));
      jToolbarWin.setSize(java.awt.Dimension(380,57));
      jToolbar.revalidate;  %repaint toolbar
      jToolbarWin.getParent.validate; %repaint parent figure
   end
end

Floating toolbar   ...and after minor fixes

Floating toolbar                 ...and after minor fixes        

Re-docking a floating toolbar can be done by simply closing the floating window – the toolbar then reappears in its default (top) position within the parent figure window.

There are other interesting functions/properties available via the Java interface – readers are encouraged to explore via the methods, methodsview, inspect functions, or my uiinspect utility.

For example, addGap() can be used to add a transparent gap between the rightmost toolbar component and the window border: this gap is kept even if the window is shrunk to a smaller width – the rightmost components disappear, maintaining the requested gap.

setBackground() sets the background color that is seen beneath transparent pixels of button images and gaps. Non-transparent (opaque or colored) pixels are not modified. If the button icons are improperly created, the result looks bad:

jToolbar.setBackground(java.awt.Color.cyan); %or: Color(0,1,1)

Default figure toolbar with cyan background

Default figure toolbar with cyan background

This problem can be fixed by looping over the toolbar icons and modifying the pixel values from their default gray background to transparent. An example for this practice was given at the beginning of last week’s article.

setMorePopupEnabled() is used to specify the behavior when the window resizes to such a small width that one or more toolbar buttons need to disappear – by default (=1 or true) the chevron (>>) mark appears on the toolbar’s right, enabling display of the missing buttons, but this behavior can be overridden (0 or false) to simply crop the extra buttons.

setRollover() controls the behavior when the mouse passes (“rolls”) over toolbar buttons. The default parameter (1 or true), displays a 3-dimensional button border, creating an embossing effect; this can be overridden (0 or false) to use a different 3D effect:

% Set non-default Rollover, MorePopupEnabled
jToolbar.setRollover(0);         % or: set(jToolbar,'Rollover','off');
jToolbar.setMorePopupEnabled(0); % or: set(jToolbar,'MorePopupEnabled','off');

default Rollover & MorePopupEnabled properties
non-default Rollover & MorePopupEnabled properties

default (top) and non-default (bottom)
Rollover & MorePopupEnabled properties

Remember that toolbars are simply containers for internal components, generally buttons and separators. These components may be accessed individually and manipulated. An example of such manipulation can be found in my FindJObj utility on the File Exchange, that lists the individual figure components: whenever the user selects a toolbar button (or any other Java component for that matter), its border is temporarily modified to a flashing red rectangle helping users understand the component’s location. Here’s the relevant code snip and screenshot (readers are encouraged to look at the actual code, which is more complex – FindJObj sub-function flashComponent()):

% Prepare the red border panel
oldBorder = jComponent.getBorder;
redBorder = javax.swing.border.LineBorder(java.awt.Color.red,2,0);
redBorderPanel = javax.swing.JPanel;
redBorderPanel.setBorder(redBorder);
redBorderPanel.setOpaque(0);  % transparent interior, red border
redBorderPanel.setBounds(jComponent.getBounds);
isSettable(compIdx) = ismethod(jComponent,'setBorder');
 
% flash by periodically displaying/hiding the panel
for idx = 1 : 2*numTimes
   if idx>1,  pause(delaySecs);  end  % don't pause at start
   visible = mod(idx,2);
   jParent = jComponent.getParent;
 
   % Most Java components allow modifying their borders
   if isSettable
      if visible
         % Set a red border
         jComp.setBorder(redBorder);
         try jComponent.setBorderPainted(1); catch, end
      else %if ~isempty(oldorder)
         % Remove red border by restoring the original border
         jComp.setBorder(oldBorder);
      end
      jComp.repaint;
 
   % Other Java components are highlighted by a transparent red-
   % border panel, placed on top of them in their parent's space
   elseif ~isempty(jParent)
      if visible
         % place the transparent red-border panel on top
         jParent.add(redBorderPanel);
         jParent.setComponentZOrder(redBorderPanel,0);
      else
         jParent.remove(redBorderPanel);
      end
      jParent.repaint;
   end
end  % idx flash loop

FindJObj - flashing red border around a toolbar icon

FindJObj - flashing red border around a toolbar icon

]]>
https://undocumentedmatlab.com/blog_old/figure-toolbar-customizations/feed 24