Limiting string length in a Edit Box on Matlab user interfaces - matlab

I inserted an Edit box in a Matlab user interface and I would like to limit the number of characters that an user can type. There is no obvious property on the Edit box (such as "max characters"). I tried to use the callback function, verifying if the current string size on the edit box was bigger than a limit I set and truncating the first characters, however the callback only acted when I clicked outside the edit box and then inside again.
Do you have any idea of how to do this?
Thanks in advance.
EDITED
As suggested by Amro, I tried placing a verification code inside the KeyPressFcn callback of the edit box. I typed the following code:
function prefix_edit_KeyPressFcn(hObject, eventdata, handles)
text = get(hObject, 'String');
if length(text) > 15
set(hObject, 'String', text(1:15));
end
The problem is that the edit box string is only changed when I type something, press Enter and then try to type something again. It seems that the KeyPressFcn is only called after pressing Enter (as mentioned in the forum post that Amro suggested).
The solution proposed in the forum seems too complicated, for such a simple task. Surely there has to be a more elegant way...

Instead of using KeyPressFcn, implement the aforementioned callback function on the KeyTypedCallback property of the underlying Java component, which can be found using the findjobj utility.
Note: do NOT use the underlying Java component's document's lineLimit attribute, since this is a blind alley - a remnant of old Java versions that are not used by Matlab.
You could set your own Document object, but the callback way is simpler I think.

Try to put your logic inside the KeyPressFcn callback function. There is an old newsgroup thread discussing a similar solution.

Related

MATLAB GUI - How do I remove the CreateFcn callback in my code?

I'm currently learning MATLAB's GUIDE gui programming. I notice that when I place some objects in a figure, a corresponding 'CreateFcn' callback function is creating in the associated .m file. MATLAB's comments state that this function is executed when the object is created (I would consider this a constructor for the object).
However, I've noticed that not all objects seem to have this 'CreateFcn' constructor. Static text objects do not appear to have this callback function. And as of currently, it seems like this function just makes the code more difficult to read. Thus I'm curious if I can delete.
By deleting it, I tend to get an error in my code stating that the function can't be found. So my question: is it possible to delete the 'CreateFcn' method to declutter my code?
Thanks,
Surely it is possible.
Double-click the object to open up the inspector window, locate the "CreateFcn" property and set its value to an empty string. Then go to the .m file and remove the code of CreateFcn. This way MATLAB wouldn't complain about the missing CreateFcn anymore.
CreateFcn is not really a constructor per se, since it happens after all properties of the object are already set. It is more like an optional post-constructor event that gives user an opportunity to further customize the object's initial behavior dynamically. For example, you can customize the object's color at creation depending on the background color on which the object appears. For most control objects, the default behavior is probably already good enough for you. So you can safely remove those CreateFcns until you find a good excuse to use one.
1) Goto the View --> Property Inspector
2) expand the Creation and deletion control, remove the text from CreateFcn and DeleteFcn 3) close the property inspector save the respective GUI (Don't forget to save)
4) remove the callbacks in m-script.

How to capture key press in Matlab uipanel

How can one capture keyboard entry inside a uipanel, i.e. when anything in the panel has focus? I've found that uipanel does not have the KeyPressFcn property. I've read this post from Undocumented Matlab about Java callbacks, but I also can't get KeyPressedCallback to work. For example, if I try to this:
set(h_panel, 'KeyPressFcn', #(src, event)key_press(obj, src, event));
I get this error:
The name 'KeyPressFcn' is not an accessible property for an instance of class 'uicontrol'.
The same thing occurs if I try KeyPressedCallback. I'm afraid I'll have to resort to some sort of hack involving the parent figure, which I would like to avoid if possible.
KeyPressedCallback is a property of the underlying Java object, not the original Matlab uicontrol object. To access the underlying Java control of a Matlab uicontrol, you need to use the findjobj utility, as I believe that I explained in my blog post that you referenced (you probably missed that crucial step):
jPanel = findjobj(hPanel);
jPanel.KeyPressedCallback = #myMatlabCallbackFunc;
Note that Matlab panels only became Java-based objects in HG2 (R2014b, see here). So on R2014a and earlier Matlab releases you will not be able to use this technique, only on one of the newer releases.
I don't see any callback properties that you can use or events to which you can attach a listener.
>> events(h_panel)
Events for class matlab.ui.container.Panel:
ObjectBeingDestroyed
LocationChanged
SizeChanged
ButtonDown
Reset
PropertyAdded
PropertyRemoved
Just the mouse event (ButtonDown) and the ButtonDownFcn callback. Perhaps there are other tricks. Ask Yair Altman!
Ultimately, I have found there are two reasonable solutions to this problem, both involving what I originally described as "some sort of hack involving the parent figure". Both of them require some sort of concept of an "active" panel or object within the figure in question.
Solution 1
Rely on the last-clicked object to direct keyboard input in the figure to that object. Use ButtonDownFcn for every object in the figure that needs keyboard input. In the callback, store the handle of the object in the appdata of the figure as the "active" object. (Something like setappdata(h_fig, 'active_obj', h_obj.) Then set KeyPressFcn in the figure to a function that will get that handle out of the appdata and branch accordingly.
Solution 2
Use some sort of keypress scheme to decide which object to direct further input to. This works well if you have a number of similar objects that merely need disambiguation. For example, set the KeyPressFcn of the figure to a function that uses keys 1-9 to indicate the correspondingly numbered object. Direct further keyboard input to that object or a related function.
Neither method is perfect, and I wish there was a way to avoid going through the figure, but in practice these aren't very complicated to implement. I'm actually using both simultaneously.

How to pre-set cursor or selection for default answer in input dialog

If one creates an inputdialog with inputdlg and a default answer, it looks like that:
Which callback command do I need to make it look like that?
The documentation is missing a lot here. It's a kind of "luxury service" for the customer ;)
But I think it would be nice, if it's easy to implement.
This question is actually solved, as I found out that there are convenient functions like uigetfile and uiputfile for my particular case. But the general case of my questions remains unsolved or at least I haven't tested the java approach.
I'm afraid using the builtin inputdlg without changes this is not possible.
At least there's not 'hidden' feature allowing for this.
You'd need access to the underlying java TextField object for that purpose.
You could copy inputdlg to some new place and make your own version of it.
In combination with the findjobj utility the desired functionality in principle exists.
http://www.mathworks.com/matlabcentral/fileexchange/14317-findjobj-find-java-handles-of-matlab-graphic-objects
Things could look like this then:
% create the edit-field:
h = uicontrol('style', 'edit',...);
% get the underlying java object
% this should be a javahandle to a JTextField
jtextfield = findjobj(h);
% set start/end of the selection as desired:
jtextfield.setSelectionStart(startPos);
jtextfield.setSelectionEnd(endPos);

MATLAB GUI Access handles

I am creating a MATLAB GUI that needs to listen to key press information and then update the screen accordingly. This would not be a problem if the callback function for a key press actually had access to the handles object, but it does not. Is there a way to give this callback access to the handles object?
This is how I start my key listener.
set(hObject,'KeyPressFcn',#keyDownListener)
Then I try to handle this in a the defined function
function keyDownListener(src,event)
% need access to handles
end
I have to imagine it is simple, but I can not seem to find a good answer for this. Thanks in advance.
I think you can do the following:
set(hObject,'KeyPressFcn',{#keyDownListener,handles})
and then define the function as:
function keyDownListener(src,event,handles)
You just have to add addtional parameters to your keyDownListener-fcn. There is a special syntax to do this, as explained here:
matlab-callback-function-only-sees-one-parameter-passed-to-it

Custom classes data tooltips in Matlab editor

Does any one would know a way of overriding the data tooltip that is shown when hovering over a variable when we are in the Matlab editor ? I have a custom class that is relatively simple and its content could be shown easily in the tool tip, but Matlab insists on saying it is a 1x1 CustomClass, which is nice and all, but it would be more useful if we could make it to show the content of the object in a nice way. Right now, I have to type the name of the variable in the cmd window e.g. when debugging instead of a short hover on the variable name. Nitpicky, but I'd find it interesting ^^
I've tried to dig a bit using undocumented leads on data tooltips, e.g. http://undocumentedmatlab.com/blog/accessing-the-matlab-editor/
http://undocumentedmatlab.com/blog/spicing-up-matlab-uicontrol-tooltips/
But I don't have the final answer, anyone has any ideas ?
The tooltip seems to get its string by using the disp method. Override disp on your class. In the method body, construct your desired string however you want and then call disp on it. In R2012a at least this works for the debugger tooltip.
Note that you'll need to do a clear classes after editing the class to get MATLAB to recognize the overridden disp.