{"id":6,"date":"2012-05-22T19:09:00","date_gmt":"2012-05-22T19:09:00","guid":{"rendered":"http:\/\/www.jensd.de\/wordpress\/?p=6"},"modified":"2013-02-14T16:17:07","modified_gmt":"2013-02-14T15:17:07","slug":"hands-on-javafx-section-aurea","status":"publish","type":"post","link":"https:\/\/www.jensd.de\/wordpress\/?p=6","title":{"rendered":"First steps with JavaFX"},"content":{"rendered":"<link href=\"http:\/\/google-code-prettify.googlecode.com\/svn\/trunk\/src\/prettify.css\" rel=\"stylesheet\" type=\"text\/css\" \/>\n<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_61 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<p class=\"ez-toc-title\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-69e1ea9cb28ec\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-69e1ea9cb28ec\"  aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#This_tutorial_will_introduce\" title=\"This tutorial will introduce\">This tutorial will introduce<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#Abstract\" title=\"Abstract\">Abstract<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#Objective\" title=\"Objective\">Objective<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#The_Model\" title=\"The Model\">The Model<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#The_UI\" title=\"The UI\u00a0\">The UI\u00a0<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#Title_Label_and_usage_hint\" title=\"Title Label and usage hint\">Title Label and usage hint<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#Indicator\" title=\"Indicator\">Indicator<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#Slider\" title=\"Slider\">Slider<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#Status_Labels\" title=\"Status Labels\">Status Labels<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#Solve_Button\" title=\"Solve Button\">Solve Button<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#Add_the_solve_action\" title=\"Add the solve action\">Add the solve action<\/a><\/li><\/ul><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-12\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#Put_it_all_together\" title=\"Put it all together\">Put it all together<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-13\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#Using_the_GridPane_layout\" title=\"Using the GridPane layout:\">Using the GridPane layout:<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-14\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#java_GridPane_root_new_GridPane_rootsetPaddingnew_Insets20_20_20_20_rootsetGridLinesVisibletrue\" title=\"[java] \nGridPane root = new GridPane(); \nroot.setPadding(new Insets(20, 20, 20, 20)); \nroot.setGridLinesVisible(true);\">[java] \nGridPane root = new GridPane(); \nroot.setPadding(new Insets(20, 20, 20, 20)); \nroot.setGridLinesVisible(true);<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-15\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#Connect_UI_to_Model\" title=\"Connect UI to Model\">Connect UI to Model<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-16\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#Connect_listener_to_refresh_the_indicator\" title=\"Connect listener to refresh the indicator:\">Connect listener to refresh the indicator:<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-17\" href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\/#The_complete_UI_code\" title=\"The complete UI code\">The complete UI code<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h2><span class=\"ez-toc-section\" id=\"This_tutorial_will_introduce\"><\/span>This tutorial will introduce<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ul>\n<li>Clean separation of application UI and logic<\/li>\n<li>Using Builders supporting Fluent API<\/li>\n<li>Effects<\/li>\n<li>Layouts<\/li>\n<li>Property Bindings<\/li>\n<li>EventHandler<\/li>\n<\/ul>\n<h2><span class=\"ez-toc-section\" id=\"Abstract\"><\/span>Abstract<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<div>\n<p><a href=\"http:\/\/3.bp.blogspot.com\/-CWR2jf04AqA\/T7uXXPYUuXI\/AAAAAAAAEeQ\/j3L7uypCT1U\/s1600\/sectio+fomula.png\"><img loading=\"lazy\" decoding=\"async\" alt=\"\" src=\"http:\/\/3.bp.blogspot.com\/-CWR2jf04AqA\/T7uXXPYUuXI\/AAAAAAAAEeQ\/j3L7uypCT1U\/s320\/sectio+fomula.png\" width=\"320\" height=\"151\" border=\"0\" \/><\/a><\/p>\n<p>The\u00a0<em>Golden Ratio<\/em>\u00a0(<em>Golden Mean<\/em>,\u00a0<em>Golden Section<\/em>) is defined as\u00a0\u03c6 = (\u221a5\u00a0+ 1) \/ 2.<\/p>\n<h1><span class=\"ez-toc-section\" id=\"Objective\"><\/span>Objective<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Create an UI to find the golden section by using a slider. Add value labels and an indicator to get green when golden action is hit.<\/p>\n<div><a href=\"http:\/\/2.bp.blogspot.com\/-mf6k5H4gTZs\/T7uXWqzseII\/AAAAAAAAEeM\/jFSIRl7i48c\/s1600\/SectioAurea.png\"><img loading=\"lazy\" decoding=\"async\" alt=\"\" src=\"http:\/\/2.bp.blogspot.com\/-mf6k5H4gTZs\/T7uXWqzseII\/AAAAAAAAEeM\/jFSIRl7i48c\/s400\/SectioAurea.png\" width=\"358\" height=\"400\" border=\"0\" \/><\/a><\/div>\n<h2><\/h2>\n<h2><span class=\"ez-toc-section\" id=\"The_Model\"><\/span>The Model<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Create observable double a and b values and a boolean value to indicate whether the golden section has been hit:<br \/>\n[java]<br \/>\nprivate DoubleProperty aValue = new SimpleDoubleProperty(0.0);<br \/>\nprivate DoubleProperty bValue = new SimpleDoubleProperty(0.0);<br \/>\nprivate BooleanProperty sectioAurea = new SimpleBooleanProperty(false);<br \/>\n[\/java]<\/p>\n<p>Method to calculate the golden section:<br \/>\n[java]<br \/>\nprivate void reCalculate(){<\/p>\n<p>double b = aValue.substract(100).multiply(-1).get();<br \/>\nsetBValue(b);<\/p>\n<p>double result1 = aValue.get()\/bValue.get();<br \/>\nresult1 = Math.round(result1*100.0)\/100.0;<\/p>\n<p>double result2 = (aValue.get()+bValue.get())\/aValue.get();<br \/>\nresult2 = Math.round(result2*100.0)\/100.0;<\/p>\n<p>sectioAurea.set(result1 == result2);<br \/>\n}<br \/>\n[\/java]<br \/>\n<strong>Please note:<\/strong> get() returns the primitive double value, getValue()\u00a0respectively returns the Double instance.<\/p>\n<p>Next attach listeners to re-caculate the golden section indicator on value changes:<br \/>\n[java]<br \/>\nprivate void attachListener(){ChangeListener onChangeListener = new ChangeListener(){<br \/>\n@Override<br \/>\npublic void changed(ObservableValue arg0, Number arg1, Number arg2) {<br \/>\nreCalculate();<br \/>\n}<br \/>\n};<\/p>\n<p>getAValueProperty().addListener(onChangeListener);<br \/>\ngetBValueProperty().addListener(onChangeListener);<br \/>\n}<br \/>\n[\/java]<br \/>\nHere is the complete model code width appropriate getter and setter methods:<br \/>\n[java]<br \/>\npackage de.jensd.javafx.aurea;<\/p>\n<p>import javafx.beans.property.BooleanProperty;<br \/>\nimport javafx.beans.property.DoubleProperty;<br \/>\nimport javafx.beans.property.SimpleBooleanProperty;<br \/>\nimport javafx.beans.property.SimpleDoubleProperty;<br \/>\nimport javafx.beans.value.ChangeListener;<br \/>\nimport javafx.beans.value.ObservableValue;<\/p>\n<p>\/**<br \/>\n*<br \/>\n* @author Jens Deters<br \/>\n*\/<br \/>\npublic class SectioModel {<\/p>\n<p>private DoubleProperty aValue = new SimpleDoubleProperty(0.0);<br \/>\nprivate DoubleProperty bValue = new SimpleDoubleProperty(0.0);<br \/>\nprivate BooleanProperty sectioAurea = new SimpleBooleanProperty(false);<\/p>\n<p>public SectioModel() {<br \/>\nattachListener();<br \/>\n}<\/p>\n<p>private void attachListener(){<\/p>\n<p>ChangeListener onChangeListener = new ChangeListener(){<br \/>\n@Override<br \/>\npublic void changed(ObservableValue arg0, Number arg1, Number arg2) {<br \/>\nreCalculate();<br \/>\n}<br \/>\n};<\/p>\n<p>getAValueProperty().addListener(onChangeListener);<br \/>\ngetBValueProperty().addListener(onChangeListener);<br \/>\n}<\/p>\n<p>public DoubleProperty getAValueProperty() {<br \/>\nreturn aValue;<br \/>\n}<\/p>\n<p>public double getAValue() {<br \/>\nreturn aValue.get();<br \/>\n}<\/p>\n<p>public void setAValue(double d) {<br \/>\naValue.set(d);<br \/>\n}<\/p>\n<p>public DoubleProperty getBValueProperty() {<br \/>\nreturn bValue;<br \/>\n}<\/p>\n<p>public double getBValue() {<br \/>\nreturn bValue.get();<br \/>\n}<\/p>\n<p>public void setBValue(double d) {<br \/>\nbValue.set(d);<br \/>\n}<\/p>\n<p>public BooleanProperty getSectioAureaProperty() {<br \/>\nreturn sectioAurea;<br \/>\n}<\/p>\n<p>public boolean isSectioAurea() {<br \/>\nreturn sectioAurea.get();<br \/>\n}<\/p>\n<p>private void reCalculate(){<\/p>\n<p>double b = aValue.substract(100).multiply(-1).get();<br \/>\nsetBValue(b);<\/p>\n<p>double result1 = aValue.get()\/bValue.get();<br \/>\nresult1 = Math.round(result1*100.0)\/100.0;<\/p>\n<p>double result2 = (aValue.get()+bValue.get())\/aValue.get();<br \/>\nresult2 = Math.round(result2*100.0)\/100.0;<\/p>\n<p>sectioAurea.set(result1 == result2);<br \/>\n}<br \/>\n}<br \/>\n[\/java]<\/p>\n<h2><span class=\"ez-toc-section\" id=\"The_UI\"><\/span><span>The UI\u00a0<\/span><span class=\"ez-toc-section-end\"><\/span><\/h2>\n<div><a href=\"http:\/\/3.bp.blogspot.com\/-6D0rTyvRqMs\/T7uoMEFpupI\/AAAAAAAAEeo\/kXvioemchLk\/s1600\/SectioAurea+with+grid.png\"><img loading=\"lazy\" decoding=\"async\" alt=\"\" src=\"http:\/\/3.bp.blogspot.com\/-6D0rTyvRqMs\/T7uoMEFpupI\/AAAAAAAAEeo\/kXvioemchLk\/s400\/SectioAurea+with+grid.png\" width=\"358\" height=\"400\" border=\"0\" \/><\/a><\/div>\n<h2><span class=\"ez-toc-section\" id=\"Title_Label_and_usage_hint\"><\/span>Title Label and usage hint<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>[java]<br \/>\nText titleText = TextBuilder.create().<br \/>\ntext(&#8220;Sectio Aurea&#8221;).<br \/>\neffect(ds).<br \/>\nfont(Font.font(null, FontWeight.BOLD, 32)).<br \/>\nbuild();<\/p>\n<p>Text descriptionText = TextBuilder.create().<br \/>\ntext(&#8220;Move the slider until your hit the golden section.\\nHint: use the cursor keys for exact control.&#8221;).<br \/>\ntextAlignment(TextAlignment.CENTER).<br \/>\nbuild();<br \/>\n[\/java]<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Indicator\"><\/span>Indicator<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>[java]<br \/>\nStop[] falseStops = new Stop[]{new Stop(0.0, Color.WHITE), new Stop(0.3, Color.RED), new Stop(1.0, Color.DARKRED)};<br \/>\nfalsePaint = new RadialGradient(0.0, 0.0, -10.0, -10.0, 50, false, CycleMethod.NO_CYCLE, falseStops);<\/p>\n<p>Stop[] trueStops = new Stop[]{new Stop(0.0, Color.WHITE), new Stop(0.3, Color.GREENYELLOW), new Stop(1.0, Color.DARKGREEN)};<br \/>\ntruePaint = new RadialGradient(0.0, 0.0, -10.0, -10.0, 50, false, CycleMethod.NO_CYCLE, trueStops);<\/p>\n<p>ellipse = EllipseBuilder.create().<br \/>\nradiusX(30).<br \/>\nradiusY(30).<br \/>\nfill(falsePaint).<br \/>\nbuild();<\/p>\n<p>DropShadow ds = new DropShadow();<br \/>\nds.setOffsetY(3.0f);<br \/>\nds.setColor(Color.color(0.4f, 0.4f, 0.4f));<\/p>\n<p>ellipse.setEffect(ds);<br \/>\n[\/java]<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Slider\"><\/span>Slider<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>[java]<br \/>\nslider = SliderBuilder.create().<br \/>\nmin(model.getAValue()).<br \/>\nmax(model.getBValue()).<br \/>\nshowTickMarks(true).<br \/>\nshowTickLabels(true).<br \/>\nmajorTickUnit(20).<br \/>\nminorTickCount(3).<br \/>\nprefWidth(300).<br \/>\nblockIncrement(0.1f).<br \/>\nbuild();<br \/>\n[\/java]<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Status_Labels\"><\/span>Status Labels<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>[java]<br \/>\naValueText = TextBuilder.create().build();<br \/>\nbValueText = TextBuilder.create().build();<br \/>\naureaText = TextBuilder.create().build();<br \/>\n[\/java]<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Solve_Button\"><\/span>Solve Button<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>[java]<br \/>\nsolveButton = ButtonBuilder.create().text(&#8220;Solve&#8221;).build();<br \/>\n[\/java]<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Add_the_solve_action\"><\/span>Add the solve action<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>[java]<br \/>\nsolveButton.setOnAction(new EventHandler() {<br \/>\n@Override<br \/>\npublic void handle(ActionEvent arg0) {<br \/>\nmodel.setAValue(61.8);<br \/>\n}<br \/>\n});<br \/>\n[\/java]<\/p>\n<h1><span class=\"ez-toc-section\" id=\"Put_it_all_together\"><\/span>Put it all together<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<h2><span class=\"ez-toc-section\" id=\"Using_the_GridPane_layout\"><\/span>Using the GridPane layout:<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<h2><span class=\"ez-toc-section\" id=\"java_GridPane_root_new_GridPane_rootsetPaddingnew_Insets20_20_20_20_rootsetGridLinesVisibletrue\"><\/span>[java]<br \/>\nGridPane root = new GridPane();<br \/>\nroot.setPadding(new Insets(20, 20, 20, 20));<br \/>\nroot.setGridLinesVisible(true);<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>RowConstraints rowInfo = new RowConstraints(100);<br \/>\nColumnConstraints colInfo = new ColumnConstraints(100);<\/p>\n<p>root.getRowConstraints().<br \/>\nadd(rowInfo);<\/p>\n<p>for (int j = 0; j &lt;= 2; j++) {<br \/>\nroot.getColumnConstraints().<br \/>\nadd(colInfo);<br \/>\n}<\/p>\n<p>GridPane.setHalignment(titleText, HPos.CENTER);<br \/>\nGridPane.setHalignment(descriptionText, HPos.CENTER);<br \/>\nGridPane.setHalignment(slider, HPos.CENTER);<br \/>\nGridPane.setHalignment(aValueText, HPos.CENTER);<br \/>\nGridPane.setHalignment(ellipse, HPos.CENTER);<br \/>\nGridPane.setHalignment(bValueText, HPos.CENTER);<br \/>\nGridPane.setHalignment(solveButton, HPos.CENTER);<\/p>\n<p>GridPane.setConstraints(titleText, 0, 0, 3, 1);<br \/>\nGridPane.setConstraints(descriptionText, 0, 1, 3, 1);<br \/>\nGridPane.setConstraints(slider, 0, 2, 3, 1);<br \/>\nGridPane.setConstraints(aValueText, 0, 3);<br \/>\nGridPane.setConstraints(ellipse, 1, 3);<br \/>\nGridPane.setConstraints(bValueText, 2, 3);<br \/>\nGridPane.setConstraints(solveButton, 2, 4);<br \/>\n[\/java]<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Connect_UI_to_Model\"><\/span>Connect UI to Model<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>[java]<br \/>\nmodel.getAValueProperty().<br \/>\nbindBidirectional(slider.valueProperty());<\/p>\n<p>aValueText.textProperty().<br \/>\nbind(model.getAValueProperty().<br \/>\nasString(&#8220;%.1f&#8221;));<br \/>\nbValueText.textProperty().<br \/>\nbind(model.getBValueProperty().<br \/>\nasString(&#8220;%.1f&#8221;));<\/p>\n<p>aureaText.textProperty().<br \/>\nbind(model.getSectioAureaProperty().<br \/>\nasString());<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Connect_listener_to_refresh_the_indicator\"><\/span>Connect listener to refresh the indicator:<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<pre>model.getSectioAureaProperty().\r\n            addListener(new ChangeListener() {<\/pre>\n<p>@Override<br \/>\npublic void changed(ObservableValue arg0, Boolean arg1, Boolean arg2) {<br \/>\nrefreshIndicator();<br \/>\n}<br \/>\n});<br \/>\n[\/java]<\/p>\n<h2><span class=\"ez-toc-section\" id=\"The_complete_UI_code\"><\/span>The complete UI code<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>[java]<br \/>\npackage de.jensd.javafx.aurea;<\/p>\n<p>import javafx.application.Application;<br \/>\nimport javafx.beans.value.ChangeListener;<br \/>\nimport javafx.beans.value.ObservableValue;<br \/>\nimport javafx.event.ActionEvent;<br \/>\nimport javafx.event.EventHandler;<br \/>\nimport javafx.geometry.HPos;<br \/>\nimport javafx.geometry.Insets;<br \/>\nimport javafx.scene.Scene;<br \/>\nimport javafx.scene.control.Button;<br \/>\nimport javafx.scene.control.ButtonBuilder;<br \/>\nimport javafx.scene.control.Slider;<br \/>\nimport javafx.scene.control.SliderBuilder;<br \/>\nimport javafx.scene.effect.DropShadow;<br \/>\nimport javafx.scene.layout.ColumnConstraints;<br \/>\nimport javafx.scene.layout.GridPane;<br \/>\nimport javafx.scene.layout.RowConstraints;<br \/>\nimport javafx.scene.paint.Color;<br \/>\nimport javafx.scene.paint.CycleMethod;<br \/>\nimport javafx.scene.paint.Paint;<br \/>\nimport javafx.scene.paint.RadialGradient;<br \/>\nimport javafx.scene.paint.Stop;<br \/>\nimport javafx.scene.shape.Ellipse;<br \/>\nimport javafx.scene.shape.EllipseBuilder;<br \/>\nimport javafx.scene.text.Font;<br \/>\nimport javafx.scene.text.FontWeight;<br \/>\nimport javafx.scene.text.Text;<br \/>\nimport javafx.scene.text.TextAlignment;<br \/>\nimport javafx.scene.text.TextBuilder;<br \/>\nimport javafx.stage.Stage;<\/p>\n<p>\/**<br \/>\n*<br \/>\n* @author Jens Deters<br \/>\n*\/<br \/>\npublic class SectioAureaApplication extends Application {<\/p>\n<p>private SectioModel model = new SectioModel();<br \/>\nprivate Slider slider;<br \/>\nprivate Text aValueText;<br \/>\nprivate Text bValueText;<br \/>\nprivate Text aureaText;<br \/>\nprivate Ellipse ellipse;<br \/>\nprivate Paint falsePaint;<br \/>\nprivate Paint truePaint;<br \/>\nprivate Button solveButton;<\/p>\n<p>public static void main(String[] args) {<br \/>\nApplication.launch(SectioAureaApplication.class, args);<br \/>\n}<\/p>\n<p>@Override<br \/>\npublic void start(Stage stage) throws Exception {<br \/>\nstage.setTitle(&#8220;Sectio Aurea&#8221;);<\/p>\n<p>model = new SectioModel();<br \/>\nmodel.setAValue(0);<br \/>\nmodel.setBValue(100.9);<\/p>\n<p>slider = SliderBuilder.create().<br \/>\nmin(model.getAValue()).<br \/>\nmax(model.getBValue()).<br \/>\nshowTickMarks(true).<br \/>\nshowTickLabels(true).<br \/>\nmajorTickUnit(20).<br \/>\nminorTickCount(3).<br \/>\nprefWidth(300).<br \/>\nblockIncrement(0.1f).<br \/>\nbuild();<\/p>\n<p>aValueText = TextBuilder.create().<br \/>\nbuild();<\/p>\n<p>bValueText = TextBuilder.create().<br \/>\nbuild();<\/p>\n<p>aureaText = TextBuilder.create().<br \/>\nbuild();<\/p>\n<p>solveButton = ButtonBuilder.create().<br \/>\ntext(&#8220;Solve&#8221;).<br \/>\nbuild();<\/p>\n<p>Stop[] falseStops = new Stop[]{new Stop(0.0, Color.WHITE), new Stop(0.3, Color.RED), new Stop(1.0, Color.DARKRED)};<br \/>\nfalsePaint = new RadialGradient(0.0, 0.0, -10.0, -10.0, 50, false, CycleMethod.NO_CYCLE, falseStops);<\/p>\n<p>Stop[] trueStops = new Stop[]{new Stop(0.0, Color.WHITE), new Stop(0.3, Color.GREENYELLOW), new Stop(1.0, Color.DARKGREEN)};<br \/>\ntruePaint = new RadialGradient(0.0, 0.0, -10.0, -10.0, 50, false, CycleMethod.NO_CYCLE, trueStops);<\/p>\n<p>ellipse = EllipseBuilder.create().<br \/>\nradiusX(30).<br \/>\nradiusY(30).<br \/>\nfill(falsePaint).<br \/>\nbuild();<\/p>\n<p>DropShadow ds = new DropShadow();<br \/>\nds.setOffsetY(3.0f);<br \/>\nds.setColor(Color.color(0.4f, 0.4f, 0.4f));<\/p>\n<p>ellipse.setEffect(ds);<\/p>\n<p>Text titleText = TextBuilder.create().<br \/>\ntext(&#8220;Sectio Aurea&#8221;).<br \/>\neffect(ds).<br \/>\nfont(Font.font(null, FontWeight.BOLD, 32)).<br \/>\nbuild();<\/p>\n<p>Text descriptionText = TextBuilder.create().<br \/>\ntext(&#8220;Move the slider until your hit the golden section.\\nHint: use the cursor keys for exact control.&#8221;).<br \/>\ntextAlignment(TextAlignment.CENTER).<br \/>\nbuild();<\/p>\n<p>\/\/ Put it all together<br \/>\nGridPane root = new GridPane();<br \/>\nroot.setPadding(new Insets(20, 20, 20, 20));<br \/>\nroot.setGridLinesVisible(false);<\/p>\n<p>RowConstraints rowInfo = new RowConstraints(100);<br \/>\nColumnConstraints colInfo = new ColumnConstraints(100);<\/p>\n<p>root.getRowConstraints().<br \/>\nadd(rowInfo);<br \/>\nroot.getRowConstraints().<br \/>\nadd(rowInfo);<\/p>\n<p>for (int j = 0; j &lt;= 2; j++) {<br \/>\nroot.getColumnConstraints().<br \/>\nadd(colInfo);<br \/>\n}<\/p>\n<p>GridPane.setHalignment(titleText, HPos.CENTER);<br \/>\nGridPane.setHalignment(descriptionText, HPos.CENTER);<br \/>\nGridPane.setHalignment(slider, HPos.CENTER);<br \/>\nGridPane.setHalignment(aValueText, HPos.CENTER);<br \/>\nGridPane.setHalignment(ellipse, HPos.CENTER);<br \/>\nGridPane.setHalignment(bValueText, HPos.CENTER);<br \/>\nGridPane.setHalignment(solveButton, HPos.CENTER);<\/p>\n<p>GridPane.setConstraints(titleText, 0, 0, 3, 1);<br \/>\nGridPane.setConstraints(descriptionText, 0, 1, 3, 1);<br \/>\nGridPane.setConstraints(slider, 0, 2, 3, 1);<br \/>\nGridPane.setConstraints(aValueText, 0, 3);<br \/>\nGridPane.setConstraints(ellipse, 1, 3);<br \/>\nGridPane.setConstraints(bValueText, 2, 3);<br \/>\nGridPane.setConstraints(solveButton, 2, 4);<\/p>\n<p>root.getChildren().<br \/>\naddAll(titleText, descriptionText, slider, aValueText, ellipse, bValueText, solveButton);<\/p>\n<p>bindProperties();<\/p>\n<p>stage.setScene(new Scene(root, 350, 380));<br \/>\nstage.show();<\/p>\n<p>}<\/p>\n<p>private void refreshIndicator() {<br \/>\nif (model.getSectioAureaProperty().<br \/>\nget()) {<br \/>\nellipse.fillProperty().<br \/>\nset(truePaint);<\/p>\n<p>} else {<br \/>\nellipse.fillProperty().<br \/>\nset(falsePaint);<br \/>\n}<br \/>\n}<\/p>\n<p>private void bindProperties() {<\/p>\n<p>model.getAValueProperty().<br \/>\nbindBidirectional(slider.valueProperty());<\/p>\n<p>aValueText.textProperty().<br \/>\nbind(model.getAValueProperty().<br \/>\nasString(&#8220;%.1f&#8221;));<br \/>\nbValueText.textProperty().<br \/>\nbind(model.getBValueProperty().<br \/>\nasString(&#8220;%.1f&#8221;));<\/p>\n<p>aureaText.textProperty().<br \/>\nbind(model.getSectioAureaProperty().<br \/>\nasString());<\/p>\n<p>model.getSectioAureaProperty().<br \/>\naddListener(new ChangeListener() {<\/p>\n<p>@Override<br \/>\npublic void changed(ObservableValue arg0, Boolean arg1, Boolean arg2) {<br \/>\nrefreshIndicator();<br \/>\n}<br \/>\n});<\/p>\n<p>solveButton.setOnAction(new EventHandler() {<\/p>\n<p>@Override<br \/>\npublic void handle(ActionEvent arg0) {<br \/>\nmodel.setAValue(61.8);<br \/>\n}<br \/>\n});<\/p>\n<p>}<br \/>\n}<br \/>\n[\/java]<br \/>\n_____________________________________________________<\/p>\n<p>here&#8217;s the\u00a0NetBeans project:\u00a0<a href=\"http:\/\/dl.dropbox.com\/u\/39617681\/SectioAurea.zip\">SectioAurea.zip<\/a><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial will introduce Clean separation of application UI and logic Using Builders supporting Fluent API Effects Layouts Property Bindings EventHandler Abstract The\u00a0Golden Ratio\u00a0(Golden Mean,\u00a0Golden Section) is defined as\u00a0\u03c6 = (\u221a5\u00a0+ 1) \/ 2. Objective Create an UI to find the golden section by using a slider. Add value labels and an indicator to get&hellip; <span class=\"clear\"><\/span><a href=\"https:\/\/www.jensd.de\/wordpress\/?p=6\" class=\"more-link read-more\" rel=\"bookmark\">Continue Reading <span class=\"screen-reader-text\">First steps with JavaFX<\/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":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[9,10,2,4,8,7,6],"tags":[],"jetpack_publicize_connections":[],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p38FCL-6","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/6"}],"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=6"}],"version-history":[{"count":9,"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/6\/revisions"}],"predecessor-version":[{"id":8,"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/6\/revisions\/8"}],"wp:attachment":[{"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jensd.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}