How to do validation of input of a SWT widget (Text)

14,402

Solution 1

The VerifyListener you are creating will be called before any text has actually been entered. You a currently checking the text that has already been entered to see if the value is valid, but it will never be valid because no text has yet been entered.

Try reading the value of e.text to see if it's an integer and use the e.start and e.end properties along with the the getText() you have now to see if the overall new value will be between 0 and 65535.

An easier solution may be to create a ModifyListener that only enables a submit button when the Text widget's text contains a valid port number.

You can try something similar to this:

txtPort.addVerifyListener(new VerifyListener() {  
    @Override  
    public void verifyText(VerifyEvent e) {
        /* Notice how we combine the old and new below */
        String currentText = ((Text)e.widget).getText();
        String port =  currentText.substring(0, e.start) + e.text + currentText.substring(e.end);
        try{  
            int portNum = Integer.valueOf(port);  
            if(portNum <0 || portNum > 65535){  
                e.doit = false;  
            }  
        }  
        catch(NumberFormatException ex){  
            if(!port.equals(""))
                e.doit = false;  
        }  
    }  
});

Solution 2

I want to suggest JFace DataBinding. You can easily add a ControlDecorationSupport to your text field and give the user some indication about what´s going wrong.

/* with portText being your SWT text control */
IObservableValue textObservable = WidgetProperties.text().observe(portText);

UpdateValueStrategy strategy = new UpdateValueStrategy();
strategy.setBeforeSetValidator(new IValidator() {

    @Override
    public IStatus validate(Object value) {
        Integer portNumber = null;
        try {
            portNumber = Integer.valueOf((String) value);
        } catch (NumberFormatException e) {
            return error(e.getMessage() + " is not a number");
        }
        if (portNumber < 0 || portNumber > 65535) {
            return error("Number is out of range");
        }
        return ok();
    }
});

/* with text being the port value in your model */
Binding binding = new DataBindingContext().bindValue(
        textObservable,
        PojoProperties.value(Model.class, "text").observe(this.model), 
        strategy, null);

ControlDecorationSupport.create(binding, SWT.TOP | SWT.LEFT);
Share:
14,402
Cratylus
Author by

Cratylus

Updated on July 16, 2022

Comments

  • Cratylus
    Cratylus almost 2 years

    How can add validation to an SWT widget? E.g. Text?
    I tried both of the following (found online):

    txtPort.addListener(SWT.Verify,new Listener() {  
      @Override  
      public void handleEvent(Event event) {  
          String port = ((Text)event.widget).getText();  
          try{  
              int portNum = Integer.valueOf(port);  
              if(portNum <0 || portNum > 65535){  
                    event.doit = false;  
             }  
          }  
          catch(Exception ex){  
             event.doit = false;  
          }                 
       }  
    });  
    

    Also:

    txtPort.addVerifyListener(new VerifyListener() {  
       @Override  
       public void verifyText(VerifyEvent e) {  
         String port = ((Text)e.widget).getText();  
          try{  
             int portNum = Integer.valueOf(port);  
             if(portNum <0 || portNum > 65535){  
                 e.doit = false;  
              }  
          }  
          catch(Exception ex){  
              e.doit = false;  
          }  
       }  
    });     
    

    If I add a character, the cursor stucks and I can not even delete it.
    Even if I just delete everything the first time, the cursor also stucks and I can not write anything else.
    What am I messing up here? How am I supposed to do the validation of a Text?
    In this case I only want to accept a number serving as port.

  • Cratylus
    Cratylus over 11 years
    Do you have in mind an online example for the proper code of this?
  • Baz
    Baz over 11 years
    +1, but please catch NumberFormatException, don't use Exception when you know which one to catch.
  • Cratylus
    Cratylus over 11 years
    @MikeK:Seems to work but it needs to be modified as follows: catch(Exception ex){ if(!port.equals("")) {e.doit = false;}}