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:
Listbox mousedown problems

Subject: Listbox mousedown problems

From: helper

Date: 12 May, 2008 12:30:31

Message: 1 of 13

Ok, I give up...

I can't even begin to list all the dozens of things I've
tried to make this work, but this problem is fighting back
like I killed its pet hamster.

I have a listbox uicontrol and an edittext uicontrol
working in conjuction to allow me to change the elements of
the listbox. The following is code which reproduces it:

%-----------------------------------------%
function ListBoxTest
figure
hListbox = uicontrol('style','listbox',...
  'pos',[20 20 100 100],...
  'String',{'a','b','c'},...
  'backg','w',...
  'Callback',@(x,y)Listbox_Callback);
hEditText = uicontrol('style','edit',...
  'pos',[20 130 100 20],...
  'String','',...
  'backg','w',...
  'Callback',@(x,y)EditText_Callback);
Listbox_Callback

  function Listbox_Callback
    val = get(hListbox,'Value');
    str = get(hListbox,'String');
    set(hEditText,'String',str{val})
  end

  function EditText_Callback
    val = get(hListbox,'Value');
    str = get(hListbox,'String');
    newStr = get(hEditText,'String');
    str{val} = newStr;
    % pause(1)
    set(hListbox,'String',str)
  end
end
%-----------------------------------------%


Now, typing in the editbox changes the elements of the list
and everything is working fine there.

To see my problem, perform the following steps:

1. Select element 1 in the listbox
2. Click in the editbox and edit the value
3. Click element 3 in the listbox

You will see that the listbox jumps back to element 1, and
the user must click on the listbox again to change the
value.

The problem is caused by the fact that the editbox's
callback changes the "String" property of the listbox, thus
cancelling any mousedown that has previously occurred on
the listbox.

Try uncommenting the PAUSE command, and in step 3 above,
hold the mouse button down on element 3. You will see the
SET command altering the listbox selection.

The root of the problem is that the listbox's callback
doesn't fire until the mouseup, however the editbox's
callback will fire on the mousedown.

Things I have tried:

1. Using the listbox's "ButtonDownFcn" rather than
its "Callback", however this doesn't work for left-click
when "Enable" is "on".

2. Using the FEX's FINDJOBJ function to be able to get a
callback when a mousedown event occurs on the listbox.
However, setting the "MousePressedCallback" (and many other
callback options) doesn't seem to fire when the mouse is
pressed. This is probably the solution, but I can't seem
to get it to work.

3. Using MANY methods for the editbox's callback to
recognize it has been fired by a mousedown event on the
listbox so it can avoid setting the string property until
the listbox's callback has fired. Note that:
  a) checking the PointerPostion property of the root
object to see if it is over the listbox doesn't help
because the callback could have fired from a keypress (tab
or enter).
  b) The currentcharacter property (of the figure) will
tell me that the enter key was pressed, however it will not
tell me that the tab key was pressed.
  c) checking the CurrentObject doesn't work because a
mousedown event on the listbox doesnt change the
CurrentObject.
  d) e) f) g) h) ... z) I can go on

 
I have enjoyed battling this killer rabbit, however it has
beaten me badly and I am crawling outta the cave dragging
my shield behind me.

Does anyone feel like whacking a rabbit?

Subject: Listbox mousedown problems

From: roberson@ibd.nrc-cnrc.gc.ca (Walter Roberson)

Date: 12 May, 2008 17:11:38

Message: 2 of 13

In article <g09d97$ir0$1@fred.mathworks.com>,
helper <spamless@nospam.com> wrote:

>To see my problem, perform the following steps:
>
>1. Select element 1 in the listbox
>2. Click in the editbox and edit the value
>3. Click element 3 in the listbox
>
>You will see that the listbox jumps back to element 1, and
>the user must click on the listbox again to change the
>value.

Did you try recording the Value parameter of the listbox before
the change and then setting the Value of the listbox after
the String has changed? The Value parameter controls which line
of the listbox is the current line.
--
  "There is nothing so bad but it can masquerade as moral."
                                              -- Walter Lippmann

Subject: Listbox mousedown problems

From: helper

Date: 13 May, 2008 00:04:04

Message: 3 of 13

> Did you try recording the Value parameter of the listbox
before
> the change and then setting the Value of the listbox after
> the String has changed? The Value parameter controls
which line
> of the listbox is the current line.

That will not work for me.

The problem is that although the mousedown event changes
which element appears to be selected on the listbox, and
causes the editbox callback to fire, it does not change
the "Value" property in MATLAB. The "Value" property does
not change until the mouseup event.

Subject: Listbox mousedown problems

From: matt dash

Date: 13 May, 2008 04:09:03

Message: 4 of 13

"helper " <spamless@nospam.com> wrote in message
<g0altk$221$1@fred.mathworks.com>...
> > Did you try recording the Value parameter of the listbox
> before
> > the change and then setting the Value of the listbox after
> > the String has changed? The Value parameter controls
> which line
> > of the listbox is the current line.
>
> That will not work for me.
>
> The problem is that although the mousedown event changes
> which element appears to be selected on the listbox, and
> causes the editbox callback to fire, it does not change
> the "Value" property in MATLAB. The "Value" property does
> not change until the mouseup event.
>

This sounds a lot like my problems of trying to make a
scrollbar that you can click and drag.... same thing, you
can't do it with the window motion function because the
value doesn't update until the upbutton. I got around it by
using the java callbacks. You might give that a try if
you're desperate, though I'm not sure what kind of java
callbacks a listbox has. (I used findjobj on the file
exchange and worked from there.)

Subject: Listbox mousedown problems

From: helper

Date: 13 May, 2008 04:29:03

Message: 5 of 13

> This sounds a lot like my problems of trying to make a
> scrollbar that you can click and drag.... same thing, you
> can't do it with the window motion function because the
> value doesn't update until the upbutton. I got around it
by
> using the java callbacks. You might give that a try if
> you're desperate, though I'm not sure what kind of java
> callbacks a listbox has. (I used findjobj on the file
> exchange and worked from there.)


Check bullet #2 on my original post.

I tried this, but I can't seem to actually get the
MousePressedCallback to fire. Some of the java callbacks
will fire (e.g., MouseMovedCallback,
PropertyChangedCallback), but some won't (e.g.,
MousePressedCallback, MouseReleasedCallback,
MouseClickedCallback). I tried:

hListJava = findjobj(hListbox);
hListJava.MousePressedCallback =...
   @(x,y)disp('Mouse Pressed');

However, no callback fires. Any ideas what I am doing
wrong?

Subject: Listbox mousedown problems

From: Malcolm Lidierth

Date: 13 May, 2008 11:32:02

Message: 6 of 13

Why use anonymous functions?
This seems to work - or have I missed the point?

function ListBoxTest
figure
hListbox = uicontrol('style','listbox',...
  'pos',[20 20 100 100],...
  'String',{'a','b','c'},...
  'backg','w',...
  'Callback',@Listbox_Callback);
hEditText = uicontrol('style','edit',...
  'pos',[20 130 100 20],...
  'String','',...
  'backg','w',...
  'Callback',@EditText_Callback);


  function Listbox_Callback(hObject, EventData)
    val = get(hListbox,'Value');
    str = get(hListbox,'String');
    set(hEditText,'String',str{val})
  end

  function EditText_Callback(hObject, EventData)
    val = get(hListbox,'Value');
    str = get(hListbox,'String');
    newStr = get(hEditText,'String');
    str{val} = newStr;
    % pause(1)
    set(hListbox,'String',str)
  end
end

Subject: Listbox mousedown problems

From: helper

Date: 13 May, 2008 12:03:45

Message: 7 of 13

"Malcolm Lidierth" <ku.ca.lck@htreidil.mloclam> wrote in
message <g0bu7i$jkr$1@fred.mathworks.com>...

> Why use anonymous functions?
> This seems to work - or have I missed the point?

You have missed it Malcom. Try out the reproduction steps
in my first post, and you'll see where I am having my
problem.

By the way, I use anonymous functions so I don't have to
have the unused inputs to all of my callbacks. Notice the
little orange squigglies under the inputs arguments within
the MATLAB editor.

Subject: Listbox mousedown problems

From: Malcolm Lidierth

Date: 13 May, 2008 14:27:03

Message: 8 of 13

OK - I think I now see your problem - but I can't help much.

For the findjobj above you may need to dig deeper through
the hierarchy

K>> ans = findjobj(hListbox);
returns a ScrollPane

K>> get(ans.getViewport(), 'View')

gets you to the
com.mathworks.hg.peer.ListboxPeer$UicontrolList

Subject: Listbox mousedown problems

From: matt dash

Date: 13 May, 2008 15:24:03

Message: 9 of 13

Hah, Ok, having completely ignored your first post I feel
obligated to help now. See if this is what you're looking for:

For me this does what I think you want, with the possible
exception that it updates as you type and not when you're
done typing, but maybe that's ok with you. The trick is to
use the callbacks of the editbox, not the list box.

function ListBoxTest
figure
handles.hListbox = uicontrol('style','listbox',...
    'pos',[20 20 100 100],...
    'String',{'a','b','c'},...
    'backg','w',...
    'Callback',@Listbox_Callback);
handles.hEditText = uicontrol('style','edit',...
    'pos',[20 130 100 20],...
    'String','',...
    'backg','w',...
    'Callback',@EditText_Callback);

guidata(gcf,handles)

jEdit=findjobj(handles.hEditText);
jEdit.KeyTypedCallback=@imtyping;


    function Listbox_Callback(hObject, EventData)
        val = get(handles.hListbox,'Value');
        str = get(handles.hListbox,'String');
        set(handles.hEditText,'String',str{val})
    end

    function EditText_Callback(hObject, EventData)
        val = get(handles.hListbox,'Value');
        str = get(handles.hListbox,'String');
        newStr = get(handles.hEditText,'String');
        str{val} = newStr;
        % pause(1)
        set(handles.hListbox,'String',str)
    end

    function imtyping(src,eventdata)
        jEdit=src;
        string=jEdit.getText;
        handles=guidata(gcf);
        val = get(handles.hListbox,'Value');
        str = get(handles.hListbox,'String');
        newStr = char(string);
        str{val} = newStr;
        set(handles.hListbox,'String',str);
        drawnow
        
        
    end

    end

Subject: Listbox mousedown problems

From: helper

Date: 13 May, 2008 15:52:04

Message: 10 of 13

Good idea to have the typing within the edit box update the
listbox string rather than the callback. This does indeed
solve this problem.

Based on Malcom's post, prior to seeing yours, I understood
I was using the wrong java object. Using the correct java
object,

hListJava = findjobj(hListbox);
hListJava = get(hListJava.Viewport,'View');

I am able to know the listbox value based on the mousedown
event and, thus using Walter's idea, "store" the listbox
value prior to setting the "String".

What is interesting here is that upon the mousedown event
the Java object changes its "SelectionIndex" value and
MATLAB fires the EditBox callback. Within the editbox
callback, MATLAB's "Value" property retains the original
listbox value (until the mouseup event), while the Java
object retains the new listbox value. Therefore, I will
simultaneously have acces to both and not need to "store"
the value.

One problem, however, is that I do not like the way
FINDJOBJ "cycles" through all the Java objects to find the
object. It activates and shows all the menu items, and
seems to take a long time to find the requested object.

Isn't there a better way for me to get a handle to this
java object?

Regardless, I think I might implement Matt's "imtyping"
idea since it looks cool for the user. Also, I can do
something similar to this method without having to resort
to using the Java object and instead use MATLAB's
KeyPressFcn. Of course, I will have to accumulate all
keypresses myself (since MATLAB's editbox doesn't update
the "String" property until the callback), but I have done
this successfully before.

Thanks all for your help. You did a fine job killing my
killer rabbit.

Subject: Listbox mousedown problems

From: Malcolm Lidierth

Date: 13 May, 2008 16:34:02

Message: 11 of 13

> Isn't there a better way for me to get a handle to this
> java object?

You could create the java object directly using
javacomponent. Yair's uicomponent and my own jcontrol help
with that, both on ML Central.


>Of course, I will have to accumulate all
keypresses myself....

Noth that, if you use the CallbackFcn(hObject, EventData)
form, the individual key information should be available in
EventData

Subject: Listbox mousedown problems

From: Malcolm Lidierth

Date: 13 May, 2008 16:35:05

Message: 12 of 13

> Isn't there a better way for me to get a handle to this
> java object?

You could create the java object directly using
javacomponent. Yair's uicomponent and my own jcontrol help
with that, both on ML Central.


>Of course, I will have to accumulate all
keypresses myself....

Noth that, if you use the CallbackFcn(hObject, EventData)
form, the individual key information should be available in
EventData

Subject: Listbox mousedown problems

From: Yair Altman

Date: 27 Jul, 2008 20:12:02

Message: 13 of 13

"helper " <spamless@nospam.com> wrote in message [snip]

> hListJava = findjobj(hListbox);
> hListJava = get(hListJava.Viewport,'View');

> One problem, however, is that I do not like the way
> FINDJOBJ "cycles" through all the Java objects to find the
> object. It activates and shows all the menu items, and
> seems to take a long time to find the requested object.


All you need to do is to do is to add the '-nomenu' option
to findjobj:

hListJava = findjobj(hListbox,'-nomenu');

Yair Altman

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