- Undocumented Matlab - http://undocumentedmatlab.com -

Editbox data input validation

Posted By Yair Altman On October 2, 2013 | 6 Comments

Last week I explained [1] how Matlab’s editbox control can be customized using its underlying Java component. Today I extend that article by explaining how we can use this information to provide a very user-friendly input-validation function for Matlab editboxes.

Zip-code entry validation example
Zip-code entry validation example


As before, we first need to get the Matlab control’s underlying Java control. This is done using the findjobj [2] utility:

% Prepare the log editbox
hEditbox = uicontrol('Style','edit', 'String','Matlab', ...);
% Get the underlying Java editbox
jEditbox = findjobj(hLogPanel);
try
    % Multi-line editboxes are contained within a scroll-panel
    jEditbox = handle(jEditbox.getViewport.getView, 'CallbackProperties');
catch
    % probably a single-line editbox
end

Callbacks

Once we have the jEditbox reference handle, we can use some ~30 different event callbacks that it exposes [3]. Some of the useful callbacks include:

  • ActionPerformedCallback – fired when <enter> is clicked in the editbox
  • CaretUpdateCallback – fired when the caret position has changed
  • KeyTypedCallback – fired whenever a keyboard button is typed when the editbox has focus

For example:

set(jEditbox, 'KeyPressedCallback',@myValidationFunction);
% Callback function definition
function myValidationFunction(jEditbox, eventData)
    % The following comments refer to the case of Alt-Shift-b
    keyChar = get(eventData,'KeyChar');  % or: eventData.getKeyChar  ==> 'B'
    isAltDown = get(eventData,'AltDown');  % ==> 'on'
    isAltDown = eventData.isAltDown;  % ==> true
    modifiers = get(eventData,'Modifiers');  % or: eventData.getModifiers ==> 9 = 1 (Shift) + 8 (Alt)
    modifiersDescription = char(eventData.getKeyModifiersText(modifiers));  % ==> 'Alt+Shift'
    % (now decide what to do with this key-press...)
end

Using such a validation function enables us to immediately convert typed characters into ‘*’ (in password fields) or check that the input conforms to a standard format such as a 5-digit zip code, a valid-looking email address or a valid-looking credit-card number (Luhn’s algorithm [4], recently featured in a video tutorial [5] by Doug Hull). Of course, there are dedicated JIDE controls [6] that do much of this already, but let’s not digress.
In today’s example, we shall implement a simple input-validation function for a 5-digit zip code. When the input data is invalid, the editbox will be colored red and an appropriate message will appear next to the editbox. In addition, invalid (non-digit) characters shall be rejected with a beep sound.

Zip-code validation example

To illustrate the above, let’s use an example of a 5-digit zip-code entry validation. We start by creating an empty editbox with an associated message label next to it:

figure('Color','w', 'Menubar','none');
hEditbox = uicontrol('Style','edit', 'Pos',[10,10,60,20], 'String','Matlab');  % start with an invalid string
hMessageLabel = uicontrol('Style','text', 'Pos',[80,10,200,20], 'horizontal','left', 'background','w', 'Foreground','red');

Next we get the underlying jEditbox reference and set its entry-validation callback function:

jEditbox = findjobj(hEditbox);  % single-line editbox so there's need to drill-down the scroll-pane
set(jEditbox, 'KeyPressedCallback',{@editboxValidation,hMessageLabel});

Note how we pass the message-label’s handle as an extra input parameter to the callback function.
Now we define the callback function editboxValidation and place it on the Matlab path (for example, by placing the following within editboxValidation.m in a folder that is already on your path):

% editboxValidation - ensure that an editbox input is a valid 5-digit zip code
function editboxValidation(jEditbox, eventData, hMessageLabel)
    keyChar = eventData.getKeyChar;  % see note below about how we can trick Matlab here
    if ~alldigits(keyChar) && isprintable(keyChar)
        beep;
        fixedText = strrep(char(jEditbox.getText), keyChar, '');
        jEditbox.setText(fixedText);
    end
    updateAppearance(jEditbox, hMessageLabel);
end
% Check whether a string only contains digits
function flag = alldigits(str)
    flag = ~isnan(str2double(str));
end
% Check whether a character is printable
function flag = isprintable(keyChar)
    keyVal = double(keyChar);
    flag = ~isempty(keyVal) && keyVal > 31 && keyVal < 128;
end
% Update the GUI appearance based on the editbox text
function updateAppearance(jEditbox, hMessageLabel)
    currentText = char(jEditbox.getText);
    if isempty(currentText)
        set(hMessageLabel, 'String','Please enter a 5-digit zip-code')
        jEditbox.setBorder(javax.swing.border.LineBorder(java.awt.Color.red, 3, false));
    elseif ~alldigits(currentText)
        beep;
        set(hMessageLabel, 'String','Invalid zip: should only contain digits')
        jEditbox.setBorder(javax.swing.border.LineBorder(java.awt.Color.red, 3, false));
    elseif length(currentText) ~= 5
        set(hMessageLabel, 'String','Invalid zip: should have exactly 5 digits')
        jEditbox.setBorder(javax.swing.border.LineBorder(java.awt.Color.red, 3, false));
    else
        set(hMessageLabel, 'String','');
        jEditbox.setBorder(javax.swing.border.LineBorder(java.awt.Color.gray, 1, false));
    end
end

Finally, we call the validation function directly after creating our GUI, to let the user know that the zip-code needs to be entered:

% Note how we trick Matlab by using eventData as a struct rather than a Java object
% (i.e., getKeyChar is set here to be a simple struct field, rather than a Java method)
eventData.getKeyChar = '';
editboxValidation(jEditbox,eventData,hMessageLabel)

Zip-code entry validation example
Zip-code entry validation example

Naturally, this is a very simple example, and you can easily expand it for your needs. But it does show the basic components of any input validation: checking the new data, updating the control as appropriate, and modifying the appearance of the underlying control and of other associated controls.

Available report – “Advanced Customizations of Matlab Uicontrols”

Interested readers can find more information about these and other possible customizations in my report on “Advanced Customizations of Matlab Uicontrols“. This 90-page PDF report can be purchased here [7] ($29, please allow 24 hours for delivery by email). The report explains how to customize Matlab’s uicontrols in ways that are simply not possible using documented Matlab properties. This includes treatment of push buttons, toggle buttons, radio buttons, checkboxes, editboxes, listboxes, popup menus (aka combo-boxes/drop-downs), sliders, labels, and tooltips. Much of the information in the report is also available in hard-copy format in chapter 6 of my Matlab-Java programming book [8].

Categories: GUI, Handle graphics, Java, Medium risk of breaking in future versions, UI controls, Undocumented feature


6 Comments (Open | Close)

6 Comments To "Editbox data input validation"

#1 Pingback By Listbox layout customization | Undocumented Matlab On November 13, 2013 @ 13:08

[…] written on listboxes in a long while, and since I’ve recently posted on related controls (editbox, combo-box), I thought of following up with an article on customizing Matlab listbox layout. By the […]

#2 Comment By David M On February 14, 2015 @ 14:44

For anyone interested in limiting the contents of the editbox in real-time, I recommend using the MaskFormatter wrapped in a JFormattedtextField. Here is an example for a 5 digit zip-code:

jMaskFormatter = javax.swing.text.MaskFormatter('#####');
jFormattedTextField = javax.swing.JFormattedTextField(jMaskFormatter);
javacomponent(jFormattedTextField,[10,10,120,25],gcf);

Info on the MaskFormatter class can be found here:

[15]

#3 Comment By Adam On August 19, 2015 @ 13:19

Keeps showing Java exception errors in the Command Window. I have added some null checks into the editboxValidation function but couldn’t stop the error messages being displayed. When I hit a non-numeric character like space or a letter, computer beeps as it should and a long list of Java exception errors are shown in the Command Window. I am copying the error output below. I would appreciate if you could shed a light. Using MATLAB R2014a 32-bit on Windows 7 64-bit machine. Thank you.

Exception in thread “AWT-EventQueue-0” java.lang.NullPointerException
at javax.swing.text.DefaultCaret.paint(Unknown Source)
at javax.swing.plaf.basic.BasicTextUI.paintSafely(Unknown Source)
at javax.swing.plaf.basic.BasicTextUI.paint(Unknown Source)
at javax.swing.plaf.basic.BasicTextUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$700(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

#4 Comment By b On January 8, 2016 @ 03:22

I have the same issue as Adam. For some reason it helps to display some (invisible) text in the command window before issuing setText(), like so:

fprintf(repmat(' \b',1,500))
jObj.setText(txt);

This helps preventing the aforementioned NPE in most (but not all) cases. Can anyone explain this?

MATLAB 2015b 64-bit on Win7 64-bit machine.

#5 Comment By Pedro Luis Guevara On June 12, 2019 @ 18:46

Good morning. I have the following problem I have a uitable in main GUI that has “n” rows (the rows depend on the value that the user enters in a text box) and 10 columns. I require a code (something like a keypresskeypress event) that allows me to evaluate and discard the entered data that are not numeric both in the uitable and in some text boxes that I have in the main GUI. I do not know much about event management in MATLAB and I’m having a lot of problems with this. My uitable is called (“TablaDatosElementos”) and the text box that allows creating the number of rows is called (“NumElem”) Thank you very much and I hope you can help me.

I am a beginner in the use of MATLAB and more when I use tools that are foreign to it (like JAVA). Will it be that one of you can help me design a code for what I need? I can provide lines of the code of the program that I am doing if that helps.

I hope you can help me with this big problem.

Thank you

#6 Comment By Yair Altman On June 12, 2019 @ 18:49

Pedro – I will be happy to assist you as a professional (paid) consultant. Email me if you are interested.


Article printed from Undocumented Matlab: http://undocumentedmatlab.com

URL to article: http://undocumentedmatlab.com/articles/editbox-data-input-validation

URLs in this post:

[1] explained: http://undocumentedmatlab.com/blog/customizing-editboxes/

[2] findjobj: http://undocumentedmatlab.com/blog/findjobj-find-underlying-java-object/

[3] 30 different event callbacks that it exposes: http://undocumentedmatlab.com/blog/uicontrol-callbacks/

[4] Luhn’s algorithm: https://en.wikipedia.org/wiki/Luhn_algorithm

[5] video tutorial: http://blogs.mathworks.com/videos/2013/09/16/luhn-checksum-implemented-in-matlab/

[6] dedicated JIDE controls: http://undocumentedmatlab.com/blog/uitable-customization-report/#JIDE-Grids

[7] here: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&currency_code=USD&business=altmany@gmail.com&amount=29&item_name=Matlab+uicontrols+customization+report

[8] Matlab-Java programming book: http://undocumentedmatlab.com/matlab-java-book/

[9] IP address input control : http://undocumentedmatlab.com/articles/ip-address-input-control

[10] Smart listbox & editbox scrollbars : http://undocumentedmatlab.com/articles/smart-listbox-editbox-scrollbars

[11] Customizing listbox & editbox scrollbars : http://undocumentedmatlab.com/articles/customizing-listbox-editbox-scrollbars

[12] Rich Matlab editbox contents : http://undocumentedmatlab.com/articles/rich-matlab-editbox-contents

[13] ishghandle's undocumented input parameter : http://undocumentedmatlab.com/articles/ishghandle-undocumented-input-parameter

[14] Accessing plot brushed data : http://undocumentedmatlab.com/articles/accessing-plot-brushed-data

[15] : http://docs.oracle.com/javase/7/docs/api/javax/swing/text/MaskFormatter.html

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.