Volevo ottenere qualcosa che assomiglia alla programmazione reattiva funzionale in JavaFX e ho pensato che dal momento che JavaFX supporta già listener e binding tra proprietà dovrebbe essere abbastanza facile, quindi ho creato una piccola struttura per i binding con conversione, ad es. Io ora sono in grado di fare qualcosa del genere (ad esempio a Scala, ma dovrebbe essere possibile capire cosa intendo):JavaFX force recompute binding
val property1: Property[String]
val property2: Property[Path]
Bindings.Conversions
.bindUni(property1).to(property2)
.using(p => p.getFileName.toString)
.connect()
Qui mi legano valore property2
(che è un java.nio.file.Path
) attraverso una funzione di conversione, che prende l'ultima parte del percorso e la converte in una stringa in property1
(che è una stringa).
L'attuazione di questo è molto semplice (anche per le associazioni bidirezionali; ho semplicemente preso un po 'di codice da openjfx BidirectionalBinding
classe, tradotto alla Scala e adattato per le conversioni), e mi chiedo perché non v'è nulla di simile in JavaFX già .
Questo funziona tutto bene e riesco persino a creare catene complesse di tali associazioni. Tutto è OK a meno che la funzione di conversione non dipenda da qualche stato esterno.
Supponiamo, per esempio, che si ha la seguente catena di attacchi:
Text field value -1-> intermediate java.nio.file.Path -2-> another String --> Label
Quando i cambiamenti del campo di testo, Path
e String
vengono ricalcolate automaticamente, e il valore della proprietà String viene scritto sull'etichetta. Tutto è meraviglioso. Ma supponiamo che -2->
conversione dovrebbe dipendere stato commutato di qualche casella:
Checkbox state ---+
|
Text field value -1-> intermediate java.nio.file.Path -2-> another String --> Label
Cioè, quando casella è selezionata, trasformazione dovrebbe essere leggermente differente.
L'implementazione diretta di tale struttura non funzionerà, ovviamente, poiché la modifica dello stato della casella di controllo non attiva il ricalcolo della catena di trasformazione. Tuttavia, ho scoperto che JavaFX non fornisce alcun mezzo per forzare gli eventi di modifica. Ho provato a sovrascrivere SimpleStringProperty
, ad esempio, esponendo il suo metodo fireValueChangedEvent()
, ma questo non ha aiutato. Attualmente sto facendo qualcosa come textField.setText(""); textField.setText(oldValue);
ma questo è molto brutto e non è la strada giusta, ovviamente.
Mi manca qualcosa, ed è davvero possibile fare ciò che voglio fare, o non c'è nulla del genere e sono completamente fottuto qui?
Se la risposta è no, allora penso che ciò danneggi gravemente l'espressività dell'intero framework. Capisco che posso davvero fare quello che voglio con un numero di ascoltatori, ma questo sarà brutto, e voglio rendere il tutto il più generale possibile.
Questo è qualcosa che ho scoperto anch'io, e ora sto usando l'approccio simile (tramite binding di basso livello). Tuttavia, questo approccio sembra non estendersi bene ai binding bidirezionali con la conversione. Questo non è un problema per il mio caso d'uso, ma comunque penso che * sia * un problema per il framework. Accetterò la tua risposta, poiché questo è essenzialmente ciò che sto usando ora. Grazie. –
Il tuo caso è stato risolto. Per quanto riguarda il problema del framework, consiglierei di presentare un problema su javafx-jira.kenai.com e/o scrivere una mail a [email protected] - ti metterai in contatto direttamente con gli sviluppatori in questo modo. –