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 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.
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
> 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.
"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.)
> 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:
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
"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.
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 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
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.
Public Submission Policy
NOTICE: Any content you submit to MATLAB Central, including personal information, is not subject to the protections which may be afforded information collected under other sections of The MathWorks, Inc. Web site. You are entirely responsible for
all content that you upload, post, e-mail, transmit or otherwise make available via MATLAB Central. The MathWorks does not control the content posted by visitors to MATLAB Central and, does not guarantee the accuracy, integrity, or quality of such content.
Under no circumstances will The MathWorks be liable in any way for any content not authored by The MathWorks, or any loss or damage of any kind incurred as a result of the use of any content posted, e-mailed, transmitted or otherwise made available
via MATLAB Central. Read the complete Disclaimer prior to use.