1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation. Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 /**
  26  * @author Andrey Nazarov
  27  */
  28 package javafx.factory;
  29 
  30 import com.sun.javafx.collections.ObservableListWrapper;
  31 import java.lang.reflect.Constructor;
  32 import java.lang.reflect.Method;
  33 import java.time.LocalDate;
  34 import java.time.Month;
  35 import java.util.Arrays;
  36 import java.util.EnumSet;
  37 import java.util.Set;
  38 import javafx.beans.property.SimpleObjectProperty;
  39 import javafx.beans.property.SimpleStringProperty;
  40 import javafx.beans.property.StringProperty;
  41 import javafx.beans.value.ObservableValue;
  42 import javafx.collections.FXCollections;
  43 import javafx.collections.ObservableList;
  44 import javafx.geometry.HPos;
  45 import javafx.geometry.Rectangle2D;
  46 import javafx.scene.Node;
  47 import javafx.scene.control.Accordion;
  48 import javafx.scene.control.Button;
  49 import javafx.scene.control.ButtonBuilder;
  50 import javafx.scene.control.CheckBox;
  51 import javafx.scene.control.CheckBoxBuilder;
  52 import javafx.scene.control.ChoiceBox;
  53 import javafx.scene.control.ColorPicker;
  54 import javafx.scene.control.ComboBox;
  55 import javafx.scene.control.Control;
  56 import javafx.scene.control.DatePicker;
  57 import javafx.scene.control.Hyperlink;
  58 import javafx.scene.control.HyperlinkBuilder;
  59 import javafx.scene.control.Label;
  60 import javafx.scene.control.LabelBuilder;
  61 import javafx.scene.control.ListView;
  62 import javafx.scene.control.Menu;
  63 import javafx.scene.control.MenuBar;
  64 import javafx.scene.control.MenuItem;
  65 import javafx.scene.control.Pagination;
  66 import javafx.scene.control.PasswordField;
  67 import javafx.scene.control.PasswordFieldBuilder;
  68 import javafx.scene.control.ProgressBar;
  69 import javafx.scene.control.ProgressBarBuilder;
  70 import javafx.scene.control.ProgressIndicator;
  71 import javafx.scene.control.ProgressIndicatorBuilder;
  72 import javafx.scene.control.RadioButton;
  73 import javafx.scene.control.RadioButtonBuilder;
  74 import javafx.scene.control.ScrollBar;
  75 import javafx.scene.control.ScrollBarBuilder;
  76 import javafx.scene.control.ScrollPane;
  77 import javafx.scene.control.Separator;
  78 import javafx.scene.control.SeparatorBuilder;
  79 import javafx.scene.control.Slider;
  80 import javafx.scene.control.SliderBuilder;
  81 import javafx.scene.control.SplitMenuButton;
  82 import javafx.scene.control.SplitMenuButtonBuilder;
  83 import javafx.scene.control.SplitPane;
  84 import javafx.scene.control.SplitPaneBuilder;
  85 import javafx.scene.control.Tab;
  86 import javafx.scene.control.TabPane;
  87 import javafx.scene.control.TableColumn;
  88 import javafx.scene.control.TableColumn.CellDataFeatures;
  89 import javafx.scene.control.TableView;
  90 import javafx.scene.control.TextArea;
  91 import javafx.scene.control.TextAreaBuilder;
  92 import javafx.scene.control.TextField;
  93 import javafx.scene.control.TextFieldBuilder;
  94 import javafx.scene.control.TitledPane;
  95 import javafx.scene.control.ToggleButton;
  96 import javafx.scene.control.ToggleButtonBuilder;
  97 import javafx.scene.control.ToolBar;
  98 import javafx.scene.control.TreeItem;
  99 import javafx.scene.control.TreeTableColumn;
 100 import javafx.scene.control.TreeTableView;
 101 import javafx.scene.control.TreeView;
 102 import javafx.scene.image.Image;
 103 import javafx.scene.image.ImageView;
 104 import javafx.scene.layout.HBox;
 105 import javafx.scene.layout.StackPaneBuilder;
 106 import javafx.scene.layout.VBox;
 107 import javafx.scene.paint.Color;
 108 import javafx.scene.shape.Circle;
 109 import javafx.scene.shape.Rectangle;
 110 import javafx.scene.text.TextAlignment;
 111 import javafx.util.Callback;
 112 
 113 public enum ControlsFactory implements NodeFactory {
 114 
 115     Buttons(new ControlFactory() {
 116         public Control createControl() {
 117             return ButtonBuilder.create().text("Button the first line" + "\nthe sec long line" + "\nthe third line").focusTraversable(false).graphic(new Rectangle(10, 10, Color.RED)).build();
 118         }
 119 
 120         public Class getControlClass() {
 121             return Button.class;
 122         }
 123     }),
 124     ChoiceBoxes(new ControlFactory() {
 125         public Control createControl() {
 126             return new ChoiceBox() {
 127                 {
 128                     getItems().addAll(Arrays.asList("one", "two", "three"));
 129                     setFocusTraversable(false);
 130                     getSelectionModel().select(0);
 131                 }
 132             };
 133         }
 134 
 135         public Class getControlClass() {
 136             return ChoiceBox.class;
 137         }
 138     }),
 139     ComboBoxes(new ControlFactory() {
 140         public Control createControl() {
 141             ComboBox box = new ComboBox();
 142             box.setEditable(false);
 143             box.getItems().addAll("one", "two", "three");
 144             return box;
 145         }
 146 
 147         public Class getControlClass() {
 148             return ComboBox.class;
 149         }
 150     }),
 151     EditableComboBoxes(new ControlFactory() {
 152         public Control createControl() {
 153             ComboBox box = new ComboBox();
 154             box.setEditable(true);
 155             box.getItems().addAll("one", "two", "three");
 156             return box;
 157         }
 158 
 159         public Class getControlClass() {
 160             return ComboBox.class;
 161         }
 162     }),
 163     Paginations(new ControlFactory() {
 164         public Control createControl() {
 165             Pagination ps = new Pagination();
 166             ps.maxPageIndicatorCountProperty().set(3);
 167             return ps;
 168         }
 169 
 170         public Class getControlClass() {
 171             return Pagination.class;
 172         }
 173     }),
 174     ColorPickers(new ControlFactory() {
 175         public Control createControl() {
 176             ColorPicker cp = new ColorPicker();
 177             return cp;
 178         }
 179 
 180         public Class getControlClass() {
 181             return ColorPicker.class;
 182         }
 183     }),
 184     CheckBoxes(new ControlFactory() {
 185         public Control createControl() {
 186             return CheckBoxBuilder.create().text("Check box the first line" + "\nthe sec long line" + "\nthe third line").graphic(new Rectangle(20, 20, Color.web("lightblue"))).focusTraversable(false).build();
 187         }
 188 
 189         public Class getControlClass() {
 190             return CheckBox.class;
 191         }
 192     }),
 193     RadioButtons(new ControlFactory() {
 194         public Control createControl() {
 195             return RadioButtonBuilder.create().text("Radio the first line" + "\nthe sec long line" + "\nthe third line").graphic(new Rectangle(20, 20, Color.web("lightblue"))).focusTraversable(false).textAlignment(TextAlignment.RIGHT).build();
 196         }
 197 
 198         public Class getControlClass() {
 199             return RadioButton.class;
 200         }
 201     }),
 202     TextFields(new ControlFactory() {
 203         public Control createControl() {
 204             return TextFieldBuilder.create().text("Text box the first line" + "\nthe sec long line" + "\nthe third line").focusTraversable(false).build();
 205         }
 206 
 207         public Class getControlClass() {
 208             return TextField.class;
 209         }
 210     }),
 211     TextAreas(new ControlFactory() {
 212         public Control createControl() {
 213             return TextAreaBuilder.create().maxWidth(100).maxHeight(50).text("Text area the first line" + "\nthe sec long line" + "\nthe third line").focusTraversable(false).build();
 214         }
 215 
 216         public Class getControlClass() {
 217             return TextArea.class;
 218         }
 219     }),
 220     PasswordFields(new ControlFactory() {
 221         public Control createControl() {
 222             return PasswordFieldBuilder.create().promptText("Password box the first line" + "\nthe sec long line" + "\nthe third line").focusTraversable(false).build();
 223         }
 224 
 225         public Class getControlClass() {
 226             return PasswordField.class;
 227         }
 228     }),
 229     Sliders(new ControlFactory() {
 230         public Control createControl() {
 231             return SliderBuilder.create().min(0).max(100).value(20).focusTraversable(false).build();
 232         }
 233 
 234         public Class getControlClass() {
 235             return Slider.class;
 236         }
 237     }),
 238     Labels(new ControlFactory() {
 239         public Control createControl() {
 240             return LabelBuilder.create().text("Label the first line" + "\nthe sec longlong line" + "\nthe third line").focusTraversable(false).graphic(new Rectangle(20, 20, Color.web("lightblue"))).build();
 241         }
 242 
 243         public Class getControlClass() {
 244             return Label.class;
 245         }
 246     }),
 247     Hyperlinks(new ControlFactory() {
 248         public Control createControl() {
 249             return HyperlinkBuilder.create().text("Hyperlink the first line" + "\nthe sec long line" + "\nthe third line").focusTraversable(false).graphic(new Circle(10, Color.BLUE)).build();
 250         }
 251 
 252         public Class getControlClass() {
 253             return Hyperlink.class;
 254         }
 255     }),
 256     ImageView(new ControlFactory() {
 257         public Node createControl() {
 258             return new ImageView(new Image(ControlsFactory.class.getResourceAsStream("big_tiger_e0.gif")));
 259         }
 260 
 261         public Class getControlClass() {
 262             return ImageView.class;
 263         }
 264     }),
 265     MediaView(new ControlFactory() {
 266         public Node createControl() {
 267 //    Lines are disabled due to impossibleness of stream using.
 268 //    String path = System.getProperty("user.dir");
 269 //    while (path.indexOf("\\") != -1) {
 270 //        path = path.replace("\\", "/");
 271 //    }
 272 //    MediaPlayer mediaPlayer = new MediaPlayer(new Media("file:///" + path + "/content/somefile.flv"));
 273 //    mediaPlayer.play();
 274             Node node = null;
 275             try {
 276                 Class<?> mediaViewCl = Class.forName("javafx.scene.media.MediaView");
 277                 Class<?> mediaPlayerCl = Class.forName("javafx.scene.media.MediaPlayer");
 278                 Constructor<?> constructor = mediaViewCl.getConstructor(mediaPlayerCl);
 279                 constructor.setAccessible(true);
 280                 Object args = null;
 281                 node = (Node) constructor.newInstance(args);
 282                 Method setViewport = mediaViewCl.getDeclaredMethod("setViewport", Rectangle2D.class);
 283                 setViewport.invoke(node, new Rectangle2D(0, 0, 100, 100));
 284                 node.setStyle("-fx-stroke: black;");
 285             } catch (Exception ignored) {
 286                 ignored.printStackTrace();
 287             }
 288             return node;
 289         }
 290 
 291         public Class getControlClass() {
 292             Class controlClass = null;
 293             try {
 294                 controlClass = Class.forName("javafx.scene.media.MediaView");
 295             } catch (Exception ignored) {
 296             }
 297             return controlClass;
 298         }
 299     }),
 300     Separators(new ControlFactory() {
 301         public Control createControl() {
 302             Separator sep = SeparatorBuilder.create().halignment(HPos.CENTER).build();
 303             sep.setPrefWidth(80);
 304             return sep;
 305         }
 306 
 307         public Class getControlClass() {
 308             return Separator.class;
 309         }
 310     }),
 311     ScrollBars(new ControlFactory() {
 312         public Control createControl() {
 313             return ScrollBarBuilder.create().value(45).min(0).max(100).focusTraversable(false).build();
 314         }
 315 
 316         public Class getControlClass() {
 317             return ScrollBar.class;
 318         }
 319     }),
 320     ScrollPanes(new ControlFactory() {
 321         public Node createControl() {
 322             ScrollPane pane = new ScrollPane();
 323             HBox hbox = new HBox(30);
 324             VBox vbox1 = new VBox(10);
 325             vbox1.getChildren().addAll(new Label("one"), new Button("two"), new CheckBox("three"), new RadioButton("four"), new Label("five"));
 326             VBox vbox2 = new VBox(10);
 327             vbox2.getChildren().addAll(new Label("one"), new Button("two"), new CheckBox("three"), new RadioButton("four"), new Label("five"));
 328             hbox.getChildren().addAll(vbox1, vbox2);
 329             pane.setContent(hbox);
 330             pane.setFocusTraversable(false);
 331             return pane;
 332         }
 333 
 334         public Class getControlClass() {
 335             return ScrollPane.class;
 336         }
 337     }),
 338     ProgressIndicators(new ControlFactory() {
 339         public Node createControl() {
 340             return ProgressIndicatorBuilder.create().progress(0.85).focusTraversable(false).build();
 341         }
 342 
 343         public Class getControlClass() {
 344             return ProgressIndicator.class;
 345         }
 346     }),
 347     ProgressBars(new ControlFactory() {
 348         public Node createControl() {
 349             return ProgressBarBuilder.create().progress(0.25).focusTraversable(false).build();
 350         }
 351 
 352         public Class getControlClass() {
 353             return ProgressBar.class;
 354         }
 355     }),
 356     ListViews(new ControlFactory() {
 357         public Node createControl() {
 358             ListView list = new ListView();
 359             ObservableListWrapper<String> items = new ObservableListWrapper<String>(Arrays.asList("One", "Two", "Three", "Four", "Five", "Six", "long line long line long line long line"));
 360             list.setItems(items);
 361             list.setPrefWidth(100);
 362             list.setPrefHeight(100);
 363             list.setFocusTraversable(false);
 364             return list;
 365         }
 366 
 367         public Class getControlClass() {
 368             return ListView.class;
 369         }
 370     }),
 371     PressedToggleButtons(new ControlFactory() {
 372         public Control createControl() {
 373             return ToggleButtonBuilder.create().selected(true).text("Button the first line" + "\nthe sec long line" + "\nthe third line").focusTraversable(false).graphic(new Rectangle(10, 10, Color.RED)).build();
 374         }
 375 
 376         public Class getControlClass() {
 377             return ToggleButton.class;
 378         }
 379     }),
 380     UnPressedToggleButtons(new ControlFactory() {
 381         public Control createControl() {
 382             return ToggleButtonBuilder.create().selected(false).text("Button the first line" + "\nthe sec long line" + "\nthe third line").focusTraversable(false).graphic(new Rectangle(10, 10, Color.RED)).build();
 383         }
 384 
 385         public Class getControlClass() {
 386             return ToggleButton.class;
 387         }
 388     }),
 389     Toolbars(new ControlFactory() {
 390         public Node createControl() {
 391             ToolBar toolbar = new ToolBar();
 392             toolbar.getItems().addAll(new Button("One"), new Button("Two"), new Separator(), SplitMenuButtonBuilder.create().text("three").build());
 393             toolbar.setFocusTraversable(false);
 394             return toolbar;
 395         }
 396 
 397         public Class getControlClass() {
 398             return ToolBar.class;
 399         }
 400     }),
 401     Menubars(new ControlFactory() {
 402         public Node createControl() {
 403             MenuBar menubar = new MenuBar();
 404             menubar.getMenus().addAll(new Menu("File"));
 405             menubar.setFocusTraversable(false);
 406             return menubar;
 407         }
 408 
 409         public Class getControlClass() {
 410             return MenuBar.class;
 411         }
 412     }),
 413     SplitMenuButtons(new ControlFactory() {
 414         public Node createControl() {
 415             SplitMenuButton smb = SplitMenuButtonBuilder.create()
 416                     .text("Split box the first line" + "\nthe sec long line" + "\nthe third line")
 417                     .items(new MenuItem("Split box the first line" + "\nthe sec long line" + "\nthe third line",
 418                     new Rectangle(10, 10, Color.BLUE)))
 419                     .graphic(new Rectangle(10, 10, Color.RED))
 420                     .build();
 421             smb.setMinWidth(100);
 422             smb.setFocusTraversable(false);
 423             return smb;
 424         }
 425 
 426         public Class getControlClass() {
 427             return SplitMenuButton.class;
 428         }
 429     }),
 430     TabPanes(new ControlFactory() {
 431         public Node createControl() {
 432             TabPane pane = new TabPane();
 433             Tab tab = new Tab();
 434             tab.setText("tab 1");
 435             HBox content1 = new HBox(10);
 436             content1.getChildren().addAll(new Button("Button"), new Label("Label"), new Rectangle(40, 40, Color.TOMATO));
 437             tab.setContent(content1);
 438             Tab tab2 = new Tab();
 439             tab2.setText("tab 2");
 440             tab2.setContent(new Circle(40, Color.RED));
 441             pane.getTabs().addAll(tab, tab2);
 442             pane.setFocusTraversable(false);
 443             return pane;
 444         }
 445 
 446         public Class getControlClass() {
 447             return TabPane.class;
 448         }
 449     }),
 450     TitledPanes(new ControlFactory() {
 451         public Node createControl() {
 452             TitledPane tpane = new TitledPane();
 453             tpane.setGraphic(new Label("Title"));
 454             VBox content = new VBox(5);
 455             content.getChildren().addAll(new Label("Label"), new Button("Button"), new CheckBox("Check box"));
 456             tpane.setContent(content);
 457             tpane.setAnimated(false);
 458             tpane.setMinWidth(40);
 459             return tpane;
 460         }
 461 
 462         public Class getControlClass() {
 463             return TabPane.class;
 464         }
 465     }),
 466     TableViews(new ControlFactory() {
 467         public Node createControl() {
 468             ObservableList<Person> items = FXCollections.observableArrayList();
 469             for (int i = 0; i < 10; i++) {
 470                 items.add(new Person("name " + i, "surname " + i));
 471             }
 472             TableColumn<Person, Node> column1 = new TableColumn<Person, Node>("First Name");
 473             column1.setCellValueFactory(new Callback<CellDataFeatures<Person, Node>, ObservableValue<Node>>() {
 474                 @Override
 475                 public ObservableValue<Node> call(final CellDataFeatures<Person, Node> p) {
 476                     SimpleObjectProperty<Node> text = new SimpleObjectProperty<Node>();
 477                     text.setValue(new Label(p.getValue().getFirstName()));
 478                     return text;
 479                 }
 480             });
 481             TableColumn<Person, Node> column2 = new TableColumn<Person, Node>("Last Name");
 482             column2.setCellValueFactory(new Callback<CellDataFeatures<Person, Node>, ObservableValue<Node>>() {
 483                 @Override
 484                 public ObservableValue<Node> call(final CellDataFeatures<Person, Node> p) {
 485                     SimpleObjectProperty<Node> text = new SimpleObjectProperty<Node>();
 486                     text.setValue(new Label(p.getValue().getLastName()));
 487                     return text;
 488                 }
 489             });
 490             TableView table = new TableView(items);
 491             table.getColumns().setAll(column1, column2);
 492             table.setPrefHeight(100);
 493             table.setPrefWidth(100);
 494             table.setMinHeight(Control.USE_PREF_SIZE);
 495             table.setFocusTraversable(false);
 496             return table;
 497         }
 498 
 499         public Class getControlClass() {
 500             return TableView.class;
 501         }
 502     }),
 503     TreeTableViews(new ControlFactory() {
 504         public Node createControl() {
 505             ObservableList<TreeItem> items = FXCollections.observableArrayList();
 506             for (int i = 0; i < 10; i++) {
 507                 items.add(new TreeItem(new Person("name " + i, "surname " + i)));
 508             }
 509             TreeTableColumn<Person, Node> column1 = new TreeTableColumn<Person, Node>("First Name");
 510             column1.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<Person, Node>, ObservableValue<Node>>() {
 511                 @Override
 512                 public ObservableValue<Node> call(final TreeTableColumn.CellDataFeatures<Person, Node> p) {
 513                     SimpleObjectProperty<Node> text = new SimpleObjectProperty<Node>();
 514                     text.setValue(new Label(p.getValue().getValue().getFirstName()));
 515                     return text;
 516                 }
 517             });
 518             TreeTableColumn<Person, Node> column2 = new TreeTableColumn<Person, Node>("Last Name");
 519             column2.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<Person, Node>, ObservableValue<Node>>() {
 520                 @Override
 521                 public ObservableValue<Node> call(final TreeTableColumn.CellDataFeatures<Person, Node> p) {
 522                     SimpleObjectProperty<Node> text = new SimpleObjectProperty<Node>();
 523                     text.setValue(new Label(p.getValue().getValue().getLastName()));
 524                     return text;
 525                 }
 526             });
 527             TreeTableView treeTable = new TreeTableView();
 528             treeTable.setRoot(new TreeItem(new Person("root", "root")));
 529             treeTable.getRoot().getChildren().addAll(items);
 530             treeTable.getRoot().setExpanded(true);
 531             treeTable.getColumns().setAll(column1, column2);
 532             treeTable.setPrefHeight(100);
 533             treeTable.setPrefWidth(100);
 534             treeTable.setMinHeight(Control.USE_PREF_SIZE);
 535             treeTable.setFocusTraversable(false);
 536             return treeTable;
 537         }
 538 
 539         public Class getControlClass() {
 540             return TreeTableView.class;
 541         }
 542     }),
 543     TreeViews(new ControlFactory() {
 544         public Node createControl() {
 545             TreeItem<String> root = new TreeItem<String>("ROOT", new Rectangle(20, 20, Color.CHOCOLATE));
 546             root.setExpanded(true);
 547             TreeItem<String> firstBrunch = new TreeItem<String>("brunch 1");
 548             firstBrunch.setExpanded(true);
 549             firstBrunch.getChildren().addAll(new TreeItem<String>("first item"), new TreeItem<String>("second item", new Rectangle(20, 20, Color.DARKGREY)));
 550             root.getChildren().addAll(firstBrunch);
 551             TreeItem<String> secondBrunch = new TreeItem<String>("brunch 2");
 552             secondBrunch.getChildren().addAll(new TreeItem<String>("first item"), new TreeItem<String>("second item", new Rectangle(20, 20, Color.DARKGREY)));
 553             root.getChildren().addAll(secondBrunch);
 554             TreeView tree = new TreeView(root);
 555             tree.setFocusTraversable(false);
 556             tree.setPrefSize(100, 100);
 557             return tree;
 558         }
 559 
 560         public Class getControlClass() {
 561             return TreeView.class;
 562         }
 563     }),
 564     Accordions(new ControlFactory() {
 565         public Node createControl() {
 566             TitledPane pane1 = new TitledPane();
 567             pane1.setGraphic(new Label("title 1\nLong text long text"));
 568             pane1.setContent(new Rectangle(100, 40, Color.SKYBLUE));
 569             TitledPane pane2 = new TitledPane();
 570             pane2.setGraphic(new Label("title 2\nLong text long text"));
 571             pane2.setContent(new Rectangle(100, 40, Color.BLUEVIOLET));
 572             Accordion acc = new Accordion();
 573             acc.getPanes().addAll(pane1, pane2);
 574             acc.setExpandedPane(pane2);
 575             pane2.setAnimated(false);
 576             acc.setFocusTraversable(false);
 577             acc.setMinWidth(100);
 578             return acc;
 579         }
 580 
 581         public Class getControlClass() {
 582             return Accordion.class;
 583         }
 584     }),
 585     SplitPanes(new ControlFactory() {
 586         public Node createControl() {
 587             SplitPane pane = SplitPaneBuilder.create().items(
 588                     StackPaneBuilder.create().children(new Rectangle(40, 40, Color.WHITESMOKE)).build(),
 589                     StackPaneBuilder.create().children(new Rectangle(40, 40, Color.BLUE)).build(),
 590                     StackPaneBuilder.create().children(new Rectangle(40, 40, Color.RED)).build()).prefWidth(150).prefHeight(150).build();
 591             pane.setMinWidth(100);
 592             pane.setDividerPositions(0.33, 0.67);
 593             pane.setFocusTraversable(false);
 594             return pane;
 595         }
 596 
 597         public Class getControlClass() {
 598             return SplitPane.class;
 599         }
 600     }),
 601     DatePickers(new ControlFactory() {
 602         public Node createControl() {
 603             final DatePicker datePicker = new DatePicker();
 604             datePicker.setFocusTraversable(false);
 605             datePicker.setValue(LocalDate.of(2042, Month.MAY, 9));
 606             return datePicker;
 607         }
 608 
 609         public Class getControlClass() {
 610             return DatePicker.class;
 611         }
 612     }),;
 613 
 614     /**
 615      * Returns true/false depending on class presence
 616      *
 617      * @return true - if class is presented, otherwise - false
 618      */
 619     static boolean checkClassOnPresence(String className) {
 620         try {
 621             Class.forName(className);
 622             return true;
 623         } catch (ClassNotFoundException ex) {
 624             return false;
 625         }
 626     }
 627 
 628     /**
 629      * Returns filtered enumeration values, this is required to support embedded
 630      * execution, cause currently JavaFX Embedded does not contain Media
 631      * component.
 632      * <p>
 633      * Currently Class.forName is being used, however as soon as
 634      * ConditionalFeature enumeration will be updated to support MEDIA,
 635      * Class.forName will be substituted with Platform.isSupported method
 636      *
 637      * @return filtered enumeration values
 638      */
 639     public static ControlsFactory[] filteredValues() {
 640         Set<ControlsFactory> controlsSet = EnumSet.allOf(ControlsFactory.class);
 641         if (!checkClassOnPresence("javafx.scene.media.MediaView")) {
 642             controlsSet.remove(ControlsFactory.MediaView);
 643         }
 644         ControlsFactory[] controlsArray = new ControlsFactory[controlsSet.toArray().length];
 645         Arrays.asList(controlsSet.toArray()).toArray(controlsArray);
 646         return controlsArray;
 647     }
 648     private ControlFactory factory;
 649 
 650     ControlsFactory(ControlFactory factory) {
 651         this.factory = factory;
 652     }
 653 
 654     public Node createNode() {
 655         Node node = null;
 656         try {
 657             node = factory.createControl();
 658         } catch (Throwable ex) {
 659             ex.printStackTrace();
 660             node = new Label("Error on control instantiation : " + ex.getMessage());
 661         }
 662         return node;
 663     }
 664 
 665     public Class getControlClass() {
 666         return factory.getControlClass();
 667     }
 668 
 669     private interface ControlFactory {
 670 
 671         /**
 672          * @return current control instance
 673          */
 674         public abstract Node createControl();
 675 
 676         public abstract Class getControlClass();
 677     }
 678 
 679     public static class Person {
 680 
 681         Person(String firstName, String lastName) {
 682             this.firstName = new SimpleStringProperty(firstName);
 683             this.lastName = new SimpleStringProperty(lastName);
 684         }
 685         public StringProperty firstName;
 686 
 687         public void setFirstName(String value) {
 688             firstName.set(value);
 689         }
 690 
 691         public String getFirstName() {
 692             return firstName.get();
 693         }
 694 
 695         public StringProperty firstNameProperty() {
 696             if (firstName == null) {
 697                 firstName = new SimpleStringProperty();
 698             }
 699             return firstName;
 700         }
 701         public StringProperty lastName;
 702 
 703         public void setLastName(String value) {
 704             lastName.set(value);
 705         }
 706 
 707         public String getLastName() {
 708             return lastName.get();
 709         }
 710 
 711         public StringProperty lastNameProperty() {
 712             if (lastName == null) {
 713                 lastName = new SimpleStringProperty();
 714             }
 715             return lastName;
 716         }
 717     }
 718 }