Numeric entry only in edit text MATLAB GUI

I have an edit text in a MATLAB GUI. I want the user to be able to write only numerals and whenever they write a text character, this last character is immediately deleted. Moreover, I don't know in which kind of function to put this code(callback, keypress, etc.).


This is impossible without resorting to Java. That is because MATLAB has no way to access a uicontrol's typed string; you can only access its current string (i.e., after pressing Enter or changing focus).

Below is an imperfect workaround. It uses two identical edit boxes, one on top of the other, but the topmost box is initially hidden. The KeyPressFcn of the visible edit box:

  1. filters the keypresses on numeric-only
  2. accumulates valid keypresses in a string with global storage
  3. sets that string to the current string of the invisible edit box
  4. Makes that invisible edit box visible, so that it occludes the one you're typing in

Its CallBack function then

  1. Takes the string of the normally-invisible box
  2. Sets the always-visible box' string equal to that string
  3. Hides the normally-invisible box again

Here's the implementation (liberally borrowed from here):

function GUI_tst

    % Create new GUI
    G.fh = figure('menubar' , 'none',...
                  'units'   , 'normalized', ...
                  'position', [.4 .4 .2 .2]);

    % The actual edit box
    G.eh1 = uicontrol('style'      , 'edit',...
                     'units'      , 'normalized', ...
                     'position'   , [.1 .4 .8 .2],...
                     'string'     , '',...
                     'KeyPressFcn', @kpr,...
                     'Callback'   , @cll);

    % The "fake" edit box      
    G.eh2 = copyobj(G.eh1, G.fh);
    set(G.eh2, 'Visible', 'off');

    % Its string (global)       
    G.eh_str = '';


    guidata(G.fh, G);

end


% "Real" edit box' KeyPressFcn()   
function kpr(~, evt)

    if isempty(evt.Character)
        return; end

    G = guidata(gcbf);

    % Occlude the "real" editbox with the "fake" one
    set(G.eh2, 'visible', 'on');

    % Accumulate global string if keys are numeric
    if strcmp(evt.Key,'backspace')
        G.eh_str = G.eh_str(1:end-1);

    elseif isempty(evt.Modifier) && ...
           any(evt.Character == char((0:9)+'0') )

        G.eh_str = [G.eh_str evt.Character];        
    end

    % Set & save new string
    set(G.eh2, 'string', G.eh_str);
    guidata(gcbf,G);

end


% "Real" edit box' CallBack()   
function cll(~,~)    
    G = guidata(gcbf);   

    % Set the "real" box' string equal to the "fake" one's, 
    % and make the "fake" one invisible again
    set(G.eh1, 'String', get(G.eh2, 'String'));
    set(G.eh2, 'visible', 'off');
end

This works reasonably well, but it has some drawbacks:

  • because you're typing somewhere you can't see, the cursor is hidden
  • selecting text and pressing backspace/delete does not work
  • it's not very resource efficient

Although it is possible using Java (see this post by MATLAB-god Yair Altman), the simpler and more common way to do it is to just accept that the user is typing invalid input, and only check/correct it in the Callback function (i.e., after pressing Enter).