Programmazione:Java/Eclipse RCP/Validazione Text by RegExp
Validation by Regular Expression
Per validare ciò che l'utente digita in un controllo, tipo un Text SWT, il modo migliore è utilizzare le Regular Expression.
Per effettuare queste verifiche non è necessario estendere i componenti, anzi meno vengono estesi i componenti meglio è ^^.
Ecco alcuni esempi di regular expression per effettuare alcune validazioni.
// caratteri stampabili
PRINTABLE_MASK_DATA = "\\p{Print}"
// caratteri
ALFA_MASK_DATA = "\\p{Alpha}"
// caratteri e numeri
ALFANUM_MASK_DATA = "\\p{Alnum}"
// numeri
NUMBER_MASK_DATA = "\\p{Digit}"
// importo formattato con massimo 15 cifre intere e 3 decimali
CURRENCY_MASK_DATA = "[\\p{Digit}]{1,15}[\\,][\\p{Digit}]{0,3}";
Come detto prima la validazione può essere eseguita da codice esterno ai componenti.
Per esempio si potrebbe creare un manager che si occupi di effettuare questa validazione.
public class RETextValidationManager implements Listener {
public RETextValidationManager() {
}
/**
* Aggiunge il controllo della validazione a un componente
*/
public void addValidation(Text control, String mask) {
control.setData(WidgetManager.TEXT_INPUT_MASK_DATA, mask);
control.addListener(SWT.KeyDown, this);
control.addListener(SWT.Dispose, this);
}
/**
* Calcola la stringa generata dalla pressione del tasto
*/
protected String getTextValueOnKeyDown(Event ev) {
Text w = ((Text) ev.widget);
String v = "" + ev.character;
String val = null;
if (w.getSelectionCount() > 0) {
val = w.getText().substring(0, w.getSelection().x) + v + w.getText().substring(w.getSelection().y);
} else {
if (w.getSelection().x == 0) {
val = v + w.getText().substring(w.getSelection().x);
} else {
val = w.getText().substring(0, w.getSelection().x) + v + w.getText().substring(w.getSelection().x);
}
}
return val;
}
public void handleEvent(Event event) {
switch(event.type) {
case SWT.KeyDown:
// come prima verifica controllo se è stato premuto un tasto 'stampabile'
// altrimenti la validazione è inutile
Pattern rePrint = Pattern.compile(WidgetManager.PRINTABLE_MASK_DATA);
if (rePrint.matcher("" + event.character).matches()) {
String val = getTextValueOnKeyDown(event);
String mask = (String) event.widget.getData(WidgetManager.TEXT_INPUT_MASK_DATA);
Pattern reMask = Pattern.compile(mask);
if (!reMask.matcher(val).matches()) {
event.doit = false;
}
}
break;
case SWT.Dispose:
event.widget.removeListener(SWT.KeyDown, textInputMask);
event.widget.removeListener(SWT.Dispose, disposeTextInputMask);
break;
}
}
}
Multiple validation
Utilizzando questo sistema si aprono poi le possibilità di validazioni multiple (condizioni in AND o OR), inventandosi delle convenzioni che spezzano le condizioni. In precedenza è stata utilizzata una regular expression per validare un importo, ma questo non può funzionare correttamente in quanto si aspetterebbe che all'atto della pressione della virgola ci sia già una cifra decimale.
Una soluzione può essere l'inventarsi un separatore che permetta di definire 2 regular expression in OR. Nell'esempio che segue è stato usato come separatore '##'.
// importo formattato con massimo 15 cifre intere e 3 decimali o con al massimo 15 cifre intere senza decimali
CURRENCY_MASK_DATA = "[\\p{Digit}]{1,15}[\\,][\\p{Digit}]{0,3}##[\\p{Digit}]{1,15}";
Per far si che questo funzioni bisogna però modificare la funzione che esegue la validazione in questo modo:
public void handleEvent(Event event) {
switch(event.type) {
case SWT.KeyDown:
// come prima verifica controllo se è stato premuto un tasto 'stampabile'
// altrimenti la validazione è inutile
Pattern rePrint = Pattern.compile(WidgetManager.PRINTABLE_MASK_DATA);
if (rePrint.matcher("" + event.character).matches()) {
String val = getTextValueOnKeyDown(event);
String mask = (String) event.widget.getData(WidgetManager.TEXT_INPUT_MASK_DATA);
String[] masks = mask.split("##");
event.doit = false;
for (int i = 0; i < masks.length; i++) {
Pattern reMask = Pattern.compile(masks[i]);
if (reMask.matcher(val).matches()) {
event.doit = true;
break;
}
}
}
break;
case SWT.Dispose:
event.widget.removeListener(SWT.KeyDown, textInputMask);
event.widget.removeListener(SWT.Dispose, disposeTextInputMask);
break;
}
}