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