Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
checkbox tree callback question

Subject: checkbox tree callback question

From: John Anderson

Date: 5 Jan, 2011 14:57:04

Message: 1 of 4

I'm currently experimenting with a simple checkbox tree in matlab, making use of the java checkbox class (com.jidesoft.swing.CheckBoxTree) as well as useful advice from Yair Altman's undocumented Matlab.

In my particular application I want to be able to externally select specific paths on the checkbox tree as well as respond to selection changes mediated by mouse clicks. However, I do not want to trigger a 'selection change' callback when selecting paths externally. Is there a simple way of checking from inside the 'selection change' callback (which is activated when a selection change occurs) to determine whether the change resulted from an external path selection call (in the code below produced by the radio button activation) or from a mouse click over a checkbox.

I've tried a couple of adhoc solutions, e.g. using an additional callback to respond to mouse clicks over the checkbox tree but this doesn't seem very reliable, sometimes the events are captured and sometimes missed. I've also tried making use of gcbo to get information regarding the current callback object but this always refers to the checkbox tree, I guess becuase activating the radio button triggers the selection change callback associated with the checkbox tree.

The code below is intended to illustrate the problem. A simple check box tree is defined and the selection of the path 'objects/door' is placed under the control of a radiobutton. Toggling the radio button and clicking on to checkboxes directly both trigger the selection change callback. I would like to be able to separate these two events.

Any advice much appreciated. Best wishes,

John
 




function javaCallbackExp3

import javax.swing.tree.*;
import javax.swing.*;
import com.jidesoft.swing.CheckBoxTree.*

% define a simple tree
rootNode = DefaultMutableTreeNode( 'Objects' );
fNode = DefaultMutableTreeNode( 'window' );
rootNode.add( fNode );
sNode = DefaultMutableTreeNode( 'door' );
rootNode.add( sNode );

% define tree model
treeModel = DefaultTreeModel( rootNode );

% checkbox tree
tree = com.jidesoft.swing.CheckBoxTree( treeModel );

% define tree selection model
treeSelectionModel = tree.getCheckBoxTreeSelectionModel();

% create handle to java object callback properties
hTreeSelectionModel = handle( treeSelectionModel, 'CallbackProperties' );

% set appropriate callback
set( hTreeSelectionModel, 'ValueChangedCallback', @selectionChanged_cb );

% place tree on figure
fh = figure( 'windowStyle', 'docked' );
jScrollPane = com.mathworks.mwswing.MJScrollPane(tree);
[jComp,hc ] = javacomponent(jScrollPane,[10,10,300,150],fh);

% create tree selection button
hButton = uicontrol('style', 'radiobutton',...
    'units', 'normalized',...
    'string', 'select door',...
    'position', [0.5 0.5 0.3 0.2 ],...
    'callback', @radioButtonCallback );

% define door selection path for use in radiobutton callback
pathNew = javax.swing.tree.TreePath( [ rootNode fNode ] );

    function radioButtonCallback( hObject, ev )
      
        % if radio button set then select (door) path
        if get( hObject, 'value' )
            treeSelectionModel.setSelectionPath( pathNew );
        % otherwise deselect all paths
        else
            treeSelectionModel.clearSelection;
        end
    end

    function selectionChanged_cb( varargin )
        disp( 'selection changed' );
    end
end

Subject: checkbox tree callback question

From: Yair Altman

Date: 5 Jan, 2011 19:20:21

Message: 2 of 4

"John Anderson" <j.c.anderson@sussex.ac.uk> wrote in message <ig20s0$3ma$1@fred.mathworks.com>...
> I'm currently experimenting with a simple checkbox tree in matlab, making use of the java checkbox class (com.jidesoft.swing.CheckBoxTree) as well as useful advice from Yair Altman's undocumented Matlab.
>
> In my particular application I want to be able to externally select specific paths on the checkbox tree as well as respond to selection changes mediated by mouse clicks. However, I do not want to trigger a 'selection change' callback when selecting paths externally. Is there a simple way of checking from inside the 'selection change' callback (which is activated when a selection change occurs) to determine whether the change resulted from an external path selection call (in the code below produced by the radio button activation) or from a mouse click over a checkbox.
>
> I've tried a couple of adhoc solutions, e.g. using an additional callback to respond to mouse clicks over the checkbox tree but this doesn't seem very reliable, sometimes the events are captured and sometimes missed. I've also tried making use of gcbo to get information regarding the current callback object but this always refers to the checkbox tree, I guess becuase activating the radio button triggers the selection change callback associated with the checkbox tree.
[snip]


You can programmatically set a flag in the about-to-be-selected node's UserData or ApplicationData just before selecting it, and then check for this flag (and clear it) within your NodeSelectedCallback. Mouse and keyboard selections will obviously not have the flag set when the callback is triggered. Simple and effective.

I would also suggest checking com.mathworks.mwswing.checkboxtree.CheckBoxTree. This is a built-in Matlab component that is similar yet unrelated to the JIDE component. Example:

% Prepare the tree nodes
import com.mathworks.mwswing.checkboxtree.*
jRoot = DefaultCheckBoxNode('Root');
l1a = DefaultCheckBoxNode('Letters'); jRoot.add(l1a);
l1b = DefaultCheckBoxNode('Numbers'); jRoot.add(l1b);
l2a = DefaultCheckBoxNode('A'); l1a.add(l2a);
l2b = DefaultCheckBoxNode('b'); l1a.add(l2b);
l2c = DefaultCheckBoxNode('<html><b>α'); l1a.add(l2c);
l2d = DefaultCheckBoxNode('<html><i>β'); l1a.add(l2d);
l2e = DefaultCheckBoxNode('3.1415'); l1b.add(l2e);

% Present the standard MJTree:
jTree = com.mathworks.mwswing.MJTree(jRoot);
jScrollPane = com.mathworks.mwswing.MJScrollPane(jTree);
[jComp,hc] = javacomponent(jScrollPane,[10,10,120,110],gcf);

% Now present the CheckBoxTree:
jCheckBoxTree = CheckBoxTree(jTree.getModel);
jScrollPane = com.mathworks.mwswing.MJScrollPane(jCheckBoxTree);
[jComp,hc] = javacomponent(jScrollPane,[150,10,120,110],gcf);

Yair Altman
http://UndocumentedMatlab.com

Subject: checkbox tree callback question

From: Yair Altman

Date: 5 Jan, 2011 19:28:05

Message: 3 of 4

"Yair Altman" wrote in message <ig2g9l$pg0$1@fred.mathworks.com>...
> "John Anderson" <j.c.anderson@sussex.ac.uk> wrote in message <ig20s0$3ma$1@fred.mathworks.com>...
> > I'm currently experimenting with a simple checkbox tree in matlab, making use of the java checkbox class (com.jidesoft.swing.CheckBoxTree) as well as useful advice from Yair Altman's undocumented Matlab.

> I would also suggest checking com.mathworks.mwswing.checkboxtree.CheckBoxTree. This is a built-in Matlab component that is similar yet unrelated to the JIDE component. Example:

More information and alternatives to CheckBoxTree can be found here: http://undocumentedmatlab.com/blog/customizing-uitree-nodes-2/

Yair Altman
http://UndocumentedMatlab.com

Subject: checkbox tree callback question

From: John Anderson

Date: 5 Jan, 2011 20:56:04

Message: 4 of 4

Hi Yair,

Thanks for your advice. I've had a go at using a simple state variable and this works fine, enabling me to determine where node selections derive from (javaCallbackExp5, below). I did find that when using this approach it was important to include a short pause after setting the new selection path to ensure that the selection change callback had time to execute before resetting the state.

I also had a quick play with the checkboxTreeModel you reccommended (com.mathworks.mwswing.checkboxtree.CheckBoxTree). However, I found that when using a selectionModel to highlight particular paths the nodes were not checked even though the paths appear in the selection model (javaCallbackExp6, below).

Thanks again for your help.

Best wishes,

John


function javaCallbackExp5

state = 0;

import javax.swing.tree.*;
import javax.swing.*;
import com.jidesoft.swing.CheckBoxTree.*

% define a simple tree
rootNode = DefaultMutableTreeNode( 'Objects' );
fNode = DefaultMutableTreeNode( 'window' );
rootNode.add( fNode );
sNode = DefaultMutableTreeNode( 'door' );
rootNode.add( sNode );

% define tree model
treeModel = DefaultTreeModel( rootNode );

% tree
tree = com.jidesoft.swing.CheckBoxTree( treeModel );

treeSelectionModel = tree.getCheckBoxTreeSelectionModel();

% create handle to java object callback properties
hTreeSelectionModel = handle( treeSelectionModel, 'CallbackProperties' );

% set appropriate callback
set( hTreeSelectionModel, 'ValueChangedCallback', {@selectionChanged_cb} );

pathNew = javax.swing.tree.TreePath( [ rootNode sNode ] );
hTreeSelectionModel.setSelectionPath( pathNew );


% place tree on figure
fh = figure( 'windowStyle', 'docked' );
jScrollPane = com.mathworks.mwswing.MJScrollPane(tree);
[jComp,hc ] = javacomponent(jScrollPane,[10,10,300,150],fh);

set(fh, 'userdata', 0 );

hButton = uicontrol( 'style', 'pushbutton',...
    'units', 'normalized',...
    'position', [ 0.5 0.3 0.3 0.1 ],...
    'string', 'default selection',...
    'callback', @pushbuttonCallback );

hButton3 = uicontrol( 'style', 'pushbutton',...
    'units', 'normalized',...
    'position', [ 0.5 0.1 0.3 0.1 ],...
    'enable','off',...
    'string', 'update...',...
    'callback', @pushbutton3Callback );

pathNew = javax.swing.tree.TreePath( [ rootNode sNode ] );
    
    function pushbuttonCallback( hObject, ev )
        % restore default selection
        state=1;
        hTreeSelectionModel.setSelectionPath( pathNew );
        pause(0.01);
        state=0;
    end

    function pushbutton3Callback( hObject, ev )
        % disable update button
         set( hObject, 'enable', 'off' );
    end

    function selectionChanged_cb( varargin )
       % if selection changed manually then enable update button
       if state
           set( hButton3, 'enable', 'off' );
       else
           set( hButton3, 'enable', 'on' );
       end
    end
end





function javaCallbackExp6

import com.mathworks.mwswing.checkboxtree.*

jRoot = DefaultCheckBoxNode('Root');
l1a = DefaultCheckBoxNode('Letters'); jRoot.add(l1a);
l1b = DefaultCheckBoxNode('Numbers'); jRoot.add(l1b);
l2a = DefaultCheckBoxNode('A'); l1a.add(l2a);
l2b = DefaultCheckBoxNode('b'); l1a.add(l2b);
l2c = DefaultCheckBoxNode('<html><b>?'); l1a.add(l2c);
l2d = DefaultCheckBoxNode('<html><i>?'); l1a.add(l2d);
l2e = DefaultCheckBoxNode('3.1415'); l1b.add(l2e);

fh = figure( 'windowStyle', 'docked' );

jTree = com.mathworks.mwswing.MJTree(jRoot);
jCheckBoxTree = CheckBoxTree(jTree.getModel);
jScrollPane = com.mathworks.mwswing.MJScrollPane(jCheckBoxTree);
[jComp,hc] = javacomponent(jScrollPane,[150,10,120,110],gcf);

% get selection model
treeSelectionModel = jCheckBoxTree.getSelectionModel();

% define a path
path = javax.swing.tree.TreePath( [ jRoot l1a ] )

% select path
treeSelectionModel.setSelectionPath( path );

% recover selected path
treeSelectionModel.getSelectionPath


end

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us