Quantcast
Viewing all articles
Browse latest Browse all 219

CheckboxList

Several years ago I blogged about using a checkbox-tree in Matlab. A few days ago there was a question on the Matlab Answers forum asking whether something similar can be done with Matlab listboxes, i.e. add checkboxes next to each list item. There are actually several alternatives for this and I thought this could be a good opportunity to discuss them:

Image may be NSFW.
Clik here to view.
MathWorks CheckBoxList

MathWorks CheckBoxList


The HTML image variant

The simplest alternative is to use small icon images checked and unchecked as part of the listbox item labels. As I explained last year, listboxes (like all other Matlab uicontrols that rely on underlying Java Swing components), support HTML and can be formatted using HTML images. For example:

Image may be NSFW.
Clik here to view.
Matlab listbox with HTML image icons

Matlab listbox with HTML image icons

In order to check/uncheck items in the listbox, we can trap the underlying Java component’s MouseClickedCallback using the findjobj utility:

% Assume checked.gif, unchecked.gif are 16x16 icons
prefix = ['<html><img src="file:///' strrep(path_of_icon_files),'\','/') '/unchecked.gif" height=16 width=16 />'];
sampleData = strcat(prefix, {'first', 'Second', 'Third', 'and last'});  % all items are unchecked at first
hListbox = uicontrol(...);
jScrollPane = findjobj(hListbox);
jListbox = handle(jScrollPane.getViewport.getView, 'CallbackProperties');
jListbox.MouseClickedCallback = {@mouseClickedFcn,hListbox};
 
function mouseClickedFcn(jListbox, jEventData, hListbox)
   % Get the clicked item and row index
   clickedX = jEventData.getX;
   clickedY = jEventData.getY;
   if clickedX > 15,  return;  end  % did not click a checkbox so bail out
   clickedRow = jListbox.locationToIndex(java.awt.Point(clickedX,clickedY)) + 1;  % Matlab row index = Java row index+1
   if clickedRow <= 0,  return;  end  % clicked not on an item - bail out
   strs = get(hListbox,'String');
   clickedItem = strs{clickedRow};
 
   % Switch the icon between checked.gif <=> unchecked.gif
   if strfind(clickedItem,'unchecked')
       strs{clickedRow} = strrep(clickedItem,'unchecked','checked');
   else
       strs{clickedRow} = strrep(clickedItem,'checked','unchecked');
   end
   set(hListbox,'String',strs);  % update the list item
end

Finally, when we process the selected list item(s), we can simply check whether they contain ‘unchecked.gif’ or ‘checked.gif’. Pretty straight-forward stuff.

MathWorks CheckBoxList

com.mathworks.mwswing.checkboxlist.CheckBoxList is a JList extension that displays a list of labels in a list with a checkbox next to each label. The labels’ checkboxes can be set, unset and queried using methods supplied by the CheckBoxList class or its com.mathworks.mwswing.checkboxlist.DefaultListCheckModel model:

% First create the data model
jList = java.util.ArrayList;  % any java.util.List will be ok
jList.add(0,'First');
jList.add(1,'Second');
jList.add(2,'Third');
jList.add(3,'and last');
 
% Next prepare a CheckBoxList component within a scroll-pane
jCBList = com.mathworks.mwswing.checkboxlist.CheckBoxList(jList);
jScrollPane = com.mathworks.mwswing.MJScrollPane(jCBList);
 
% Now place this scroll-pane within a Matlab container (figure or panel)
[jhScroll,hContainer] = javacomponent(jScrollPane,[10,10,80,65],gcf);
 
% Set the listbox to respond to click events
jhCBList = handle(jCBList, 'CallbackProperties');
set(jhCBList, 'ValueChangedCallback', @myMatlabCallbackFcn);
 
% Update some items' state programmatically
jCBModel = jCBList.getCheckModel;
jCBModel.checkAll;
jCBModel.uncheckIndex(1);
jCBModel.uncheckIndex(3);

This results in the following image:

Image may be NSFW.
Clik here to view.
MathWorks CheckBoxList

MathWorks CheckBoxList

We can query the various checked/unchecked states programmatically:

>> jCBList.getCheckedValues
ans =
[First, Third]
 
>> jCBList.getCheckedIndicies'
ans =
           0       2
 
>> jCBModel.isIndexChecked(0)
ans =
     1    % =true

JIDE’s CheckBoxList

There is also an unrelated JIDE equivalent: com.jidesoft.swing.CheckBoxList. Readers are referred to the JIDE documentation for additional details.

The basic idea is the same as with the MathWorks CheckBoxList: we create the data model, then create a CheckBoxList component within a JScrollPane and place this onscreen using the javacomponent function. We can then modify or query the data model programmatically, and set various callback functions to process user events.

% Prepare the data model as above
 
% Now display onscreen:
jCBList = com.jidesoft.swing.CheckBoxList(jList.toArray)
jScrollPane = com.mathworks.mwswing.MJScrollPane(jCBList);
[jhScroll,hContainer] = javacomponent(jScrollPane, [120,10,80,65], gcf);
 
% Do some programmatic updates:
jCBList.selectAll;  % reverse: jCBList.selectNone
jCBList.setCheckBoxListSelectedIndices([0,2]);

The appearance is very similar to the MathWorks CheckBoxList, except that JIDE’s CheckBoxList has slightly less space between the list rows, and between the checkboxes and labels. The main difference between these components is not in their visual appearance but rather in their supported functionalities (internal methods) – some people might prefer the MathWorks component, others might like JIDE better. To see these functionalities, use my uiinspect and/or checkClass utilities.

For additional information on the MathWorks and JIDE components, and how to investigate and customize them, see Chapter 5 of my Matlab-Java programming book.

ActiveX and other alternatives

If you are running on Windows, you could use ActiveX controls that implement checkbox list functionality. One such control that is pretty standard is Microsoft’s MSComctlLib.ListViewCtrl.2. I showed an example of ListViewCtrl usage a few years ago, and readers are referred there for details. Here is the end result:

Image may be NSFW.
Clik here to view.
Sorted ListViewCtrl

Sorted ListViewCtrl

Granted, this is more of a table having a checkbox column than a listbox, but you can easily make the ListViewCtrl have only a single column.

In addition to this standard ListViewCtrl control, there are plenty of other third-party ActiveX or Java controls that can more-or-less easily be integrated in our Matlab GUI. The drawback of ActiveX is that it only works on a limited set of platforms, whereas the Java-based components (either MathWorks or JIDE) work on all Matlab installations.

Anyway, don’t let anyone say ever again that Matlab GUI is boring. It is not. It is only limited by our imagination and our willingness to find and customize components that implement our requirements. There are plenty of alternatives out there, we just need to reach out and use them. If you can’t do it yourself, you could always use an external consultant like me to help you.

 
Related posts:
  1. Customizing listbox & editbox scrollbars Matlab listbox and multi-line editbox uicontrols have pre-configured scrollbars. This article shows how they can be customized....
  2. Tri-state checkbox Matlab checkboxes can easily be made to support tri-state functionality....
  3. Color selection components Matlab has several internal color-selection components that can easily be integrated in Matlab GUI...
  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...
 

Viewing all articles
Browse latest Browse all 219

Trending Articles