2012-09-20 4 views
2

J'ai créé un panneau de configuration pour une application JavaFX. J'ai réussi à créer un écouteur de changement dynamique comme suit:Validation à l'aide de bindin

public class InputMaskChecker implements ChangeListener<String> { 

    public static final String NUMERIC  = "^[0-9]*$"; 
    public static final String TEXTONLY  = "^\\w*$"; 
    public static final String PASSWORD  = "^[\\w\\+\\!\\?\\-\\$\\&\\%£]+$"; 
    public static final String DATASOURCE = "^([a-zA-Z]+:){3}@([a-zA-Z0-9]+:)+[a-zA-Z0-9]+$"; 
    public static final String TCPPORT  = "^(6553[0-5]|655[0-2]\\d|65[0-4]\\d\\d|6[0-4]\\d{3}|[1-5]\\d{4}|[2-9]\\d{3}|1[1-9]\\d{2}|10[3-9]\\d|102[4-9])$"; 

    private static final String STYLE = "-fx-effect: dropshadow(gaussian, red, 4, 0.0, 0, 0);"; 

    public final BooleanProperty erroneous = new SimpleBooleanProperty(false); 

    private final String mask; 
    private final int max_lenght; 
    private final TextField control; 


    public InputMaskChecker(String mask, TextField control) { 
     this.mask = mask; 
     this.max_lenght = 0; 
     this.control = control; 
    } 

    public InputMaskChecker(String mask, int max_lenght, TextField control) { 
     this.mask = mask; 
     this.max_lenght = max_lenght; 
     this.control = control; 
    } 

    @Override 
    public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) { 
     erroneous.setValue(!newValue.matches(mask) || ((max_lenght > 0) ? newValue.length() > max_lenght : false) || newValue.length() == 0); 
     control.setStyle(erroneous.get() ? STYLE : "-fx-effect: null;"); 
    } 
} 

utiliser dans mon contrôleur comme ceci:

field1.textProperty().addListener(new InputMaskChecker(InputMaskChecker.DATASOURCE, field1)); 
field2.textProperty().addListener(new InputMaskChecker(InputMaskChecker.TEXTONLY, field2)); 
field3.textProperty().addListener(new InputMaskChecker(InputMaskChecker.PASSWORD, field3)); 
field4.textProperty().addListener(new InputMaskChecker(InputMaskChecker.NUMERIC, 1, field4)); 

Il fonctionne comme prévu avec un petit problème: je voudrais avoir mon bouton SAVE sur le contrôleur principal réagissent aux auditeurs d'une manière qui est désactivée si un champ a une erreur.

C'est maintenant ma demande de brainstorming. Avez-vous des suggestions?

L'utilisation d'un partage SimpleBooleanProperty, AND-ing auditeurs ne fonctionnera pas évidemment.

(solution) MISE À JOUR: Ajouter une variable private final BooleanBinding binding; au contrôleur. Puis:

InputMaskChecker listener1 = new InputMaskChecker(InputMaskChecker.DATASOURCE, field1); 
InputMaskChecker listener2 = new InputMaskChecker(InputMaskChecker.DATASOURCE, field2); 
InputMaskChecker listener3 = new InputMaskChecker(InputMaskChecker.DATASOURCE, field3); 
InputMaskChecker listener4 = new InputMaskChecker(InputMaskChecker.DATASOURCE, field4); 

field1.textProperty().addListener(listener1); 
field2.textProperty().addListener(listener2); 
field3.textProperty().addListener(listener3); 
field4.textProperty().addListener(listener4); 

binding = new BooleanBinding() { 
    { 
    super.bind(listener1.erroneous, listener2.erroneous, listener3.erroneous, listener4.erroneous); 
    } 

    @Override 
    protected boolean computeValue() { 
     return (listener1.erroneous.get() || listener2.erroneous.get() || listener3.erroneous.get() || listener4.erroneous.get()); 
    } 
}; 

control.getDisableProperty().bind(binding); 

Terminé;)

Répondre

0

je peux suggérer à côté approache:

Assurez-vous InputMaskChecker stateful avec public SimpleBooleanProperty valid; qui sera appelé dans la méthode de mise à jour:

@Override 
public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) { 
    valid.set(!newValue.matches(mask) || ((max_lenght > 0) ? newValue.length() > max_lenght : false) || newValue.length() == 0); 
    // BTW, I would suggest to use styleclasses instead for performance reasons 
    control.setStyle(valid.get() ? STYLE : "-fx-effect: null;): 
} 

alors vous pouvez dire dans "Enregistrer" création de bouton:

Button btn = new Button("Save"); 
btn.disableProperty().bind(
     listener1.valid.and(listener2.valid).and(listener3.valid).not()); 

ou de créer une méthode utilitaire qui ajoutera un écouteur et mettra à jour la propriété "Enregistrer" désactivée.

+0

Résolu avec une liaison de bas niveau. De toute façon, vous ne pouvez pas utiliser des stylets avec ceci. J'ai essayé mais, une fois ajouté un styleclass, il ne le supprime pas après ... même en utilisant la méthode '.setEffect (new Dropshadow (...));' ne fonctionne pas. La seule chance est 'control.setStyle (valide.get()? STYLE:" -fx-effect: null;); ' – matticala

+0

setEffect() ne devrait pas fonctionner setStyle() a la plus grande priorité dans les commandes de styles Voir http://stackoverflow.com/questions/12333985/javafx-can-not-set-font-size-programmatically-after-font-being-set-by-css/12334881#12334881 –

+0

alors que vous avez résolu une autre question De cette façon, s'il vous plaît, postez votre code comme une réponse distincte et acceptez votre propre réponse au lieu de la mienne –

Questions connexes