{"id":1307,"date":"2014-07-10T16:08:06","date_gmt":"2014-07-10T14:08:06","guid":{"rendered":"http:\/\/www.jensd.de\/wordpress\/?p=1307"},"modified":"2014-07-10T16:51:29","modified_gmt":"2014-07-10T14:51:29","slug":"ui-logic-with-using-javafx-bindings","status":"publish","type":"post","link":"https:\/\/www.jensd.de\/wordpress\/?p=1307","title":{"rendered":"UI logic with using JavaFX Bindings"},"content":{"rendered":"<p>For<a href=\"http:\/\/www.jensd.de\/wordpress\/?p=1276\" title=\"MQTT.fx 0.0.4 released\"> MQTT.fx<\/a> I needed a ComboBox to enter new Topics or to choose recent topics from list.<br \/>\nBut I want the user to enter or choose only (more or less) reasonable values otherwise the &#8220;Publish&#8221;\/&#8221;Subscribe&#8221; buttons should be disabled:<\/p>\n<p><a href=\"http:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-1.jpg\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"1322\" data-permalink=\"https:\/\/www.jensd.de\/wordpress\/?attachment_id=1322\" data-orig-file=\"https:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-1.jpg\" data-orig-size=\"363,141\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"ComboBox Bindings Demo 1\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-1-300x116.jpg\" data-large-file=\"https:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-1.jpg\" tabindex=\"0\" role=\"button\" src=\"http:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-1.jpg\" alt=\"ComboBox Bindings Demo 1\" width=\"363\" height=\"141\" class=\"aligncenter size-full wp-image-1322\" srcset=\"https:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-1.jpg 363w, https:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-1-300x116.jpg 300w\" sizes=\"(max-width: 363px) 100vw, 363px\" \/><\/a><\/p>\n<p><a href=\"http:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-2.jpg\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"1323\" data-permalink=\"https:\/\/www.jensd.de\/wordpress\/?attachment_id=1323\" data-orig-file=\"https:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-2.jpg\" data-orig-size=\"362,141\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"ComboBox Bindings Demo 2\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-2-300x116.jpg\" data-large-file=\"https:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-2.jpg\" tabindex=\"0\" role=\"button\" src=\"http:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-2.jpg\" alt=\"ComboBox Bindings Demo 2\" width=\"362\" height=\"141\" class=\"aligncenter size-full wp-image-1323\" srcset=\"https:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-2.jpg 362w, https:\/\/www.jensd.de\/wordpress\/wp-content\/uploads\/2014\/07\/ComboBox-Bindings-Demo-2-300x116.jpg 300w\" sizes=\"(max-width: 362px) 100vw, 362px\" \/><\/a><\/p>\n<p>Using the <a href=\"http:\/\/docs.oracle.com\/javafx\/2\/binding\/jfxpub-binding.htm\" title=\"http:\/\/docs.oracle.com\/javafx\/2\/binding\/jfxpub-binding.htm\" target=\"_blank\">JavaFX Bindings API<\/a> prevents some boilerplate code (implementing Listeners) and it is even more flexible as the result can be bound to several controls and at the end of the day its much more readable.<\/p>\n<p><strong>Contraint 1: The selection must not be empty.<\/strong><\/p>\n<ol>\n<li>First create a JavaFX BooleanBinding.<\/li>\n<li>Then bind it to the disabledProperty of the button.<\/li>\n<\/ol>\n<p><strong>Contraint 2: Entered values must not contain only blanks<\/strong> (leading\/trailing blanks can be trimmed later).<\/p>\n<p>My approach is to <\/p>\n<ol>\n<li>add an EventFilter and to consume the event in case of only entered character is &#8220;SPACE&#8221; <\/li>\n<li>and if there are just blanks left when editing the value the content is cleared.<\/li>\n<\/ol>\n<p>[java]<br \/>\npublic class ComboBoxBindingsDemoController {<\/p>\n<p>    @FXML<br \/>\n    private Label valueLabel;<\/p>\n<p>    @FXML<br \/>\n    private Button goButton;<\/p>\n<p>    @FXML<br \/>\n    private ComboBox<String> valueComboBox;<\/p>\n<p>    private ObservableList<String> demoItemsList;<br \/>\n    private static final Pattern LEADING_BLANKS_PATTERN = Pattern.compile(&#8220;^\\\\s*+&#8221;);<\/p>\n<p>    @FXML<br \/>\n    public void initialize() {<br \/>\n        valueComboBox.setItems(getDemoItemsList());<\/p>\n<p>        BooleanBinding goButtonState = valueComboBox.editorProperty().get().textProperty().isEmpty()<br \/>\n                .or(valueComboBox.valueProperty().asString().isEmpty());<\/p>\n<p>        goButton.disableProperty().bind(goButtonState);<\/p>\n<p>        valueComboBox.getEditor().addEventFilter(KeyEvent.KEY_TYPED, (KeyEvent event) -> {<br \/>\n            Matcher matcher = LEADING_BLANKS_PATTERN.matcher(valueComboBox.getEditor().getText());<br \/>\n            if (&#8221; &#8220;.equals(event.getCharacter()) &#038;&#038; valueComboBox.getEditor().getText().length() == 0) {<br \/>\n                event.consume();<br \/>\n            }<br \/>\n            else if(matcher.matches()){<br \/>\n                valueComboBox.getEditor().clear();<br \/>\n            }<br \/>\n        });<\/p>\n<p>    }<\/p>\n<p>    public ObservableList<String> getDemoItemsList() {<br \/>\n        if (demoItemsList == null) {<br \/>\n            demoItemsList = FXCollections.observableArrayList();<br \/>\n            demoItemsList.add(&#8220;Erlangen&#8221;);<br \/>\n            demoItemsList.add(&#8220;N\u00fcrnberg&#8221;);<br \/>\n            demoItemsList.add(&#8220;B\u00fcchenbach&#8221;);<br \/>\n        }<br \/>\n        return demoItemsList;<br \/>\n    }<\/p>\n<p>    @FXML<br \/>\n    public void goAction() {<br \/>\n        System.out.println(&#8220;Value &#8216;&#8221; + valueComboBox.getValue().trim() + &#8220;&#8216;&#8221;);<br \/>\n    }<\/p>\n<p>}<br \/>\n[\/java]<\/p>\n<p><strong>Complete runnable demo can be found at <a href=\"https:\/\/bitbucket.org\/Jerady\/comboboxbindingsdemoapp\/src\" title=\"https:\/\/bitbucket.org\/Jerady\/comboboxbindingsdemoapp\/src\" target=\"_blank\">Bitbucket<\/a>.<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>For MQTT.fx I needed a ComboBox to enter new Topics or to choose recent topics from list. But I want the user to enter or choose only (more or less) reasonable values otherwise the &#8220;Publish&#8221;\/&#8221;Subscribe&#8221; buttons should be disabled: Using the JavaFX Bindings API prevents some boilerplate code (implementing Listeners) and it is even more&hellip; <span class=\"clear\"><\/span><a href=\"https:\/\/www.jensd.de\/wordpress\/?p=1307\" class=\"more-link read-more\" rel=\"bookmark\">Continue Reading <span class=\"screen-reader-text\">UI logic with using JavaFX Bindings<\/span><i class=\"fa fa-arrow-right\"><\/i><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false,"jetpack_publicize_message":"UI logic with using JavaFX Bindings http:\/\/wp.me\/p38FCL-l5","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[51,2,4,49],"tags":[107,76,105],"jetpack_publicize_connections":[],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p38FCL-l5","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1307"}],"collection":[{"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1307"}],"version-history":[{"count":18,"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1307\/revisions"}],"predecessor-version":[{"id":1330,"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1307\/revisions\/1330"}],"wp:attachment":[{"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1307"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1307"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1307"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}