File Exchange

image thumbnail

Widgets Toolbox

version 1.2.308 (1.12 MB) by Robyn Jackey
Modular components and controls to efficiently develop advanced user interfaces in MATLAB.

81 Downloads

Updated 04 Feb 2019

View License

Widgets Toolbox helps you efficiently develop advanced user interfaces in MATLAB. The toolbox provides additional UI controls and higher-level modules that implement common building blocks needed in MATLAB apps. Widgets combine existing control functionalities together into a larger, reusable, common functionality to accelerate development of graphical user interfaces. Existing users of GUI Layout Toolbox will find Widgets Toolbox pairs nicely with GUI Layout Toolbox.

Example components are:
- A file selection control, consisting of a label, edit field, and browse button
- A listbox control combined with a label and a set of buttons for managing the list composition and ordering
- A tree control providing advanced functionalities like drag and drop, and checkbox nodes

Widgets Toolbox also provides
- Superclasses for a whole application, to provide and manage saving and loading session state to and from a MAT-file
- Dialog windows for several typical kinds of user selection (and more to come in future development)
- A logger, especially useful for complex or deployed apps, that will store application events/data (of a configurable severity level) to a log file and display them in the command window
- Framework for efficiently building your own widgets

Widgets Toolbox is most applicable to users who are writing hand code to develop complex, modular applications with hand code using object-oriented programming in MATLAB. This toolbox currently only supports traditional MATLAB figure windows (Java-based) and does not support web graphics used in uifigure containers or App Designer. Widgets may be added programmatically to a GUIDE-generated app, but they will not show up in the graphical GUIDE editor.

It is recommended you install this as a toolbox to automatically set up the proper MATLAB and Java paths. If you install this manually, please review the installation directions in the Getting Started guide.

Planning a complex or business-critical app? MathWorks Consulting can advise you on design and architecture: https://www.mathworks.com/services/consulting/proven-solutions/software-development-with-matlab.html

Cite As

Robyn Jackey (2019). Widgets Toolbox (https://www.mathworks.com/matlabcentral/fileexchange/66235-widgets-toolbox), MATLAB Central File Exchange. Retrieved .

Comments and Ratings (58)

David

David (view profile)

Robyn, I've managed to find a work around for both of the pieces I was working on with the Preferences class, I'll include them below for your reference.

*Open Recent menu's contents not persisting through closing/re-opening the app: Change all of the times that uiw.abstract.SessionManagement checks the RecentSessionPath preference to look at RecentSessionPaths, so it's always looking at the same list. (lines 214, 413, 422, 499, and 517)

*Custom Preferences not persisting: Edit lines 125-126 in uiw.model.Preferences, this probably isn't a desired long term solution because now propList gets resized as it loops through the list of properties, but the metaclass() function doesn't seem to grab the dynamic properties that addprop adds to the Preferences instance.
From:
mc = metaclass(obj);
propList = mc.PropertyList;

To:
propNames = properties(obj);
for i = 1:numel(propNames)
propList(i) = findprop(obj,propNames{i}); %#ok<AGROW>
end

David

David (view profile)

Robyn, I have been looking using the HasPreferences mix-in class that comes with SingleSessionApp and I believe I've noticed a bit of inconsistency with the way SessionManagement uses its' preferences. It looks like that when SessionManagement is attempting to populate the File > Open Recent menu it sometimes looks for the preference 'RecentSessionPath' and sometimes for 'RecentSessionPaths', so it ends up with two lists that don't match up most of the time. End result is the list of recent files in that Open Recent menu, and the additional preferences that I'm trying to define, don't always persist between closing/re-opening the app. Not sure if the two are directly related, I think I may be missing how to add the preferences I'm defining to the list returned by the Preferences class's getPreferenceProperties function, as the only ones it returns for me now are Position, LastFolder, and RecentSessionPaths.

Robyn Jackey

@Giuseppe - I am looking into future compatibility to use widgets within the web figures (uifigure) that app designer uses. The Java components (primarily Tree, Table) will not work in web figures. I will investigate whether I can map those to the web figure uitree and uitable, as they are being actively developed and each release getting closer to feature parity with the widgets Tree and Table.

Hello Robin, any plan to make it compatible with appdesigner? I am currently using Matlab 2017b and the Tree in appdesigner has been introduced only in Matlab 2018...Thanks

Robyn Jackey

@Kevin - thank you for your feedback! I will take a look at the ButtonDownFcn.

Kevin Phung

@Robyn, I think there may be a bug in which the ButtonDownFcn for your table widget to execute 3 times in a row

Kevin Phung

Hi Robyn, just wanted to say thanks for this amazing toolbox. Was looking for an alternative to matlabs poorly designed uitable, and this was it! Currently have no constructive criticism regarding your program, just wanted to express my gratitude.

Robyn Jackey

@Eddie - The ZIP file download appears to be broken as it removed the + from package directories and the @ from class directories. For now, if you need to manual install, I recommend you instead download the toolbox file and rename the .mltbx extension to .zip. Go into there and into the fsroot folder, and you will have all of the correct source files/folders. If you manually install you will need to manually add the included Java JAR file to the Java path.

@Markus - I will take a look at this in my next round of updates. Thanks for reporting it!

@Daniel - Thanks for the feedback. As you noted, I decided to require case sensitivity in the parameter/value pairs, although most built-in MATLAB components accept lowercase or shortened names. In my opinion I think sticking to the exact name makes for more readable & maintainable code. But I'll give your suggestion some further thought.

@Mohammed - Excellent! Glad you were able to get it working!

Eddie

Eddie (view profile)

I tried to install this manually - but the class folders included in the zip file do not start with '+' but start with an empty space, therefore matlab cannot find the class. Do I need to manually batch rename those folders to include the '+' sign?

Markus

Markus (view profile)

@Robyn: Very useful toolbox. Thank you!
I use the Table class with an UIcontexmenu and I would like to select multiple lines with control + left mouse click.
In my opinion I detected an litte little mistake in your code. The problem occurs in the function "onMouseEvent" of the class Table line 328.
It is not possible to select multiple lines without the context menu opening automatically.

I changed the line 328 and now it works. Hope I could help

OLD (your code):
% Launch context menu in certain cases
if strcmp(mouseEvent.SelectionType,'alt')

NEW (fix):
% Launch context menu in certain cases
if strcmp(mouseEvent.SelectionType,'alt') && mouseEvent.ControlOn~=1

Eddie

Eddie (view profile)

would love to see support for reordering of treenodes. Right now I am using un-parenting and re-parenting trick to get around this issue.

Eddie

Eddie (view profile)

Great toolbox!
Perhaps it's just me (being lazy) but it might be nice if the Name,Value syntax accepted lower-case parameters names.
For example:
>> uiw.widgets.Slider('parent',gcf);
returns an error, while
>> uiw.widgets.Slider('Parent',gcf);
is ok.

The behavior of most native MATLAB functions ignore the case of parameter names.

@Robyn
Thanks for your feedback. I was exploring on my own and managed to get the handle of jTable; If your table is saved in a variable "w', then jTable = w.JControl. Maybe your suggestion to explore getJavaObjects will work, too, but I got it working so I'm happy. Thanks for your help, anyway :D

If someone faces the same problem, here's my code:
% add the custom class "LookupFieldCellEditor" by Yair Altman to your java classpath
javaaddpath('LookupFieldCellEditor.zip');

% create a java hashtable to hold the different lists
hashTable = java.util.Hashtable;

% add each list to its corresponding row value
for i:1:rowCount
% rowValue: in my case, it is the value of the first column in each row
% horizontalList: a 1-by-n cell array holding your list

% add your pair of rowValue & horizontal list to the hash table
hashTable.put(rowValue, horizontalList);
end

% create an instance of the custom java class
% first arg. is the hash table
% second arg. is the column index where the cell editor will be looking to select the right list to display. (don't forget java index starts from 0)
cellEditor = LookupFieldCellEditor(hashTable, 0);

jTable = w.JControl;
jColModel = javaMethodEDT('getColumnModel', jTable);

% In my case, I wanted different lists to be displayed in my fourth column, so it's my target column
targetCol = javaMethodEDT('getColumn', jColModel , 3);
% sets the custom cell editor for the target column
javaMethodEDT('setCellEditor', targetCol, cellEditor);

Robyn Jackey

@Mohammed - Thank you for your feedback! I have not attempted row- or cell-specific lists before. If it helps, there's a method you can call (getJavaObjects I think) to return the Java editors, etc. If necessary you could also subclass the Table widget to override any functionality. Sorry I don't have a better answer. I'll have a look at the color issue on my next round of bugfixes.

@Adam - yes this is strange. The renderer I think is different for the Checkbox Tree vs. normal Tree. There must be an issue there. It is kind of niche as you say and could be complicated to fix. I think it is unlikely I'll be able to dig deep to fix this one. Sorry for that.

Thanks for the great toolbox. For the Table widget, I tried to set up a different list for each row, but I could not find a way. I usually do this by getting the jTable (from jscroll = findjobj(mTable); jTable = jscroll.getViewport.getView) and then setting the cell editor for the right column using the LookupFieldCellEditor by Yair Altman. If there is a way you can help, I'd really appreciate it.

Also, I noticed when you add a column for Color in a Table and the user selects a new color, the new data will be saved in the 0-255 range instead of being normalized to 0-1. This somehow causes a problem when dealing with a logical column in the same table when trying to set the logical value programmatically to false ONLY (setting it to true doesn't cause a problem). The table will notice that the numbers of the new color is out of range for Java causing a Java exception

Adam

Adam (view profile)

I am also noticing strange behaviour with the CheckboxTree that is not present with the Tree. I am using a html string such as:

sprintf( '<html><Font color = "rgb(0,180,0)">%s</font></html>', name )

It works fine for most nodes, but some exhibit strange behaviour with the CheckboxTree. In particular a node which has a child and has a space in its string truncates to only the first word, but then if I click on the name (not the checkbox) the full name appears, then disappears again sometimes if I click on it a second time or always if I expand the node. Also some of the other even short strings are being visually clipped in a seemingly arbitrary way. All works fine for the regular tree though. It also works fine without using html strings so it is a bit of a niche bug, I just wanted part of my strings to be a different colour.

I like the look of the toolbox on the whole though.

Robyn Jackey

@Manuel - Thank you for reporting this. I had not noticed this before, but will take a look when I have some time.

Manuel Petit

Hi Robyn,
Thank you so much for this great submission! Really helpful!
I noticed a weird behavior of the CheckboxTree about the FontSize property: everything works fine with Tree (properties are updated correctly in the object and visually), however with CheckboxTree the object is correctly updated but the size of the font do not changed. Is it possible to actually change it ?
Thanks

Robyn Jackey

@Roman - thank you for reporting this. That was unintentional and I will try to fix this soon. Please bear with me as the end of year is very busy.

The current version is NOT compatible with R2017a. It uses isStringScalar, which was introduced in R2017b.

Robyn Jackey

@Carsten - Ideally you should retain the handles of each tree node and track them with your data hierarchy. You could also store anything you like in the UserData property of the nodes.

@Giuseppe - For deployment, you will need to manually select the Java JAR file you mentioned from the Widgets toolbox installation directory. You may also need to manually include any icon files you are using in your GUI, if they don't get picked up automatically by the deployment tool.

Hi Robyn,

Thanks for a great toolbox!

I have a very simple (I think!) question: I want to be able to determine the state of a checkbox in a CheckboxTreeNode, but as the nodes have no 'Tag' I'm not able to find them!? I don't want to find them by the 'Name' property, as this sometimes changes. I will also like to be able to programmtically check and uncheck the checkboxes - how can I accomplish that?

Thanks

Hello Robyn

I developed an app that uses your toolbox, I packed it and sent to one of my colleagues. He managed to install it, but he gets the following error:

Error using javaObjectEDT
No class com.mathworks.consulting.widgets.tree.TreeNode can be located on the Java class path

I solved it adding programmatically the file "MathWorksConsultingWidgets.jar" in the java class path. Is this the only way to get rid of the problem?

Thanks

Robyn Jackey

Kiron - The new version just posted 1.1.257 should fix this issue.

Kiron Mateti

Hi Robyn, great toolbox! I am trying to prevent the display of what seems to be an active display of mouse events in the Table widget. I get command window output of "up", "down", "click", when manipulating the table. All the callbacks that I have access to are empty, so I am wondering if it is a level deeper? Thanks!

Robyn Jackey

Release 1.0.245 just posted contains minor changes. Please see the release notes at the bottom of this page. A larger update with significant bugfixes, improvements, and additional functionality is in review now.

Robyn Jackey

Hi Dani - yes, sorry for this. The approval process for publishing version 1.1 has delayed the release for several months. I anticipate another few weeks. (A temporary release 1.0.x will be arriving within a few days but has minimal changes.)

Dani

Dani (view profile)

Takes a long time for that 1.1 release to come out?

Robyn Jackey

Hi Tyler, thanks for letting me know. I have it fixed in the upcoming release.

Tyler Cumby

Hi Robyn, I just noticed that uiw.mixin.HasLabel's LabelFontWeight property is defined as "double" instead of "char".

Robyn Jackey

Thank you Tyler!

Tyler Cumby

I just wanted to voice my appreciation of Table and TableColumFormat: you've made it really easy to incorporate our own custom table cell editors and renderers. Thanks!

Robyn Jackey

@Kai - The "Compatible with any release" is an error. I've corrected this in version 1.1 which is currently going through submission approval process. It does require R2017a because many of the classes use property validators. This feature is a very useful programming aid and also permits automatic conversions to the property's datatype, which makes using them easier. That said, I understand some users are fixed on an earlier release for other reasons. Your earlier comment about the tree control may have been overwritten by this one. I'd like to follow up and see if I can reproduce that problem. Can you please PM me to discuss both of these by clicking on my name above and click "Contact Author"?

Additionally, it says on the right to be compatible with any Matlab release, yet it requires 2017a to work, which is a quite limiting restriction.

Robyn Jackey

@Rebecca, I have not encountered this before. Are you using R2017a or greater? If you are still having trouble, please PM me (click on my name above, then click the Contact button below my photo)

Hi Robyn, we're testing the toolbox on a new computer that downloaded the .mtlbx file, and are getting the following error, do you have any tips?

Error using hgconvertunits
Input was not a valid graphics object
Error in getpixelposition
Error in uiw.abstract.BaseContainer/getPixelSize (line 78)
pos = getpixelposition(obj,false);
Error in uiw.abstract.WidgetContainer/onContainerResized (line 194)
[wC,hC] = obj.getPixelSize();
Error in uiw.mixin.HasLabel (line 77)
obj.onContainerResized();
Error in uiw.abstract.WidgetContainer (line 37)
obj@uiw.mixin.HasLabel();
Error in uiw.widget.Toolstrip (line 49)
function obj = Toolstrip(varargin)
Error in demoToolstrip (line 22)
w = uiw.widget.Toolstrip(...

Roman Gorlov

@Robyn, perfect, thank you! I will use the JControl for now and await the next version.

Robyn Jackey

@Rebecca - You would want to set a keyboard callback on the table itself, rather than the figure. The upcoming release (currently in final testing) has this. If you need it right away, you can do something like this: w.JControl.KeyPressedCallback = @(h,e)disp(e). Or if you PM me I will send you a prerelease version.

Works great, thanks Robyn! I have one more question: it seems that clicking on a row does something to the window key press listener, such that any callbacks for key presses are not activated while the row/cells are highlighted. I've tried adding a 'WindowKeyPress' listener to the main figure, and that causes the callback to execute, but only after clicking out of the table. What I'd like to do is to be able to select a row, hit delete, and activate a callback that deletes that row (which I have written), but I can't get the delete key press callback to activate. Do you know how to get around this?

Robyn Jackey

@Rebecca - Great idea! I think I can add a new property to set the grid color. For now, this is undocumented, but you can do this:
w.JControl.setGridColor( uiw.abstract.JavaControl.rgbToJavaColor([1 0 0]) )

Is there a way to add borders to the table cells? Right now the white cells and very close-to-white borders make all of the cell contents run together and hard to distinguish columns, such as in the example

David

David (view profile)

Robyn Jackey

@David - I haven't been able to reproduce it myself, but it may help to put in an extra guard to avoid the Java exception. If you insert this just before line 448 in Table.m, it should just return if that error condition occurs:

% Re-verify the number of rows and columns
if rIdx > obj.JTableModel.getRowCount() || cIdx > obj.JTableModel.getColumnCount()
return
end

Please let me know if this helps.

Robyn Jackey

@David - I think you're doing everything correctly. I have had a similar report from another user about a Java error like this, that I need to investigate. I don't know if it would make a difference, but you might try setting the "Data" property instead of "DataTable". The "Data" property has had more testing, while "DataTable" was added as a convenience but it may be doing more under the hood since it also sets the ColumnName. I will post back when I find more. If you can reliably reproduce this, it would be great to get an example. You can PM me from the author page (click on my name above) to email me.

David

David (view profile)

For the Table widget, what should the procedure be to remove a row from the table? I have created a pushbutton uicontrol that first reads the SelectedRows from the widget, removes that row from the Matlab table that is my data source, then re-sends the now shortened table to the widget via the DataTable property. Even though everything seems to work as expected (the selected row is removed from the Table widget and the figure updates correctly), I am getting a Java 'IndexOutOfBounds' exception in the command window from the widget's source file, line 448 (onTableModelChanged function). I'm not sure if this is an issue with the widget or my approach though.

Robyn Jackey

@Giuseppe - I may need a bit more info to reproduce this issue. Can you PM me and send some example code?

Still didn't manage to find a way to deselect the checked boxes when I select a new box with the CheckboxTree....As far as I know there is no option yet to do that so I am trying to do it myself....I have the impression it is a bit unstable, though

Robyn Jackey

@Marnoch - Glad you are liking the Widgets Toolbox! You're right that the Tree in Widgets Toolbox does not currently support lazy loading of nodes. Actually, I've had very few requests for it, but it is something I will consider for a future update.

This looks like a very useful set of functionality, but I have an issue. I am developing an application where we have a potentially very large number of nodes and branches. I have been using the depreciated uitree and related functions, but was hoping to switch to using this toolbox. The problem I have is that it is very advantagous for us to use lazy noding, or dynamic node creation, so that nodes are not created until their parent is expanded. I have been acheving this by manipulating the AllowsChildren and isLeaf properties of uitree nodes, however there is no equivilent property to isLeaf that is settable on either type of tree included in this toolbox. This means that the user is not shown a control to expand a node until child nodes are actually added, which prevents the lazy noding technique being used. Is there a way to acheive somethig similar?
Thanks

Jesper

Jesper (view profile)

Dani

Dani (view profile)

Thanks for the install instructions.
One more thing. Could be useful if in Toolstrip the Background color of the sections and the object behind them could be controlled separately as to make the sections stand out more.

Robyn Jackey

@Dani - Thanks for the feedback! I'll have a look and make some improvements.

For installation, I recommend downloading the toolbox file and installing that way, which handles everything. This method also adds the Java .jar file under \resource to the static Java path for the next launch. If you download as a zip, you need to add everything to the MATLAB path, adding the one .jar file either via javaaddpath (dynamic Java path) or to javaclasspath.txt (static Java path - preferred).

Dani

Dani (view profile)

Nice! I especially like the Toolstrip. Few comments:

1. Would be nice to have some installation instructions (which paths to add) so that one can run the demos out of the box. With several demos I get
Error using javaObjectEDT

No class com.mathworks.consulting.widgets.tree.TreeNode can be located on the Java class path
No class com.mathworks.consulting.widgets.table.TableModel can be located on the Java class path

2. demoColorSelector gives an error because roundn of the Mapping Toolbox is not available. Would be nice if this would run without special toolbox functions.

3. In several examples, e.g. demoEditablePopup, the objects are not high enough and the bottom line of the box around the popup does not show. On my system is I have to use 'Position',[10 10 300 26]); instead of the default 25. Would be nice if one could query the objects for how large they should be. Popups and normal edit boxes often behave differently with popups needing a bit more height.

4. What is FixedText?

5. FolderSelector
Would be nice to have a folder selector that also shows the contents of the individual folders. I often only know which folder I want to use once I see what it contains.

6. Make objects not focusable? When one clicks in demoPopup or demoSlider they get a stippeled rim around them. Deactivate?

Anita

Anita (view profile)

Updates

1.2.308

Bugfixes to Table for editing with numeric data format and for color column format

1.2.305

Minor bugfixes: string support, R2017a, SessionManagement, CheckboxTree, Table
See GettingStarted.mlx for release notes.

1.2.289

Various bugfixes. See release notes in GettingStarted.mlx

1.1.257

Add application superclasses and demo
Add logging capabilities
New widgets: ImageSelector, ProgressBar
New dialogs: About, SearchList, TableSelection
Various bugfixes
Rename FixedText widget to Text
(Release notes in GettingStarted.mlx)

1.0.245

Toolstrip renamed Toolbar to accurately reflect its capability. Toolbar also now enables toggling group visibility to show/hide sections.

Added Contents.m file to allow toolbox and version number to be registered with "ver" command in MATLAB.

1.0.0.0

Minor bugfix to List, Popup, Table.

MATLAB Release Compatibility
Created with R2018b
Compatible with R2017a to any release
Platform Compatibility
Windows macOS Linux

Discover Live Editor

Create scripts with code, output, and formatted text in a single executable document.


Learn About Live Editor

demo

demo/+demoAppPkg/+enum

demo/+demoAppPkg/+model/@DataModel

demo/+demoAppPkg/+view/@App

demo/+demoAppPkg/+view/@BarChart

demo/+demoAppPkg/+view/@DisplayTable

demo/+demoAppPkg/+view/@PlotSelector

resource/+uix

widgets

widgets/+uiw/+abstract

widgets/+uiw/+dialog

widgets/+uiw/+enum

widgets/+uiw/+event

widgets/+uiw/+mixin

widgets/+uiw/+model

widgets/+uiw/+tool

widgets/+uiw/+tool/@Logger

widgets/+uiw/+utility

widgets/+uiw/+widget