How to set a mask in SWT text to allow only Decimals

I want the user to be able to enter only decimal numbers in the text, I do not want him to allow text to be entered as:

  • HI
  • ABC. 34
  • 34.HEY
  • 32.3333.123

I am trying to use VerifyListener, but it only gives me the part of the text that is inserted, so I get the text I want to insert, and the text before inserting, also tried to combine the text, but I am having problems when you delete the key (backspace), and I get a String as 234 [BACKSPACE] 455.

Is there a way to set the mask in the text or successfully combine VerifyEvent with the current text to get "new text" before setting it to text?

+3
source share
4 answers

You need to add Listener to Text using SWT.Verify . Inside this Listener you can verify that the input contains only a decimal number.

Below it will be allowed to insert decimal places in the text box. It will check the value every time you change something in the text and reject it if it is not decimal. This will solve your problem as VerifyListener is executed before new text is inserted. The new text should convey to the listener, which will be accepted.

 public static void main(String[] args) { Display display = Display.getDefault(); final Shell shell = new Shell(display); shell.setLayout(new FillLayout()); final Text textField = new Text(shell, SWT.BORDER); textField.addVerifyListener(new VerifyListener() { @Override public void verifyText(VerifyEvent e) { Text text = (Text)e.getSource(); // get old text and create new text by using the VerifyEvent.text final String oldS = text.getText(); String newS = oldS.substring(0, e.start) + e.text + oldS.substring(e.end); boolean isFloat = true; try { Float.parseFloat(newS); } catch(NumberFormatException ex) { isFloat = false; } System.out.println(newS); if(!isFloat) e.doit = false; } }); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } } 
+8
source

Have you tried FormattedText widgets from the nebula? - This is an easy way to implement such input fields, see http://eclipse.org/nebula/widgets/formattedtext/formattedtext.php

+2
source

To get the behavior that I wanted, I had to use several listeners:

  • VerifyListner restricts characters that are accepted as partial input as you type
  • FocusListener checks for general input when you exit focus. If generic input is invalid, an error will be displayed.
  • ModifyListener checks if decoration errors can hide when typing. It does not show the appearance of the error, since an invalid partial input such as "4e-" is allowed to finally enter "4e-3"

     valueField.addVerifyListener((event) -> restrictInput(event)); valueField.addModifyListener((event) -> validateValueOnChange(valueField.getText())); valueField.addFocusListener(new FocusListener() { @Override public void focusGained(org.eclipse.swt.events.FocusEvent e) {} @Override public void focusLost(org.eclipse.swt.events.FocusEvent event) { validateValueOnFocusLoss(valueField.getText()); } }); protected void restrictInput(VerifyEvent event) { String allowedCharacters = "0123456789.,eE+-"; String text = event.text; for (int index = 0; index < text.length(); index++) { char character = text.charAt(index); boolean isAllowed = allowedCharacters.indexOf(character) > -1; if (!isAllowed) { event.doit = false; return; } } } protected void validateValueOnChange(String text) { try { Double.parseDouble(valueField.getText()); valueErrorDecorator.hide(); } catch (NumberFormatException exception) { //expressions like "5e-" are allowed while typing } } protected void validateValueOnFocusLoss(String value) { try { Double.parseDouble(valueField.getText()); valueErrorDecorator.hide(); } catch (NumberFormatException exception) { valueErrorDecorator.show(); } } 

The ModifyListener modifier can be further improved to check for partial input, which cannot finally give a valid general input, for example. "4e -.... 3". In this special case, ModifyListener should activate the error correction when typing.

+2
source

In addition to @Tom Seidel's answer:
You can use org.eclipse.swt.widgets.Spinner . This allows you to use only numbers. You can specify the minimum and maximum value, and the return value is int , so there is no need to throw String .

 final Composite composite parent = new Composite(superParent, SWT.NONE); parent.setLayout(new FillLayout()); final Spinner spinner = new Spinner(parent, SWT.BORDER); spinner.setvalues(0, 10, Integer.MAX_VALUE, 0, 1, 10); 

The Spinner value can be obtained by calling:

 int selectedValue = spinner.getSelection(); 
0
source

Source: https://habr.com/ru/post/910570/


All Articles