2015-07-22 2 views
5

Sono nuovo di JavaFx, sto creando un'applicazione in cui l'utente deve compilare alcuni moduli e volevo "pre validarli" con i binding. Oggetti semplici come nessuno degli elementi possono essere vuoti o alcuni di essi possono contenere solo numeri. Ecco quello che ho finora:Binding condizionale

saveBtn.disableProperty().bind(Bindings.when(
      departureHourText.textProperty().isNotEqualTo("") 
        .and(isNumber(departureHourText.getText()))) 
      .then(false) 
      .otherwise(true)); 

Ecco il mio metodo isNumber:

private BooleanProperty isNumber(String string) { 
    return new SimpleBooleanProperty(string.matches("[0-9]+")); 
} 

ma il pulsante è continuare a essere disattivata non importa ciò che scriv nel campo di testo.

Qualsiasi aiuto è molto apprezzato.

UPDATE

Quando ho valutare questa espressione: departureHourText.textProperty().isNotEqualTo("") il risultato sarà: BooleanBinding [invalid]

risposta

10

tua espressione è un po 'fuori.

Proviamo a testare entrambe le parti del tuo estratto conto logica:

saveBtn.disableProperty().bind(Bindings.when(
     departureHourText.textProperty().isNotEqualTo("")) 
     .then(false) 
     .otherwise(true)); 

Il codice precedente funziona correttamente. Quando aggiungi una stringa alla casella di testo, otterrai un evento di attivazione/disattivazione del pulsante.

saveBtn.disableProperty().bind(Bindings.when(
     isNumber(departureHourText.getText())) 
     .then(false) 
     .otherwise(true)); 

Il codice sopra riportato fa sì che il pulsante sia sempre bloccato come disabilitato. Analizziamo perché.

Aggiungiamo un comunicato stampa nel metodo ISNUMBER():

private BooleanProperty isNumber(String string) { 
System.out.println("This was called"); 
return new SimpleBooleanProperty(string.matches("[0-9]+")); 
} 

Se guardiamo a quando questo viene eseguito quando si inizia a digitare, troviamo che esso è chiamato solo quando abbiamo inizialmente dichiariamo il legame! Questo perché il tuo metodo non sa quando essere chiamato, quindi il binding lo vede solo inizialmente, quando è falso perché non ci sono numeri nel campo.

Quello che dobbiamo fare è trovare un modo in modo che quando la nostra proprietà di testo viene aggiornata, sappia cambiare stato. Se guardiamo il nostro isNotEqualTo() come esempio, scopriremo che probabilmente vorremmo cercare un modo per creare un nuovo BooleanBinding in qualche modo.

Ora ho trovato una funzione e ho modificato da un collegamento github (https://gist.github.com/james-d/9904574). Il link indica come possiamo creare un nuovo BooleanBinding da un modello regex.

In primo luogo, facciamo un nuovo modello:

Pattern numbers = Pattern.compile("[0-9]+"); 

Quindi creare la funzione di legame:

BooleanBinding patternTextAreaBinding(TextArea textArea, Pattern pattern) { 
BooleanBinding binding = Bindings.createBooleanBinding(() -> 
    pattern.matcher(textArea.getText()).matches(), textArea.textProperty()); 
return binding ; 
} 

Quindi, con che ora possiamo fare quello che si voleva fare! Cambiamo semplicemente la tua funzione precedente per la nostra nuova funzione patternTextAreaBinding (TextArea textArea, Pattern pattern) e passiamo nei nostri due valori, l'area di testo che vuoi tenere traccia e il Pattern a cui vuoi aderire (ho chiamato il modello sopra i numeri).

saveBtn.disableProperty().bind(Bindings.when(
     departureHourText.textProperty().isNotEqualTo("") 
       .and(patternTextAreaBinding(departureHourText,numbers))) 
     .then(false) 
     .otherwise(true)); 

Spero che ti aiuti!

0

Mi chiedo se l'espressione potrebbe essere scritta senza il when? If (x) then false else true; sembra essere ridondante e potrebbe forse essere semplificata utilizzando not (x) ...

Ci può essere un'opzione di utilizzare solo il .not() invece come in: .bind(departureHourText.textProperty().isNotEqualTo("").and(patternTextAreaBinding(departureHourText,numbers))).not())