Path: csiph.com!feeder.erje.net!2.eu.feeder.erje.net!news-1.dfn.de!news.dfn.de!cache.uni-koblenz.de!not-for-mail From: Tassilo Horn Newsgroups: comp.lang.java.programmer Subject: JavaFX: Bindings, StringConverters, and ChangeListeners Date: Wed, 22 Jun 2016 15:18:09 +0200 Organization: University Koblenz-Landau Campus Koblenz Lines: 49 Message-ID: <87wplhbbvy.fsf@gnu.org> NNTP-Posting-Host: j289989.servers.jiffybox.net Mime-Version: 1.0 Content-Type: text/plain X-Trace: cache.uni-koblenz.de 1466601489 23348 134.119.24.195 (22 Jun 2016 13:18:09 GMT) X-Complaints-To: news@cache.uni-koblenz.de NNTP-Posting-Date: Wed, 22 Jun 2016 13:18:09 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.1.50 (gnu/linux) Cancel-Lock: sha1:HKOPRS6fhazULuPB+wTl15Y3bFM= Xref: csiph.com comp.lang.java.programmer:34690 Hi all, I'm doing my first JavaFX UI stuff and basically come along quite well. However, there's one absurdly simple problem which I've not been able to solve completely. I have a TextField txtMaxTreffer whose textProperty() is bidirectionally bound to some IntegerProperty maxTreffer using a NumberStringConverter. txtMaxTreffer.textProperty().bindBidirectional(maxTreffer, new NumberStringConverter()); To prevent the user from entering invalid input, the textProperty() also has a ChangeListener that resets to the old value in case the new value cannot be parsed to an Integer. In general, that works just fine meaning that the user cannot enter wrong input, and thus the NumberStringConverter which is implicitly invoked by the binding is always able to transfer the TextField value to the IntegerProperty. Well, there is one situation where it doesn't work so well: When you prepend to the input of the TextField (or the input has been empty). In that case (and only in that case), it seems the NumberStringConverter is invoked first and only afterwards the ChangeListener is called. Obviously, my mechanics rely on the opposite order. That is, let's say the textfield's value is "100" and now you prepend an X to make the value "X100". Then the NumberStringConverter.fromString() method gets invoked with "X100" and throws a ParseException. Then, my ChangeListener is called and changes the invalid value back to "100". In the other two cases where I enter the invalid input in the middle ("1X00") or at the end ("100X"), first my ChangeListener is called and resets back to "100" before the NumberStringConverter has its turn. Ok, the only bad effect here is that a ParseException is logged to stderr but I guess there must be some way to make that work without exception, too. Of course I could provide my own NumberStringConverter which checks for valid input before trying to parse the string to a number but then I'd have the very same checks in both the converter and the change listener. Any other ideas? Maybe a ChangeListener is not the right thing for validation and correction anyhow? Thanks, Tassilo