Commits

shemnon committed c81ba05

update modena

Comments (0)

Files changed (23)

samples/Modena/src/main/java/modena/Modena.java

 /*
- * Copyright (c) 2008, 2012 Oracle and/or its affiliates.
+ * Copyright (c) 2008, 2013 Oracle and/or its affiliates.
  * All rights reserved. Use is subject to license terms.
  *
  * This file is available and licensed under the following license:
  */
 package modena;
 
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+import java.util.Locale;
+import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import javafx.application.Application;
 import javafx.application.Platform;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.embed.swing.SwingFXUtils;
 import javafx.event.ActionEvent;
 import javafx.event.EventHandler;
 import javafx.fxml.FXMLLoader;
-import javafx.scene.Group;
+import javafx.geometry.NodeOrientation;
+import javafx.geometry.Rectangle2D;
 import javafx.scene.Node;
 import javafx.scene.Scene;
+import javafx.scene.SnapshotParameters;
+import javafx.scene.control.ButtonBuilder;
+import javafx.scene.control.ChoiceBox;
+import javafx.scene.control.ColorPicker;
+import javafx.scene.control.ComboBox;
 import javafx.scene.control.Label;
-import javafx.scene.control.ScrollPane;
+import javafx.scene.control.Menu;
+import javafx.scene.control.MenuBar;
+import javafx.scene.control.RadioMenuItem;
+import javafx.scene.control.RadioMenuItemBuilder;
 import javafx.scene.control.ScrollPaneBuilder;
 import javafx.scene.control.Separator;
-import javafx.scene.control.Tab;
 import javafx.scene.control.TabBuilder;
 import javafx.scene.control.TabPane;
 import javafx.scene.control.ToggleButton;
 import javafx.scene.control.ToggleButtonBuilder;
 import javafx.scene.control.ToggleGroup;
 import javafx.scene.control.ToolBar;
+import javafx.scene.control.Tooltip;
+import javafx.scene.image.Image;
+import javafx.scene.image.ImageView;
+import javafx.scene.image.WritableImage;
 import javafx.scene.layout.BorderPane;
 import javafx.scene.layout.HBoxBuilder;
 import javafx.scene.layout.Pane;
+import javafx.scene.paint.Color;
 import javafx.scene.transform.Scale;
-import javafx.scene.transform.Transform;
+import javafx.stage.FileChooser;
 import javafx.stage.Stage;
+import javax.imageio.ImageIO;
 
 public class Modena extends Application {
+    public static final String TEST = "test";
     static {
         System.getProperties().put("javafx.pseudoClassOverrideEnabled", "true");
     }
+    private static final String testAppCssUrl = Modena.class.getResource("TestApp.css").toExternalForm();
+    private static String MODENA_STYLESHEET_URL;
+    private static String MODENA_EMBEDDED_STYLESHEET_URL;
+    private static String MODENA_STYLESHEET_BASE;
+    private static String CASPIAN_STYLESHEET_URL;
+    private static String CASPIAN_STYLESHEET_BASE;
+    static {
+        try {
+            // these are not supported ways to find the platform themes and may 
+            // change release to release. Just used here for testing.
+            File caspianCssFile = new File("../../../javafx-ui-controls/src/com/sun/javafx/scene/control/skin/caspian/caspian.css");
+            if (!caspianCssFile.exists()) {
+                caspianCssFile = new File("rt/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/caspian/caspian.css");
+            }
+            CASPIAN_STYLESHEET_URL = caspianCssFile.exists() ? 
+                    caspianCssFile.toURI().toURL().toExternalForm() :
+                    com.sun.javafx.scene.control.skin.ButtonSkin.class.getResource("caspian/caspian.css").toExternalForm();
+            File modenaCssFile = new File("../../../javafx-ui-controls/src/com/sun/javafx/scene/control/skin/modena/modena.css");
+            if (!modenaCssFile.exists()) {
+                modenaCssFile = new File("rt/javafx-ui-controls/src/com/sun/javafx/scene/control/skin/modena/modena.css");
+            }
+            MODENA_STYLESHEET_URL = modenaCssFile.exists() ? 
+                    modenaCssFile.toURI().toURL().toExternalForm() : 
+                    com.sun.javafx.scene.control.skin.ButtonSkin.class.getResource("modena/modena.css").toExternalForm();
+            MODENA_STYLESHEET_BASE = MODENA_STYLESHEET_URL.substring(0,MODENA_STYLESHEET_URL.lastIndexOf('/')+1);
+            CASPIAN_STYLESHEET_BASE = CASPIAN_STYLESHEET_URL.substring(0,CASPIAN_STYLESHEET_URL.lastIndexOf('/')+1);
+            MODENA_EMBEDDED_STYLESHEET_URL = MODENA_STYLESHEET_BASE + "modena-embedded-performance.css";
+            System.out.println("MODENA_EMBEDDED_STYLESHEET_URL = " + MODENA_EMBEDDED_STYLESHEET_URL);
+        } catch (MalformedURLException ex) {
+            Logger.getLogger(Modena.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
     
+    private final BorderPane outerRoot = new BorderPane();
     private BorderPane root;
+    private SamplePageNavigation samplePageNavigation;
+    private SamplePage samplePage;
+    private Node mosaic;
+    private Node heightTest;
+    private SimpleWindowPage simpleWindows;
+    private Node combinationsTest;
+    private Node customerTest;
+    private Stage mainStage;
+    private Color backgroundColor;
+    private Color baseColor;
+    private Color accentColor;
+    private String fontName = null;
+    private int fontSize = 13;
+    private String styleSheetContent = "";
+    private String styleSheetBase = "";
+    private ToggleButton modenaButton,retinaButton,rtlButton,embeddedPerformanceButton;
+    private TabPane contentTabs;
+    private boolean test = false;
+    private boolean embeddedPerformanceMode = false;
+    private final EventHandler<ActionEvent> rebuild = new EventHandler<ActionEvent>(){
+        @Override public void handle(ActionEvent event) {
+            Platform.runLater(new Runnable() {
+                @Override public void run() {
+                    updateUserAgentStyleSheet();
+                    rebuildUI(modenaButton.isSelected(), retinaButton.isSelected(),
+                              contentTabs.getSelectionModel().getSelectedIndex(),
+                              samplePageNavigation.getCurrentSection());
+                }
+            });
+        }
+    };
+    
+    private static Modena instance;
+
+    public static Modena getInstance() {
+        return instance;
+    }
+    
+    public Map<String, Node> getContent() {
+        return samplePage.getContent();
+    }
+
+    public void setRetinaMode(boolean retinaMode) {
+        if (retinaMode) {
+            contentTabs.getTransforms().setAll(new Scale(2,2));
+        } else {
+            contentTabs.getTransforms().setAll(new Scale(1,1));
+        }
+        contentTabs.requestLayout();
+    }
+    
+    public void restart() {
+        mainStage.close();
+        root = null;
+        accentColor = null;
+        baseColor = null;
+        backgroundColor = null;
+        fontName = null;
+        fontSize = 13;
+        try {
+            start(new Stage());
+        } catch (Exception ex) {
+            throw new RuntimeException("Failed to start another Modena window", ex);
+        }
+    }
     
     @Override public void start(Stage stage) throws Exception {
+        if (getParameters().getRaw().contains(TEST)) {
+            test = true;
+        }
+        mainStage = stage;
+        // set user agent stylesheet
+        updateUserAgentStyleSheet(true);
+        // build Menu Bar
+        outerRoot.setTop(buildMenuBar());
+        outerRoot.setCenter(root);
         // build UI
-        rebuildUI(true, false,0);
+        rebuildUI(true,false,0, null);
         // show UI
-        Scene scene = new Scene(root, 1024, 768);
-        scene.getStylesheets().add(
-                getClass().getResource("TestApp.css").toExternalForm());
+        Scene scene = new Scene(outerRoot, 1024, 768);
+        scene.getStylesheets().add(testAppCssUrl);
         stage.setScene(scene);
-        stage.show();
+        stage.setTitle("Modena");
+//        stage.setIconified(test); // TODO: Blocked by http://javafx-jira.kenai.com/browse/JMY-203
+        stage.show(); // see SamplePage.java:110 comment on how test fails without having stage shown
+        instance = this;
     }
     
-    private void rebuildUI(boolean modena, boolean retina, int selectedTab) {
-        try {
-            // load theme
-            if (modena) {
-                setUserAgentStylesheet(
-                        getClass().getResource("Modena.css").toExternalForm());
-            } else {
-                setUserAgentStylesheet(null);
+    private MenuBar buildMenuBar() {
+        MenuBar menuBar = new MenuBar();
+        menuBar.setUseSystemMenuBar(true);
+        Menu fontSizeMenu = new Menu("Font");
+        ToggleGroup tg = new ToggleGroup();
+        fontSizeMenu.getItems().addAll(
+            buildFontRadioMenuItem("System Default", null, 0, tg),
+            buildFontRadioMenuItem("Mac (13px)", "Lucida Grande", 13, tg),
+            buildFontRadioMenuItem("Windows 100% (12px)", "Segoe UI", 12, tg),
+            buildFontRadioMenuItem("Windows 125% (15px)", "Segoe UI", 15, tg),
+            buildFontRadioMenuItem("Windows 150% (18px)", "Segoe UI", 18, tg),
+            buildFontRadioMenuItem("Linux (13px)", "Lucida Sans", 13, tg),
+            buildFontRadioMenuItem("Embedded Touch (22px)", "Arial", 22, tg),
+            buildFontRadioMenuItem("Embedded Small (9px)", "Arial", 9, tg)
+        );
+        menuBar.getMenus().add(fontSizeMenu);
+        return menuBar;
+    }
+    
+    private void updateUserAgentStyleSheet() {
+        updateUserAgentStyleSheet(modenaButton.isSelected());
+    }
+    
+    private void updateUserAgentStyleSheet(boolean modena) {
+        final SamplePage.Section scrolledSection = samplePageNavigation==null? null : samplePageNavigation.getCurrentSection();
+        if (!modena &&
+            (baseColor == null || baseColor == Color.TRANSPARENT) &&
+            (backgroundColor == null || backgroundColor == Color.TRANSPARENT) &&
+            (accentColor == null || accentColor == Color.TRANSPARENT) &&
+            (fontName == null)) {
+            // no customizations
+            System.out.println("USING NO CUSTIMIZATIONS TO CSS, stylesheet = "+(modena?"modena":"caspian"));
+            setUserAgentStylesheet(modena ? Application.STYLESHEET_MODENA : Application.STYLESHEET_CASPIAN);
+            return;
+        }
+        styleSheetContent = modena ? 
+                loadUrl(MODENA_STYLESHEET_URL) : 
+                loadUrl(CASPIAN_STYLESHEET_URL);
+        if (modena && embeddedPerformanceMode) styleSheetContent += loadUrl(MODENA_EMBEDDED_STYLESHEET_URL);
+        styleSheetBase = modena ? MODENA_STYLESHEET_BASE : CASPIAN_STYLESHEET_BASE;
+        styleSheetContent += "\n.root {\n";
+        System.out.println("baseColor = "+baseColor);
+        System.out.println("accentColor = " + accentColor);
+        System.out.println("backgroundColor = " + backgroundColor);
+        if (baseColor != null && baseColor != Color.TRANSPARENT) {
+            styleSheetContent += "    -fx-base:" + colorToRGBA(baseColor) + ";\n";
+        }
+        if (backgroundColor != null && backgroundColor != Color.TRANSPARENT) {
+            styleSheetContent += "    -fx-background:" + colorToRGBA(backgroundColor) + ";\n";
+        }
+        if (accentColor != null && accentColor != Color.TRANSPARENT) {
+            styleSheetContent += "    -fx-accent:" + colorToRGBA(accentColor) + ";\n";
+        }
+        if (fontName != null) {
+            styleSheetContent += "    -fx-font:"+fontSize+"px \""+fontName+"\";\n";
+        }
+        styleSheetContent += "}\n";
+        
+        // set white background for caspian
+        if (!modena) {
+            styleSheetContent += ".needs-background {\n-fx-background-color: white;\n}";
+        }
+            
+        // load theme
+        setUserAgentStylesheet("internal:stylesheet"+Math.random()+".css");
+        
+        if (root != null) root.requestLayout();
+
+        // restore scrolled section
+        Platform.runLater(new Runnable() {
+            @Override public void run() {
+                samplePageNavigation.setCurrentSection(scrolledSection);
             }
+        });
+    }
+    
+    private void rebuildUI(boolean modena, boolean retina, int selectedTab, final SamplePage.Section scrolledSection) {
+        try {
             if (root == null) {
                 root = new BorderPane();
+                outerRoot.setCenter(root);
             } else {
                 // clear out old UI
                 root.setTop(null);
                 root.setCenter(null);
             }
+            // Create sample page and nav
+            samplePageNavigation = new SamplePageNavigation();
+            samplePage = samplePageNavigation.getSamplePage();
             // Create Content Area
-            final TabPane contentTabs = new TabPane();
+            contentTabs = new TabPane();
             contentTabs.getTabs().addAll(
-                TabBuilder.create().text("All Controls").content(
+                TabBuilder.create().text("All Controls").content( samplePageNavigation ).build(),
+                TabBuilder.create().text("UI Mosaic").content(
                     ScrollPaneBuilder.create().content(
-                        new SamplePage()
+                        mosaic = (Node)FXMLLoader.load(Modena.class.getResource("ui-mosaic.fxml"))
                     ).build()
                 ).build(),
-                TabBuilder.create().text("UI Mosaic").content(
+                TabBuilder.create().text("Alignment Test").content(
+                    ScrollPaneBuilder.create().content(
+                        heightTest = (Node)FXMLLoader.load(Modena.class.getResource("SameHeightTest.fxml"))
+                    ).build()
+                ).build(),
+                TabBuilder.create().text("Simple Windows").content(
                     ScrollPaneBuilder.create().content(
-                        (Node)FXMLLoader.load(Modena.class.getResource("ui-mosaic.fxml"))
+                        simpleWindows = new SimpleWindowPage()
+                    ).build()
+                ).build(),
+                TabBuilder.create().text("Combinations").content(
+                    ScrollPaneBuilder.create().content(
+                        combinationsTest = (Node)FXMLLoader.load(Modena.class.getResource("CombinationTest.fxml"))
+                    ).build()
+                ).build(),
+                // Customer example from bug report http://javafx-jira.kenai.com/browse/DTL-5561
+                TabBuilder.create().text("Customer Example").content(
+                    ScrollPaneBuilder.create().content(
+                        customerTest = (Node)FXMLLoader.load(Modena.class.getResource("ScottSelvia.fxml"))
                     ).build()
                 ).build()
             );
             contentTabs.getSelectionModel().select(selectedTab);
+            samplePage.setMouseTransparent(test);
+            // height test set selection for 
+            Platform.runLater(new Runnable() {
+                @Override public void run() {
+                    for (Node n: heightTest.lookupAll(".choice-box")) {
+                        ((ChoiceBox)n).getSelectionModel().selectFirst();
+                    }
+                    for (Node n: heightTest.lookupAll(".combo-box")) {
+                        ((ComboBox)n).getSelectionModel().selectFirst();
+                    }
+                }
+            });
             // Create Toolbar
-            final ToggleButton modenaButton;;
-            final ToggleButton retinaButton = ToggleButtonBuilder.create()
-                .text("Retina @2x")
+            retinaButton = ToggleButtonBuilder.create()
+                .text("@2x")
                 .selected(retina)
                 .onAction(new EventHandler<ActionEvent>(){
                     @Override public void handle(ActionEvent event) {
                         ToggleButton btn = (ToggleButton)event.getSource();
-                        if (btn.isSelected()) {
-                            contentTabs.getTransforms().setAll(new Scale(2,2));
-                        } else {
-                            contentTabs.getTransforms().setAll(new Scale(1,1));
-                        }
-                        contentTabs.requestLayout();
+                        setRetinaMode(btn.isSelected());
                     }
                 })
                 .build();
             ToggleGroup themesToggleGroup = new ToggleGroup();
-            ToggleGroup colorToggleGroup = new ToggleGroup();
             ToolBar toolBar = new ToolBar(
                 HBoxBuilder.create()
                     .children(
                             .text("Modena")
                             .toggleGroup(themesToggleGroup)
                             .selected(modena)
-                            .onAction(new EventHandler<ActionEvent>(){
-                                @Override public void handle(ActionEvent event) { 
-                                    rebuildUI(true,retinaButton.isSelected(), contentTabs.getSelectionModel().getSelectedIndex());
-                                }
-                            })
+                            .onAction(rebuild)
                             .styleClass("left-pill")
                             .build(),
                         ToggleButtonBuilder.create()
                             .text("Caspian")
                             .toggleGroup(themesToggleGroup)
                             .selected(!modena)
-                            .onAction(new EventHandler<ActionEvent>(){
-                                @Override public void handle(ActionEvent event) { 
-                                    rebuildUI(false,retinaButton.isSelected(), contentTabs.getSelectionModel().getSelectedIndex());
-                                }
-                            })
+                            .onAction(rebuild)
                             .styleClass("right-pill")
                             .build()
                     )
                     .build(),
+                ButtonBuilder.create()
+                    .graphic(new ImageView(new Image(Modena.class.getResource("reload_12x14.png").toString())))
+                    .onAction(rebuild)
+                    .build(),
+                rtlButton = ToggleButtonBuilder.create()
+                    .text("RTL")
+                    .onAction(new EventHandler<ActionEvent>() {
+                            @Override public void handle(ActionEvent event) {
+                                root.setNodeOrientation(rtlButton.isSelected() ? 
+                                        NodeOrientation.RIGHT_TO_LEFT : NodeOrientation.LEFT_TO_RIGHT);
+                            }
+                        })
+                    .build(),
+                embeddedPerformanceButton = ToggleButtonBuilder.create()
+                    .text("EP")
+                    .selected(embeddedPerformanceMode)
+                    .tooltip(new Tooltip("Apply Embedded Performance extra stylesheet"))
+                    .onAction(new EventHandler<ActionEvent>() {
+                        @Override public void handle(ActionEvent event) {
+                            embeddedPerformanceMode = embeddedPerformanceButton.isSelected();
+                            rebuild.handle(event);
+                        }
+                    })
+                    .build(),
                 new Separator(),
                 retinaButton,
+                new Label("Base:"),
+                createBaseColorPicker(),
+                new Label("Background:"),
+                createBackgroundColorPicker(),
+                new Label("Accent:"),
+                createAccentColorPicker(),
                 new Separator(),
-                new Label("Base Color:"),
-                HBoxBuilder.create()
-                    .spacing(3)
-                    .children(
-                        createColorButton(null, colorToggleGroup, modena),
-                        createColorButton("#f3622d", colorToggleGroup, modena),
-                        createColorButton("#fba71b", colorToggleGroup, modena),
-                        createColorButton("#57b757", colorToggleGroup, modena),
-                        createColorButton("#41a9c9", colorToggleGroup, modena),
-                        createColorButton("#888", colorToggleGroup, modena),
-                        createColorButton("red", colorToggleGroup, modena),
-                        createColorButton("orange", colorToggleGroup, modena),
-                        createColorButton("yellow", colorToggleGroup, modena),
-                        createColorButton("green", colorToggleGroup, modena),
-                        createColorButton("cyan", colorToggleGroup, modena),
-                        createColorButton("blue", colorToggleGroup, modena),
-                        createColorButton("purple", colorToggleGroup, modena),
-                        createColorButton("magenta", colorToggleGroup, modena),
-                        createColorButton("black", colorToggleGroup, modena)
-                    )
-                    .build()
+                ButtonBuilder.create().text("Save...").onAction(saveBtnHandler).build(),
+                ButtonBuilder.create().text("Restart").onAction(new EventHandler<ActionEvent>() {
+                    @Override public void handle(ActionEvent event) {
+                        restart();
+                    }
+                }).build()
             );
+            toolBar.setId("TestAppToolbar");
             // Create content group used for scaleing @2x
             final Pane contentGroup = new Pane() {
                 @Override protected void layoutChildren() {
             // populate root
             root.setTop(toolBar);
             root.setCenter(contentGroup);
-            // move foucus out of the way
+            
+            samplePage.getStyleClass().add("needs-background");
+            mosaic.getStyleClass().add("needs-background");
+            heightTest.getStyleClass().add("needs-background");
+            combinationsTest.getStyleClass().add("needs-background");
+            customerTest.getStyleClass().add("needs-background");
+            simpleWindows.setModena(modena);
+            // apply retina scale
+            if (retina) {
+                contentTabs.getTransforms().setAll(new Scale(2,2));
+            }
+            // update state
             Platform.runLater(new Runnable() {
                 @Override public void run() {
+                    // move focus out of the way
                     modenaButton.requestFocus();
+                    samplePageNavigation.setCurrentSection(scrolledSection);
                 }
             });
-            // apply retina scale
-            if (retina) {
-                contentTabs.getTransforms().setAll(new Scale(2,2));
-            }
         } catch (IOException ex) {
             Logger.getLogger(Modena.class.getName()).log(Level.SEVERE, null, ex);
         }
     }
+
+    public RadioMenuItem buildFontRadioMenuItem(String name, final String in_fontName, final int in_fontSize, ToggleGroup tg) {
+        return RadioMenuItemBuilder.create().text(name).onAction(new EventHandler<ActionEvent>(){
+                   @Override public void handle(ActionEvent event) {
+                       setFont(in_fontName, in_fontSize);
+                   }
+               }).style("-fx-font: " + in_fontSize + "px \"" + in_fontName + "\";").toggleGroup(tg).build();
+    }
+    
+    public void setFont(String in_fontName, int in_fontSize) {
+        System.out.println("===================================================================");
+        System.out.println("==   SETTING FONT TO "+in_fontName+" "+in_fontSize+"px");
+        System.out.println("===================================================================");
+        fontName = in_fontName;
+        fontSize = in_fontSize;
+        updateUserAgentStyleSheet();
+    }
+    
+    private ColorPicker createBaseColorPicker() {
+        ColorPicker colorPicker = new ColorPicker(Color.TRANSPARENT);
+        colorPicker.getCustomColors().addAll(
+                Color.TRANSPARENT,
+                Color.web("#f3622d"),
+                Color.web("#fba71b"),
+                Color.web("#57b757"),
+                Color.web("#41a9c9"),
+                Color.web("#888"),
+                Color.RED,
+                Color.ORANGE,
+                Color.YELLOW,
+                Color.GREEN,
+                Color.CYAN,
+                Color.BLUE,
+                Color.PURPLE,
+                Color.MAGENTA,
+                Color.BLACK
+        );
+        colorPicker.valueProperty().addListener(new ChangeListener<Color>() {
+            @Override public void changed(ObservableValue<? extends Color> observable, Color oldValue, Color c) {
+                setBaseColor(c);
+            }
+        });
+        return colorPicker;
+    }
     
-    private ToggleButton createColorButton(final String color, ToggleGroup toggleGroup, boolean modena) {
-        final boolean isBase = color == null;
-        String colorCSS;
-        if (!isBase) {
-            colorCSS = "-fx-base: "+color+";";
+    public void setBaseColor(Color c) {
+        if (c == null) {
+            baseColor = null;
         } else {
-            colorCSS = "-fx-base: "+(modena ? "#ececec" : "#d0d0d0")+";";
-        }
-        return ToggleButtonBuilder.create()
-            .text(isBase?"default":null)
-            .style(colorCSS)
-            .toggleGroup(toggleGroup)
-            .selected(isBase)
-            .onAction(new EventHandler<ActionEvent>(){
-                @Override public void handle(ActionEvent event) { 
-                    if (isBase) {
-                        root.setStyle(null);
-                    } else {
-                        root.setStyle("-fx-base: "+color+";");
-                    }
+            baseColor = c;
+        }
+        updateUserAgentStyleSheet();
+    }
+    
+    private ColorPicker createBackgroundColorPicker() {
+        ColorPicker colorPicker = new ColorPicker(Color.TRANSPARENT);
+        colorPicker.getCustomColors().addAll(
+                Color.TRANSPARENT,
+                Color.web("#f3622d"),
+                Color.web("#fba71b"),
+                Color.web("#57b757"),
+                Color.web("#41a9c9"),
+                Color.web("#888"),
+                Color.RED,
+                Color.ORANGE,
+                Color.YELLOW,
+                Color.GREEN,
+                Color.CYAN,
+                Color.BLUE,
+                Color.PURPLE,
+                Color.MAGENTA,
+                Color.BLACK
+        );
+        colorPicker.valueProperty().addListener(new ChangeListener<Color>() {
+            @Override public void changed(ObservableValue<? extends Color> observable, Color oldValue, Color c) {
+                if (c == null) {
+                    backgroundColor = null;
+                } else {
+                    backgroundColor = c;
                 }
-            })
-            .styleClass("color-well")
-            .build();
+                updateUserAgentStyleSheet();
+            }
+        });
+        return colorPicker;
     }
     
+    private ColorPicker createAccentColorPicker() {
+        ColorPicker colorPicker = new ColorPicker(Color.web("#0096C9"));
+        colorPicker.getCustomColors().addAll(
+                Color.TRANSPARENT,
+                Color.web("#0096C9"),
+                Color.web("#4fb6d6"),
+                Color.web("#f3622d"),
+                Color.web("#fba71b"),
+                Color.web("#57b757"),
+                Color.web("#41a9c9"),
+                Color.web("#888"),
+                Color.RED,
+                Color.ORANGE,
+                Color.YELLOW,
+                Color.GREEN,
+                Color.CYAN,
+                Color.BLUE,
+                Color.PURPLE,
+                Color.MAGENTA,
+                Color.BLACK
+        );
+        colorPicker.valueProperty().addListener(new ChangeListener<Color>() {
+            @Override public void changed(ObservableValue<? extends Color> observable, Color oldValue, Color c) {
+                setAccentColor(c);
+            }
+        });
+        return colorPicker;
+    }
+
+    public void setAccentColor(Color c) {
+        if (c == null) {
+            accentColor = null;
+        } else {
+            accentColor = c;
+        }
+        updateUserAgentStyleSheet();
+    }
+    
+    private EventHandler<ActionEvent> saveBtnHandler = new EventHandler<ActionEvent>() {
+        @Override public void handle(ActionEvent event) {
+            FileChooser fc = new FileChooser();
+            fc.getExtensionFilters().add(new FileChooser.ExtensionFilter("PNG", "*.png"));
+            File file = fc.showSaveDialog(mainStage);
+            if (file != null) {
+                try {
+                    samplePage.getStyleClass().add("root");
+                    int width = (int)(samplePage.getLayoutBounds().getWidth()+0.5d);
+                    int height = (int)(samplePage.getLayoutBounds().getHeight()+0.5d);
+                    BufferedImage imgBuffer = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
+                    Graphics2D g2 = imgBuffer.createGraphics();
+                    for (int y=0; y<height; y+=2048) {
+                        SnapshotParameters snapshotParameters = new SnapshotParameters();
+                        int remainingHeight = Math.min(2048, height - y);
+                        snapshotParameters.setViewport(new Rectangle2D(0,y,width,remainingHeight));
+                        WritableImage img = samplePage.snapshot(snapshotParameters, null);
+                        g2.drawImage(SwingFXUtils.fromFXImage(img,null),0,y,null);
+                    }
+                    g2.dispose();
+                    ImageIO.write(imgBuffer, "PNG", file);
+                    System.out.println("Written image: "+file.getAbsolutePath());
+                } catch (IOException ex) {
+                    Logger.getLogger(Modena.class.getName()).log(Level.SEVERE, null, ex);
+                }
+            }
+        }
+    };
+    
     public static void main(String[] args) {
         launch(args);
     }
+    
+    /** Utility method to load a URL into a string */
+    private static String loadUrl(String url) {
+        StringBuilder sb = new StringBuilder();
+        try {
+            BufferedReader br = new BufferedReader(new InputStreamReader(new URL(url).openStream()));
+            String line;
+            while ((line = br.readLine()) != null) {
+                sb.append(line);
+                sb.append('\n');
+            }
+        } catch (IOException ex) {
+            Logger.getLogger(Modena.class.getName()).log(Level.SEVERE, null, ex);
+        }
+        return sb.toString();
+    }
+    
+    // =========================================================================
+    // URL Handler to create magic "internal:stylesheet.css" url for our css string buffer
+    {
+        URL.setURLStreamHandlerFactory(new StringURLStreamHandlerFactory());
+    }
+
+    private String colorToRGBA(Color color) {
+        // Older version didn't care about opacity
+//        return String.format((Locale) null, "#%02x%02x%02x", 
+//                Math.round(color.getRed() * 255), 
+//                Math.round(color.getGreen() * 255), 
+//                Math.round(color.getBlue() * 255));
+        return String.format((Locale) null, "rgba(%d, %d, %d, %f)", 
+            (int) Math.round(color.getRed() * 255), 
+            (int) Math.round(color.getGreen() * 255), 
+            (int) Math.round(color.getBlue() * 255),
+            color.getOpacity());
+    }
+
+    /**
+     * Simple URLConnection that always returns the content of the cssBuffer
+     */
+    private class StringURLConnection extends URLConnection {
+        public StringURLConnection(URL url){
+            super(url);
+        }
+        
+        @Override public void connect() throws IOException {}
+
+        @Override public InputStream getInputStream() throws IOException {
+            return new ByteArrayInputStream(styleSheetContent.getBytes("UTF-8"));
+        }
+    }
+    
+    private class StringURLStreamHandlerFactory implements URLStreamHandlerFactory {
+        URLStreamHandler streamHandler = new URLStreamHandler(){
+            @Override protected URLConnection openConnection(URL url) throws IOException {
+                if (url.toString().toLowerCase().endsWith(".css")) {
+                    return new StringURLConnection(url);
+                } else {
+                    return new URL(styleSheetBase+url.getFile()).openConnection();
+                }
+            }
+        };
+        @Override public URLStreamHandler createURLStreamHandler(String protocol) {
+            if ("internal".equals(protocol)) {
+                return streamHandler;
+            }
+            return null;
+        }
+    }
 }

samples/Modena/src/main/java/modena/SameHeightTestController.java

+/*
+ * Copyright (c) 2008, 2012 Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package modena;
+
+import java.net.URL;
+import java.util.ResourceBundle;
+import javafx.application.Platform;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.fxml.FXML;
+import javafx.fxml.Initializable;
+import javafx.geometry.Insets;
+import javafx.scene.Node;
+import javafx.scene.control.Button;
+import javafx.scene.control.ComboBox;
+import javafx.scene.control.TextField;
+import javafx.scene.layout.AnchorPane;
+import javafx.scene.layout.Region;
+import javafx.scene.layout.StackPane;
+import javafx.scene.text.Text;
+
+/**
+ * Controller to auto align guidelines
+ */
+public class SameHeightTestController implements Initializable{
+    
+    private @FXML Button horizFirstButton;
+    private @FXML TextField vertFirstTextField;
+    private @FXML Region horizBaseLine;
+    private @FXML Region vertBaseLine;
+    private @FXML Region arrowButtonLeftLine;
+    private @FXML Region arrowButtonRightLine;
+    private @FXML Region arrowLeftLine;
+    private @FXML Region arrowRightLine;
+    private @FXML ComboBox editableCombo;
+    private @FXML AnchorPane arrowButtonContainer;
+    private Node arrowButton;
+    private Node arrow;
+
+    @Override public void initialize(URL url, ResourceBundle rb) {
+        Platform.runLater(new Runnable() {
+            @Override public void run() {
+                Text buttonTextNode = (Text)horizFirstButton.lookup(".text");
+                buttonTextNode.layoutYProperty().addListener(new ChangeListener<Number>() {
+                    @Override public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
+                        StackPane.setMargin(horizBaseLine, new Insets(t1.doubleValue(),0,0,0));
+                    }
+                });
+                Text textFieldTextNode = (Text)vertFirstTextField.lookup(".text");
+                textFieldTextNode.layoutXProperty().addListener(new ChangeListener<Number>() {
+                    @Override public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
+                        StackPane.setMargin(vertBaseLine, new Insets(0,0,0,t1.doubleValue()));
+                    }
+                });
+                arrowButton = editableCombo.lookup(".arrow-button");
+                arrow = editableCombo.lookup(".arrow");
+                ChangeListener updater = new ChangeListener() {
+                    @Override public void changed(ObservableValue ov, Object t, Object t1) {
+                        updateArrowLinePositions();
+                    }
+                };
+                arrow.layoutBoundsProperty().addListener(updater);
+                arrowButton.layoutBoundsProperty().addListener(updater);
+                editableCombo.layoutBoundsProperty().addListener(updater);
+                arrowButtonContainer.layoutBoundsProperty().addListener(updater);
+                updateArrowLinePositions();
+            }
+        });
+    }
+    
+    private void updateArrowLinePositions() {
+        double left = arrowButton.localToScene(0, 0).getX() - arrowButtonContainer.localToScene(0, 0).getX();
+        arrowButtonLeftLine.setLayoutX(left-1);
+        arrowButtonLeftLine.setPrefHeight(arrowButtonContainer.getLayoutBounds().getHeight());
+        arrowButtonRightLine.setLayoutX(left + arrowButton.getLayoutBounds().getWidth());
+        arrowButtonRightLine.setPrefHeight(arrowButtonContainer.getLayoutBounds().getHeight());
+        double arrowLeft = arrow.localToScene(0, 0).getX() - arrowButtonContainer.localToScene(0, 0).getX();
+        arrowLeftLine.setLayoutX(arrowLeft-1);
+        arrowLeftLine.setPrefHeight(arrowButtonContainer.getLayoutBounds().getHeight());
+        arrowRightLine.setLayoutX(arrowLeft + arrow.getLayoutBounds().getWidth());
+        arrowRightLine.setPrefHeight(arrowButtonContainer.getLayoutBounds().getHeight());
+    }
+}

samples/Modena/src/main/java/modena/SamplePage.java

  */
 package modena;
 
-import javafx.application.Platform;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javafx.collections.ObservableList;
+import javafx.geometry.HPos;
 import javafx.geometry.Insets;
 import javafx.geometry.Orientation;
 import javafx.geometry.Pos;
+import javafx.geometry.Side;
+import javafx.geometry.VPos;
 import javafx.scene.Node;
 import javafx.scene.control.Button;
 import javafx.scene.control.ButtonBuilder;
 import javafx.scene.control.CheckBox;
+import javafx.scene.control.CheckBoxBuilder;
 import javafx.scene.control.ChoiceBoxBuilder;
+import javafx.scene.control.ColorPicker;
+import javafx.scene.control.ColorPickerBuilder;
 import javafx.scene.control.ComboBoxBuilder;
 import javafx.scene.control.Hyperlink;
 import javafx.scene.control.Label;
+import javafx.scene.control.LabelBuilder;
+import javafx.scene.control.ListViewBuilder;
+import javafx.scene.control.MenuButtonBuilder;
 import javafx.scene.control.PasswordFieldBuilder;
-import javafx.scene.control.ProgressBar;
+import javafx.scene.control.ProgressBarBuilder;
 import javafx.scene.control.ProgressIndicator;
 import javafx.scene.control.ProgressIndicatorBuilder;
 import javafx.scene.control.RadioButton;
 import javafx.scene.control.ScrollBar;
 import javafx.scene.control.ScrollBarBuilder;
+import javafx.scene.control.ScrollPane;
 import javafx.scene.control.ScrollPaneBuilder;
 import javafx.scene.control.SeparatorBuilder;
 import javafx.scene.control.Slider;
 import javafx.scene.control.SliderBuilder;
-import javafx.scene.control.Tab;
-import javafx.scene.control.TabPaneBuilder;
+import javafx.scene.control.SplitMenuButtonBuilder;
+import javafx.scene.control.TableViewBuilder;
 import javafx.scene.control.TextAreaBuilder;
 import javafx.scene.control.TextField;
 import javafx.scene.control.TextFieldBuilder;
 import javafx.scene.control.ToggleButton;
 import javafx.scene.control.ToggleButtonBuilder;
 import javafx.scene.control.ToggleGroup;
+import javafx.scene.control.Tooltip;
+import javafx.scene.control.TooltipBuilder;
+import javafx.scene.control.TreeTableViewBuilder;
+import javafx.scene.control.TreeViewBuilder;
 import javafx.scene.layout.GridPane;
 import javafx.scene.layout.HBox;
 import javafx.scene.layout.HBoxBuilder;
+import javafx.scene.layout.Priority;
 import javafx.scene.layout.VBox;
+import javafx.scene.layout.VBoxBuilder;
+import javafx.scene.paint.Color;
+import javafx.scene.web.HTMLEditorBuilder;
+
+import static modena.SamplePageChartHelper.*;
 import static modena.SamplePageHelpers.*;
+import static modena.SamplePageTableHelper.*;
+import static modena.SamplePageTreeHelper.*;
+import static modena.SamplePageTreeTableHelper.*;
 
 /**
- * Page showing every control in every state
+ * Page showing every control in every state.
  */
 public class SamplePage extends GridPane {
     private int rowIndex = 0;
-    
-    private Node withState(Node node, String state) {
-        node.getProperties().put("javafx.scene.Node.pseudoClassOverride", state);
-        return node;
-    }
-    
-    private Node withState(final Node node, final String state, final String subNodeStyleClass, final String subNodeState) {
-        if (state!=null) node.getProperties().put("javafx.scene.Node.pseudoClassOverride", state);
-        Platform.runLater(new Runnable() {
-            @Override public void run() {
-                node.lookup(subNodeStyleClass).getProperties().put("javafx.scene.Node.pseudoClassOverride", subNodeState);
-            }
-        });
-        return node;
-    }
-    
-    private void newSection(String name, Node ...children) {
-        Label sectionLabel = new Label(name);
-        sectionLabel.getStyleClass().add("section-label");
-        HBox box = new HBox(10);
-        box.getStyleClass().add("section-border");
-        box.getChildren().addAll(children);
-        setConstraints(sectionLabel, 0, rowIndex);
-        setConstraints(box, 1, rowIndex++);
-        getChildren().addAll(sectionLabel,box);
-    }
-    
-    private void newDetailedSection(String[] labels, Node ...children) {
-        Label sectionLabel = new Label(labels[0]);
-        sectionLabel.getStyleClass().add("section-label");
-        HBox hbox = new HBox(10);
-        for (int n = 0; n < children.length; n++ ) {
-            VBox vbox = new VBox(10);
-            vbox.getStyleClass().add("section-border");
-            vbox.setAlignment(Pos.CENTER);
-            Label stateLabel = new Label(labels[n+1]);
-            stateLabel.getStyleClass().add("section-label");
-            vbox.getChildren().add(stateLabel);
-            vbox.getChildren().add(children[n]);
-            hbox.getChildren().addAll(vbox);
-        }
-        setConstraints(sectionLabel, 0, rowIndex);
-        setConstraints(hbox, 1, rowIndex++);
-        getChildren().addAll(sectionLabel,hbox);
-    }
-    
+    private Map<String, Node> content = new HashMap<>();
+    private List<Section> sections = new ArrayList<>();
+
     public SamplePage() {
         setVgap(25);
-        setHgap(25);
-        setPadding(new Insets(20));
-        newSection("Button:", 
+        setHgap(15);
+        setPadding(new Insets(15));
+        newSection("Label:",
+                new Label("Label"),
+                withState(new Label("Disabled"), "disabled"));
+        newSection("Button:",
                 new Button("Button"),
                 withState(new Button("Hover"), "hover"),
                 withState(new Button("Armed"), "armed"),
                 withState(new Button("Focused & Hover"), "focused, hover"),
                 withState(new Button("Focused & Armed"), "focused, armed"),
                 withState(new Button("Disabled"), "disabled"));
-        newSection("Default Button:", 
-                withState(new Button("Button"), "default, hover"),
+        newSection("Default Button:",
+                ButtonBuilder.create().text("Button").defaultButton(true).build(),
                 withState(new Button("Hover"), "default, hover"),
                 withState(new Button("Armed"), "default, armed"),
                 withState(new Button("Focused"), "default, focused"),
                 withState(new Button("Focused & Hover"), "default, focused, hover"),
                 withState(new Button("Focused & Armed"), "default, focused, armed"),
                 withState(new Button("Disabled"), "default, disabled"));
-        newSection("Nice Colors:", 
+        newSection("Nice Colors:",
                 ButtonBuilder.create().text("Button").style("-fx-base: #f3622d;").build(),
                 ButtonBuilder.create().text("Button").style("-fx-base: #fba71b;").build(),
                 ButtonBuilder.create().text("Button").style("-fx-base: #57b757;").build(),
-                ButtonBuilder.create().text("Button").style("-fx-base: #57b757;").build(),
                 ButtonBuilder.create().text("Button").style("-fx-base: #41a9c9;").build(),
                 ButtonBuilder.create().text("Button").style("-fx-base: #888;").build());
+        newSection("Greys:",0,
+                createGreyButton(0),
+                createGreyButton(0.1),
+                createGreyButton(0.2),
+                createGreyButton(0.3),
+                createGreyButton(0.4),
+                createGreyButton(0.5),
+                createGreyButton(0.6),
+                createGreyButton(0.7),
+                createGreyButton(0.8),
+                createGreyButton(0.9),
+                createGreyButton(1));
         ToggleGroup tg1 = new ToggleGroup();
         ToggleGroup tg2 = new ToggleGroup();
         ToggleGroup tg3 = new ToggleGroup();
         ToggleGroup tg4 = new ToggleGroup();
-        newSection("Pill Buttons:", 
+        newSection("Pill Toggle\nButtons:",
                 HBoxBuilder.create()
                     .children(
                         ToggleButtonBuilder.create().text("Left").styleClass("left-pill").toggleGroup(tg1).build(),
                         ToggleButtonBuilder.create().text("Right").styleClass("right-pill").toggleGroup(tg4).selected(true).build()
                     )
                     .build());
-        newSection("ToggleButton:", 
+        ToggleGroup tg5 = new ToggleGroup();
+        ToggleGroup tg6 = new ToggleGroup();
+        ToggleGroup tg7 = new ToggleGroup();
+        ToggleGroup tg8 = new ToggleGroup();
+        newSection("Pill Toggle\nButtons\nFocused:",
+                HBoxBuilder.create()
+                    .children(
+                        ToggleButtonBuilder.create().text("#").styleClass("left-pill").toggleGroup(tg5).build(),
+                        ToggleButtonBuilder.create().text("#").styleClass("center-pill").toggleGroup(tg5).build(),
+                        ToggleButtonBuilder.create().text("#").styleClass("right-pill").toggleGroup(tg5).build()
+                    )
+                    .build(),
+                HBoxBuilder.create()
+                    .children(
+                        withState(ToggleButtonBuilder.create().text("L").styleClass("left-pill").toggleGroup(tg5).build(),"focused"),
+                        ToggleButtonBuilder.create().text("C").styleClass("center-pill").toggleGroup(tg5).build(),
+                        ToggleButtonBuilder.create().text("R").styleClass("right-pill").toggleGroup(tg5).build()
+                    )
+                    .build(),
+                HBoxBuilder.create()
+                    .children(
+                        ToggleButtonBuilder.create().text("L").styleClass("left-pill").toggleGroup(tg5).build(),
+                        withState(ToggleButtonBuilder.create().text("C").styleClass("center-pill").toggleGroup(tg5).build(),"focused"),
+                        ToggleButtonBuilder.create().text("R").styleClass("right-pill").toggleGroup(tg5).build()
+                    )
+                    .build(),
+                HBoxBuilder.create()
+                    .children(
+                        ToggleButtonBuilder.create().text("L").styleClass("left-pill").toggleGroup(tg5).build(),
+                        ToggleButtonBuilder.create().text("C").styleClass("center-pill").toggleGroup(tg5).build(),
+                        withState(ToggleButtonBuilder.create().text("R").styleClass("right-pill").toggleGroup(tg5).build(),"focused")
+                    )
+                    .build(),
+                HBoxBuilder.create()
+                    .children(
+                        withState(ToggleButtonBuilder.create().text("L").styleClass("left-pill").toggleGroup(tg6).selected(true).build(),"focused"),
+                        ToggleButtonBuilder.create().text("C").styleClass("center-pill").toggleGroup(tg6).build(),
+                        ToggleButtonBuilder.create().text("R").styleClass("right-pill").toggleGroup(tg6).build()
+                    )
+                    .build(),
+                HBoxBuilder.create()
+                    .children(
+                        ToggleButtonBuilder.create().text("L").styleClass("left-pill").toggleGroup(tg7).build(),
+                        withState(ToggleButtonBuilder.create().text("C").styleClass("center-pill").toggleGroup(tg7).selected(true).build(),"focused"),
+                        ToggleButtonBuilder.create().text("R").styleClass("right-pill").toggleGroup(tg7).build()
+                    )
+                    .build(),
+                HBoxBuilder.create()
+                    .children(
+                        ToggleButtonBuilder.create().text("L").styleClass("left-pill").toggleGroup(tg8).build(),
+                        ToggleButtonBuilder.create().text("C").styleClass("center-pill").toggleGroup(tg8).build(),
+                        withState(ToggleButtonBuilder.create().text("R").styleClass("right-pill").toggleGroup(tg8).selected(true).build(),"focused")
+                    )
+                    .build());
+        newSection("ToggleButton:",
                 new ToggleButton("Button"),
                 withState(new ToggleButton("Hover"), "hover"),
                 withState(new ToggleButton("Armed"), "armed"),
                 withState(new ToggleButton("Focused & Hover"), "focused, hover"),
                 withState(new ToggleButton("Focused & Armed"), "focused, armed"),
                 withState(new ToggleButton("Disabled"), "disabled"));
-        newSection("ToggleButton Selected:", 
+        newSection("ToggleButton Selected:",
                 withState(new ToggleButton("Button"), "selected"),
                 withState(new ToggleButton("Hover"), "selected, hover"),
                 withState(new ToggleButton("Armed"), "selected, armed"),
                 withState(new ToggleButton("Focused & Hover"), "selected, focused, hover"),
                 withState(new ToggleButton("Focused & Armed"), "selected, focused, armed"),
                 withState(new ToggleButton("Disabled"), "selected, disabled"));
-        newSection("CheckBox:", 
+        newSection("CheckBox:",
                 new CheckBox("CheckBox"),
                 withState(new CheckBox("Hover"), "hover"),
                 withState(new CheckBox("Armed"), "armed"),
                 withState(new CheckBox("Focused & Hover"), "focused, hover"),
                 withState(new CheckBox("Focused & Armed"), "focused, armed"),
                 withState(new CheckBox("Disabled"), "disabled"));
-        newSection("CheckBox Selected:", 
+        newSection("CheckBox Selected:",
                 withState(new CheckBox("CheckBox"), "selected"),
                 withState(new CheckBox("Hover"), "selected, hover"),
                 withState(new CheckBox("Armed"), "selected, armed"),
                 withState(new CheckBox("Focused & Hover"), "selected, focused, hover"),
                 withState(new CheckBox("Focused & Armed"), "selected, focused, armed"),
                 withState(new CheckBox("Disabled"), "selected, disabled"));
-        newSection("CheckBox Indeterminate:", 
-                withState(new CheckBox("CheckBox"), "indeterminate, selected"),
+        newSection("CheckBox\nIndeterminate:",
+                CheckBoxBuilder.create().text("CheckBox").selected(true).indeterminate(true).allowIndeterminate(true).build(),
                 withState(new CheckBox("Hover"), "indeterminate, selected, hover"),
                 withState(new CheckBox("Armed"), "indeterminate, selected, armed"),
                 withState(new CheckBox("Focused"), "indeterminate, selected, focused"),
                 withState(new CheckBox("Focused & Hover"), "indeterminate, selected, focused, hover"),
                 withState(new CheckBox("Focused & Armed"), "indeterminate, selected, focused, armed"),
                 withState(new CheckBox("Disabled"), "indeterminate, selected, disabled"));
-        newSection("RadioButton:", 
+        newSection("RadioButton:",
                 new RadioButton("RadioButton"),
                 withState(new RadioButton("Hover"), "hover"),
                 withState(new RadioButton("Armed"), "armed"),
                 withState(new RadioButton("Focused & Hover"), "focused, hover"),
                 withState(new RadioButton("Focused & Armed"), "focused, armed"),
                 withState(new RadioButton("Disabled"), "disabled"));
-        newSection("RadioButton Selected:", 
+        newSection("RadioButton\nSelected:",
                 withState(new RadioButton("RadioButton"), "selected"),
                 withState(new RadioButton("Hover"), "selected, hover"),
                 withState(new RadioButton("Armed"), "selected, armed"),
                 withState(new RadioButton("Focused & Hover"), "selected, focused, hover"),
                 withState(new RadioButton("Focused & Armed"), "selected, focused, armed"),
                 withState(new RadioButton("Disabled"), "selected, disabled"));
-        newSection("HyperLink:", 
+        newSection("HyperLink:",
                 new Hyperlink("Hyperlink"),
                 withState(new Hyperlink("Visited"), "visited"),
                 withState(new Hyperlink("Hover"), "hover"),
                 withState(new Hyperlink("F & Hover"), "focused, hover"),
                 withState(new Hyperlink("F & Armed"), "focused, armed"),
                 withState(new Hyperlink("Disabled"), "disabled"));
+        ObservableList<String> choiceBoxLongList = sampleItems(200);
+        choiceBoxLongList.add(100, "Long List");
+        newSection(
+                "ChoiceBox:",
+                ChoiceBoxBuilder.create(String.class).items(sampleItems()).value("Item A").build(),
+                ChoiceBoxBuilder.create(String.class).items(choiceBoxLongList).value("Long List").build(),
+                withState(ChoiceBoxBuilder.create(String.class).items(sampleItems()).value("Item B").build(), "hover"),
+                withState(ChoiceBoxBuilder.create(String.class).items(sampleItems()).value("Item B").build(), "showing"),
+                withState(ChoiceBoxBuilder.create(String.class).items(sampleItems()).value("Item B").build(), "focused"),
+                ChoiceBoxBuilder.create(String.class).items(sampleItems()).value("Item C").disable(true).build()
+        );
+        newSection(
+                "ComboBox:",
+                ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item A").build(),
+                ComboBoxBuilder.create(String.class).items(choiceBoxLongList).value("Long List").build(),
+                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item B").build(), "hover"),
+                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item B").build(), "showing"),
+                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item B").build(), "focused"),
+                ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item C").disable(true).build()
+                );
+        newSection(
+                "ComboBox\nEditable:",
+                ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item A").editable(true).build(),
+                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item B").editable(true).build(), "editable", ".arrow-button", "hover"),
+                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item B").editable(true).build(), "editable", ".arrow-button", "pressed")
+                );
+        newSection(
+                "ComboBox\nEditable\n(More):",
+                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item B").editable(true).build(), "editable,contains-focus", ".text-field", "focused"),
+                ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item C").editable(true).disable(true).build()
+                );
+        newSection(
+                "Color Picker:",
+                ColorPickerBuilder.create().value(Color.RED).build(),
+                withState(ColorPickerBuilder.create().value(Color.RED).build(), "hover"),
+                withState(ColorPickerBuilder.create().value(Color.RED).build(), "showing"),
+                withState(ColorPickerBuilder.create().value(Color.RED).build(), "focused"),
+                withState(ColorPickerBuilder.create().value(Color.RED).build(), "disabled")
+                );
+        newSection(
+                "Color Picker\n Split Button:",
+                ColorPickerBuilder.create().value(Color.RED).styleClass(ColorPicker.STYLE_CLASS_SPLIT_BUTTON).build(),
+                withState(ColorPickerBuilder.create().value(Color.RED).styleClass(ColorPicker.STYLE_CLASS_SPLIT_BUTTON).build(), "hover"),
+                withState(ColorPickerBuilder.create().value(Color.RED).styleClass(ColorPicker.STYLE_CLASS_SPLIT_BUTTON).build(), "showing"),
+                withState(ColorPickerBuilder.create().value(Color.RED).styleClass(ColorPicker.STYLE_CLASS_SPLIT_BUTTON).build(), "focused"),
+                withState(ColorPickerBuilder.create().value(Color.RED).styleClass(ColorPicker.STYLE_CLASS_SPLIT_BUTTON).build(), "disabled")
+                );
+        newSection(
+                "MenuButton:",
+                MenuButtonBuilder.create().items(createMenuItems(20)).text("right").popupSide(Side.RIGHT).build(),
+                MenuButtonBuilder.create().items(createMenuItems(20)).text("normal").build(),
+                withState(MenuButtonBuilder.create().items(createMenuItems(20)).text("hover").build(), "openvertically,hover"),
+                withState(MenuButtonBuilder.create().items(createMenuItems(20)).text("armed").build(), "openvertically,armed"),
+                withState(MenuButtonBuilder.create().items(createMenuItems(20)).text("focused").build(), "openvertically,focused"),
+                withState(MenuButtonBuilder.create().items(createMenuItems(20)).text("disabled").build(), "openvertically,disabled")
+                );
+        newSection(
+                "SplitMenuButton:",
+                SplitMenuButtonBuilder.create().items(createMenuItems(20)).text("right").popupSide(Side.RIGHT).build(),
+                SplitMenuButtonBuilder.create().items(createMenuItems(20)).text("normal").build(),
+                withState(SplitMenuButtonBuilder.create().items(createMenuItems(20)).text("hover").build(),"openvertically",".label", "hover"),
+                withState(SplitMenuButtonBuilder.create().items(createMenuItems(20)).text("armed").build(),"armed,openvertically",".label", "armed")
+                );
+        newSection(
+                "SplitMenuButton\nMore:",
+                withState(SplitMenuButtonBuilder.create().items(createMenuItems(20)).text("arrow hover").build(),"openvertically",".arrow-button", "hover"),
+                withState(SplitMenuButtonBuilder.create().items(createMenuItems(20)).text("showing").build(), "openvertically,showing"),
+                withState(SplitMenuButtonBuilder.create().items(createMenuItems(20)).text("focused").build(), "openvertically,focused"),
+                withState(SplitMenuButtonBuilder.create().items(createMenuItems(20)).text("disabled").build(), "openvertically,disabled")
+                );
         newDetailedSection(
-                new String[]{"Slider - H: ", "normal", "hover", "pressed", "disabled", "tickmarks"},
+                new String[]{"Slider (H):", "normal", "hover", "pressed", "disabled", "tickmarks"},
                 withState(SliderBuilder.create().maxWidth(90).min(0).max(100).value(50).build(), null),
                 withState(SliderBuilder.create().maxWidth(90).min(0).max(100).value(50).build(), null, ".thumb", "hover"),
                 withState(SliderBuilder.create().maxWidth(90).min(0).max(100).value(50).build(), null, ".thumb", "hover, pressed"),
                 withState(SliderBuilder.create().maxWidth(90).min(0).max(100).value(50).build(), "disabled"),
                 SliderBuilder.create().min(0).max(100).value(50).showTickMarks(true).showTickLabels(true).build());
         newDetailedSection(
-                new String[]{"Slider - H - Focused: ", "normal", "hover", "pressed"},
+                new String[]{"Slider (H) Focused:", "normal", "hover", "pressed"},
                 withState(new Slider(0, 100, 50), "focused"),
                 withState(new Slider(0, 100, 50), "focused", ".thumb", "hover"),
                 withState(new Slider(0, 100, 50), "focused", ".thumb", "hover, pressed"));
                 withState(SliderBuilder.create().min(0).max(100).value(50).orientation(Orientation.VERTICAL).build(), "disabled"),
                 SliderBuilder.create().min(0).max(100).value(50).showTickMarks(true).showTickLabels(true).orientation(Orientation.VERTICAL).build());
         newDetailedSection(
-                new String[] {"Scrollbar - H: ", "normal", "small", "big thumb"}, 
+                new String[] {"Scrollbar - H: ", "normal", "focused", "small", "big thumb"},
                 new ScrollBar(),
+                withState(ScrollBarBuilder.create().build(), "focused"),
                 ScrollBarBuilder.create().minWidth(30).prefWidth(30).build(),
                 ScrollBarBuilder.create().visibleAmount(60).max(100).build()
                 );
         newDetailedSection(
-                new String[] {"Scrollbar - V: ", "normal", "small", "btn hover", "btn pressed", ".thumb hover", ".thumb pressed"}, 
+                new String[] {"Scrollbar - V: ", "normal", "focused", "small", "btn hover", "btn pressed", ".thumb hover", ".thumb pressed"},
                 withState(ScrollBarBuilder.create().orientation(Orientation.VERTICAL).build(), "vertical"),
+                withState(ScrollBarBuilder.create().orientation(Orientation.VERTICAL).build(), "focused"),
                 withState(ScrollBarBuilder.create().orientation(Orientation.VERTICAL).minHeight(30).prefHeight(30).build(), "vertical"),
                 withState(ScrollBarBuilder.create().orientation(Orientation.VERTICAL).build(), "vertical", ".decrement-button", "hover"),
                 withState(ScrollBarBuilder.create().orientation(Orientation.VERTICAL).build(), "vertical", ".decrement-button", "pressed"),
                 withState(ScrollBarBuilder.create().orientation(Orientation.VERTICAL).build(), "vertical", ".thumb", "pressed")
                 );
         newDetailedSection(
-                new String[] {"ScrollPane: ", "normal", "small", "focused"}, 
+                new String[] {"ScrollPane: ", "normal", "small", "focused", "empty"},
                 ScrollPaneBuilder.create().content(scrollPaneContent()).build(),
                 ScrollPaneBuilder.create().content(scrollPaneContent()).minWidth(40).prefWidth(40).minHeight(40).prefHeight(40).build(),
-                withState(ScrollPaneBuilder.create().content(scrollPaneContent()).build(), "focused")
-                ); 
+                withState(ScrollPaneBuilder.create().content(scrollPaneContent()).build(), "focused"),
+                ScrollPaneBuilder.create().build()
+                );
         newDetailedSection(
-                new String[] {"Separator: ", "horizontal", "vertical"}, 
+                new String[] {"ScrollPane H/V: ", "H Bar", "V bar"},
+                ScrollPaneBuilder.create().content(scrollPaneContent()).vbarPolicy(ScrollPane.ScrollBarPolicy.NEVER).build(),
+                ScrollPaneBuilder.create().content(scrollPaneContent()).hbarPolicy(ScrollPane.ScrollBarPolicy.NEVER).build()
+                );
+        newDetailedSection(
+                new String[] {"Separator: ", "horizontal", "vertical"},
                 SeparatorBuilder.create().prefWidth(100).build(),
                 SeparatorBuilder.create().orientation(Orientation.VERTICAL).prefHeight(50).build()
                 );
         newDetailedSection(
-                new String[] {"ProgressBar: ", "normal", "disabled", "indeterminate"}, 
-                new ProgressBar(0.6),
-                withState(new ProgressBar(), "disabled"),
-                new ProgressBar(-1)
+                new String[] {"ProgressBar: ", "normal", "disabled", "indeterminate"},
+                ProgressBarBuilder.create().progress(0.6).prefWidth(200).build(),
+                withState(ProgressBarBuilder.create().progress(0.2).prefWidth(200).build(), "disabled"),
+                ProgressBarBuilder.create().progress(-1).prefWidth(200).build()
                 );
         newDetailedSection(
-                new String[] {"ProgressIndicator: ", "normal 0%", "normal 60%", "normal 100%", "disabled"}, 
+                new String[] {"ProgressIndicator: ", "normal 0%", "normal 60%", "normal 100%", "disabled"},
                 new ProgressIndicator(0),
                 new ProgressIndicator(0.6),
                 new ProgressIndicator(1),
                 withState(new ProgressIndicator(0.5), "disabled")
                 );
         newDetailedSection(
-                new String[] {"ProgressIndicator\nIndeterminate: ", "normal", "small", "large", "disabled"}, 
+                new String[] {"ProgressIndicator\nIndeterminate: ", "normal", "small", "large", "disabled"},
                 ProgressIndicatorBuilder.create().progress(-1).maxWidth(USE_PREF_SIZE).maxHeight(USE_PREF_SIZE).build(),
                 ProgressIndicatorBuilder.create().progress(-1).prefWidth(30).prefHeight(30).build(),
                 ProgressIndicatorBuilder.create().progress(-1).prefWidth(60).prefHeight(60).build(),
                 ProgressIndicatorBuilder.create().progress(-1).maxWidth(USE_PREF_SIZE).maxHeight(USE_PREF_SIZE).disable(true).build()
                 );
-        newSection(      
-                "TextField:", 
+        newSection(
+                "TextField:",
                 new TextField("TextField"),
                 TextFieldBuilder.create().promptText("Prompt Text").build(),
                 withState(new TextField("Focused"), "focused"),
                 withState(new TextField("Disabled"), "disabled")
-                );
-        newSection(      
-                "PasswordField:", 
+        );
+        newSection(
+                "PasswordField:",
                 PasswordFieldBuilder.create().text("Password").build(),
                 PasswordFieldBuilder.create().promptText("Prompt Text").build(),
                 withState(PasswordFieldBuilder.create().text("Password").build(), "focused"),
                 withState(PasswordFieldBuilder.create().text("Password").build(), "disabled")
-                );
-        newSection(      
-                "TextArea:", 
+        );
+        newSection(
+                "TextArea:",
                 TextAreaBuilder.create().text("TextArea").prefColumnCount(10).prefRowCount(2).build(),
-                TextAreaBuilder.create().text("Many Lines of\nText.\n#3\n#4\n#5\n#6\n#7\n#8\n#9\n#10").prefColumnCount(10).prefRowCount(3).build(),
-                TextAreaBuilder.create().text("Many Lines of\nText.\n#3\n#4\n#5\n#6\n#7\n#8\n#9\n#10").prefColumnCount(6).prefRowCount(3).build(),
+                TextAreaBuilder.create().text("Many Lines of\nText.\n#3\n#4\n#5\n#6\n#7\n#8\n#9\n#10").prefColumnCount(10).prefRowCount(5).build(),
+                TextAreaBuilder.create().text("Many Lines of\nText.\n#3\n#4\n#5\n#6\n#7\n#8\n#9\n#10").prefColumnCount(6).prefRowCount(5).build(),
                 TextAreaBuilder.create().promptText("Prompt Text").prefColumnCount(10).prefRowCount(2).build(),
                 withState(TextAreaBuilder.create().text("Focused").prefColumnCount(7).prefRowCount(2).build(), "focused"),
                 withState(TextAreaBuilder.create().text("Disabled").prefColumnCount(8).prefRowCount(2).build(), "disabled")
+        );
+        newSection(
+                "HTMLEditor:",
+                HTMLEditorBuilder.create().htmlText("Hello <b>Bold</b> Text").prefWidth(650).prefHeight(120).build()
                 );
-        newSection(      
-                "ChoiceBox:", 
-                ChoiceBoxBuilder.create(String.class).items(sampleItems()).value("Item A").build(),
-                withState(ChoiceBoxBuilder.create(String.class).items(sampleItems()).value("Item B").build(), "hover"),
-                withState(ChoiceBoxBuilder.create(String.class).items(sampleItems()).value("Item B").build(), "showing"),
-                withState(ChoiceBoxBuilder.create(String.class).items(sampleItems()).value("Item B").build(), "focused"),
-                withState(ChoiceBoxBuilder.create(String.class).items(sampleItems()).value("Item C").build(), "disabled")
+        newSection(
+                "HTMLEditor\nFocused:",
+                withState(HTMLEditorBuilder.create().htmlText("<i>Focused</i>").prefWidth(650).prefHeight(120).build(), "focused")
                 );
-        newSection(      
-                "ComboBox:", 
-                ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item A").build(),
-                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item B").build(), "hover"),
-                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item B").build(), "showing"),
-                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item B").build(), "focused"),
-                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item C").build(), "disabled")
+        newDetailedSection(
+                new String[] { "ToolBar (H|TOP):", "normal", "overflow", "disabled" },
+                createToolBar(Side.TOP, false, false),
+                createToolBar(Side.TOP, true, false),
+                createToolBar(Side.TOP, false, true)
+        );
+        newDetailedSection(
+                new String[] { "ToolBar (H|BOTTOM):", "normal", "overflow", "disabled" },
+                createToolBar(Side.BOTTOM, false, false),
+                createToolBar(Side.BOTTOM, true, false),
+                createToolBar(Side.BOTTOM, false, true)
+        );
+        newDetailedSection(
+                new String[] { "ToolBar (V|LEFT):", "normal", "overflow", "disabled" },
+                createToolBar(Side.LEFT, false, false),
+                createToolBar(Side.LEFT, true, false),
+                createToolBar(Side.LEFT, false, true)
+        );
+        newDetailedSection(
+                new String[] {"ToolBar (V|RIGHT):", "normal", "overflow", "disabled"},
+                createToolBar(Side.RIGHT,false,false),
+                createToolBar(Side.RIGHT,true,false),
+                createToolBar(Side.RIGHT,false,true)
                 );
-        newSection(      
-                "ComboBox\nEditable:", 
-                ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item A").editable(true).build(),
-                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item B").editable(true).build(), "hover"),
-                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item B").editable(true).build(), "showing"),
-                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item B").editable(true).build(), "focused"),
-                withState(ComboBoxBuilder.create(String.class).items(sampleItems()).value("Item C").editable(true).build(), "disabled")
+        newSection(
+                "Tabs\n(Top):",
+                wrapBdr(createTabPane(4, 250, 100, null, false, false, Side.TOP)),
+                wrapBdr(withState(createTabPane(5, 200, 100, "Tab Disabled &\nMany Tabs", false, true, Side.TOP), null, ".tab", "disabled")),
+                wrapBdr(withState(createTabPane(5, 200, 100, "Disabled", false, false, Side.TOP), "disabled"))
+        );
+        newSection(
+                "Tabs Floating\n(Top):",
+                createTabPane(4, 250, 100, null, true, false, Side.TOP),
+                withState(createTabPane(5, 200, 100, "Tab Disabled &\nMany Tabs", true, true, Side.TOP), null, ".tab", "disabled"),
+                withState(createTabPane(5, 200, 100, "Disabled", true, false, Side.TOP), "disabled")
                 );
-        newDetailedSection(
-                new String[] {"ToolBar (H):", "normal", "overflow", "disabled"}, 
-                createToolBar(false,false),
-                createToolBar(false,true),
-                withState(createToolBar(false,false), "disabled")
+        newSection(
+                "Tabs\n(Bottom):",
+                wrapBdr(createTabPane(4, 250, 100, null, false, false, Side.BOTTOM)),
+                wrapBdr(withState(createTabPane(5, 200, 100, "Tab Disabled &\nMany Tabs", false, true, Side.BOTTOM), null, ".tab", "disabled")),
+                wrapBdr(withState(createTabPane(5, 200, 100, "Disabled", false, false, Side.BOTTOM), "disabled"))
                 );
-        newDetailedSection(
-                new String[] {"ToolBar (V):", "normal", "overflow", "disabled"}, 
-                createToolBar(true,false),
-                createToolBar(true,true),
-                withState(createToolBar(true,false), "disabled")
+        newSection(
+                "Tabs Floating\n(Bottom):",
+                createTabPane(4, 250, 100, null, true, false, Side.BOTTOM),
+                withState(createTabPane(5, 200, 100, "Tab Disabled &\nMany Tabs", true, true, Side.BOTTOM), null, ".tab", "disabled"),
+                withState(createTabPane(5, 200, 100, "Disabled", true, false, Side.BOTTOM), "disabled")
                 );
-        newSection(      
-                "Tabs Floating:", 
-                createTabPane(3, 250,null,true),
-                withState(createTabPane(5, 200,"Tab Disabled &\nMany Tabs", true), null, ".tab", "disabled"),
-                withState(createTabPane(5, 200,"Disabled", true), "disabled")
+        newSection(
+                "Tabs\n(Left):",
+                wrapBdr(createTabPane(4, 250, 250, null, false, false, Side.LEFT)),
+                wrapBdr(withState(createTabPane(5, 200, 250, "Tab Disabled &\nMany Tabs", false, true, Side.LEFT), null, ".tab", "disabled")),
+                wrapBdr(withState(createTabPane(5, 200, 250, "Disabled", false, false, Side.LEFT), "disabled"))
+                );
+        newSection(
+                "Tabs Floating\n(Left):",
+                createTabPane(4, 250, 250, null, true, false, Side.LEFT),
+                withState(createTabPane(5, 200, 250, "Tab Disabled &\nMany Tabs", true, true, Side.LEFT), null, ".tab", "disabled"),
+                withState(createTabPane(5, 200, 250, "Disabled", true, false, Side.LEFT), "disabled")
+                );
+        newSection(
+                "Tabs\n(Right):",
+                wrapBdr(createTabPane(4, 250, 250, null, false, false, Side.RIGHT)),
+                wrapBdr(withState(createTabPane(5, 200, 250, "Tab Disabled &\nMany Tabs", false, true, Side.RIGHT), null, ".tab", "disabled")),
+                wrapBdr(withState(createTabPane(5, 200, 250, "Disabled", false, false, Side.RIGHT), "disabled"))
+                );
+        newSection(
+                "Tabs Floating\n(Right):",
+                createTabPane(4, 250, 250, null, true, false, Side.RIGHT),
+                withState(createTabPane(5, 200, 250, "Tab Disabled &\nMany Tabs", true, true, Side.RIGHT), null, ".tab", "disabled"),
+                withState(createTabPane(5, 200, 250, "Disabled", true, false, Side.RIGHT), "disabled")
                 );
         newDetailedSection(
-                new String[] {"TitledPane:", "normal", "focused", "disabled"}, 
+                new String[] { "TitledPane:", "normal", "not collapsible", "hover", "focused", "disabled" },
                 TitledPaneBuilder.create().text("Title").content(new Label("Content\nLine2.")).build(),
+                TitledPaneBuilder.create().text("Not Collapsible").content(new Label("Content\nLine2.")).collapsible(false).build(),
+                withState(TitledPaneBuilder.create().text("Title").content(new Label("Content\nLine2.")).build(), "hover"),
                 withState(TitledPaneBuilder.create().text("Title").content(new Label("Content\nLine2.")).build(), "focused"),
                 withState(TitledPaneBuilder.create().text("Title").content(new Label("Content\nLine2.")).build(), "disabled")
-                );
+        );
         newDetailedSection(
-                new String[] {"Accordian:", "normal", "hover", "focused", "disabled"}, 
+                new String[] {"Accordion:", "normal", "hover", "focused", "disabled"},
                 createAccordion(),
                 withState(createAccordion(), null, ".titled-pane", "hover"),
                 withState(createAccordion(), null, ".titled-pane", "focused"),
                 withState(createAccordion(), "disabled")
                 );
+        newDetailedSection(
+                new String[] {"SplitPane (H):", "simple", "many", "complex"},
+                createSplitPane(2, false, null),
+                createSplitPane(4, false, null),
+                createSplitPane(2, false, createSplitPane(2, true, null))
+                );
+        newDetailedSection(
+                new String[] {"SplitPane (V):", "simple", "many", "complex"},
+                createSplitPane(2,true,null),
+                createSplitPane(4,true,null),
+                createSplitPane(2,true,createSplitPane(2,false,null))
+                );
+        newDetailedSection(
+                new String[] {"Pagination:", "simple", "infinate"},
+                createPagination(5, false, true),
+                createPagination(Integer.MAX_VALUE, false, true)
+                );
+        newDetailedSection(
+                new String[] {"Pagination\nBullet Style:", "simple", "infinate"},
+                createPagination(5, true, true),
+                createPagination(Integer.MAX_VALUE, true, true)
+                );
+        newSection(
+                "Pagination\nNo Arrows:",
+                createPagination(Integer.MAX_VALUE, false, false)
+        );
+        newDetailedSection(
+                new String[] { "ListView\n2 items\nsingle selection:", "normal", "focused", "disabled" },
+                createListView(3, false, false, false),
+                withState(createListView(3, false, false, false), "focused"),
+                createListView(3, false, true, false)
+        );
+        newDetailedSection(
+                new String[] {"ListView\n10,000 items\nmultiple selection:","normal", "focused", "disabled"},
+                createListView(10000, true, false, false),
+                withState(createListView(10000, true, false, false), "focused"),
+                createListView(10000, true, true, false)
+                );
+        newDetailedSection(
+                new String[] {"ListView (H)\n10,000 items\nmultiple selection:","normal", "focused", "disabled"},
+                createListView(10000, true, false, true),
+                withState(createListView(10000, true, false, true), "focused"),
+                createListView(10000, true, true, true)
+                );
+        newSection(
+                "TableView Simple:\n(Row Selection)",
+                createTableViewSimple(550, true, false),
+                withState(createTableViewSimple(150, true, false), "focused")
+        );
+        newSection(
+                "TableView Simple:\n(Constrained Resize)",
+                createTableViewSimple(550, true, true),
+                withState(createTableViewSimple(150, true, true), "focused")
+        );
+        newSection(
+                "TableView:\n(Row Selection)",
+                createTableView(550, true),
+                withState(createTableView(150, true), "focused")
+        );
+        newSection(
+                "TableView:\n(Cell Selection)",
+                createTableView(550, false),
+                withState(createTableView(150, false), "focused")
+                );
+        newSection(
+                "TreeView:",
+                createTreeView(350),
+                withState(createTreeView(350), "focused")
+                );
+        newSection(
+                "TreeTableView:\n" +
+                        "(Row Selection)",
+                createTreeTableView(550, false),
+                withState(createTreeTableView(200, false), "focused")
+                );
+        newSection(
+                "TreeTableView:\n(Cell Selection)",
+                createTreeTableView(550, true),
+                withState(createTreeTableView(200, true), "focused")
+                );
+        newDetailedSection(
+                new String[] {"Empty:", "ListView", "TableView", "TreeView", "TreeTableView"},
+                ListViewBuilder.create(String.class).prefWidth(150).prefHeight(100).build(),
+                TableViewBuilder.create(Object.class).prefWidth(150).prefHeight(100).build(),
+                TreeViewBuilder.create(Object.class).prefWidth(150).prefHeight(100).build(),
+                TreeTableViewBuilder.create(Object.class).prefWidth(150).prefHeight(100).build()
+                );
+        newDetailedSection(
+                new String[] {"ToolTip:","inline","inline + graphic", "popup"},
+                LabelBuilder.create().text("This is a simple Tooltip.").styleClass("tooltip").build(),
+                LabelBuilder.create().text("This is a simple Tooltip\nwith graphic.").graphic(createGraphic()).styleClass("tooltip").build(),
+                VBoxBuilder.create().fillWidth(true).spacing(4).children(
+                    ButtonBuilder.create().text("Hover over me").tooltip(new Tooltip("This is a simple Tooltip.")).build(),
+                    ButtonBuilder.create().text("me too").tooltip(new Tooltip("This is a simple Tooltip\nwith more than one line.")).build(),
+                    ButtonBuilder.create().text("or me").tooltip(TooltipBuilder.create().text("This is a simple Tooltip\nwith graphic.").graphic(createGraphic()).build()).build()
+                ).build()
+                );
+        newSection(
+                "MenuBar & ContextMenu:",
+                createMenuBar(),
+                createContextMenu()
+                );
+        newSection(
+                "Menus:",
+                createInlineMenu(false),
+                createInlineMenu(true)
+                );
+        newSection(
+                "AreaChart:",
+                createAreaChart(false)
+                );
+        newSection(
+                "StackedAreaChart:",
+                createAreaChart(true)
+                );
+        newSection(
+                "BarChart\nSimple:",
+                createBarChart(false,true)
+                );
+        newSection(
+                "BarChart:",
+                createBarChart(false, false)
+                );
+        newSection(
+                "BarChart\n(H, Simple):",
+                createBarChart(true, true)
+                );
+        newSection(
+                "BarChart\n(H):",
+                createBarChart(true, false)
+                );
+        newSection(
+                "StackedBarChart\nSimple:",
+                createStackedBarChart(false,true)
+                );
+        newSection(
+                "StackedBarChart\n(H, Simple):",
+                createStackedBarChart(true, true)
+        );
+        newSection(
+                "BubbleChart:",
+                createBubbleChart(false)
+        );
+        newSection(
+                "BubbleChart\nTop & Right Axis:",
+                createBubbleChart(true)
+        );
+        newSection(
+                "LineChart:",
+                createLineChart()
+        );
+        newSection(
+                "PieChar:",
+                createPieChart()
+        );
+        newSection(
+                "ScatterChart:",
+                createScatterChart()
+        );
+    }
+
+    public List<Section> getSections() {
+        return sections;
+    }
+
+    private void newSection(String name, Node ...children) {
+        newSection(name, 10, children);
+    }
+
+    private void newSection(String name, int spacing, Node ...children) {
+        Label sectionLabel = new Label(name);
+        sectionLabel.getStyleClass().add("section-label");
+        sectionLabel.setMaxSize(Double.MAX_VALUE,Double.MAX_VALUE);
+        HBox box = new HBox(spacing);
+        box.getStyleClass().add("section-border");
+        box.getChildren().addAll(children);
+        setConstraints(sectionLabel, 0, rowIndex, 1, 1, HPos.CENTER, VPos.CENTER, Priority.ALWAYS, Priority.ALWAYS);
+        setConstraints(box, 1, rowIndex++);
+        getChildren().addAll(sectionLabel, box);
+        sections.add(new Section(name, sectionLabel, box));
+        content.put(name, box);
+    }
+
+    private void newDetailedSection(String[] labels, Node ...children) {
+        Label sectionLabel = new Label(labels[0]);
+        sectionLabel.getStyleClass().add("section-label");
+        sectionLabel.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
+        HBox hbox = new HBox(10);
+        for (int n = 0; n < children.length; n++ ) {
+            VBox vbox = new VBox(10);
+            vbox.getStyleClass().add("section-border");
+            vbox.setAlignment(Pos.CENTER);
+            Label stateLabel = new Label(labels[n+1]);
+            stateLabel.getStyleClass().add("section-label");
+            vbox.getChildren().add(stateLabel);
+            vbox.getChildren().add(children[n]);
+            hbox.getChildren().addAll(vbox);
+        }
+        setConstraints(sectionLabel, 0, rowIndex,1,1, HPos.CENTER, VPos.CENTER, Priority.ALWAYS,Priority.ALWAYS);
+        setConstraints(hbox, 1, rowIndex++);
+        getChildren().addAll(sectionLabel, hbox);
+        sections.add(new Section(labels[0], sectionLabel, hbox));
+        content.put(labels[0], hbox);
+    }
+
+    public Map<String, Node> getContent() {
+        return content;
+    }
+
+    public static class Section {
+        public final String name;
+        public final Label label;
+        public final Node box;
+
+        public Section(String name, Label label, Node box) {
+            this.name = name;
+            this.label = label;
+            this.box = box;
+        }
+
+        @Override public String toString() {
+            return name.replaceAll("\n"," ");
+        }
     }
 }

samples/Modena/src/main/java/modena/SamplePageChartHelper.java

+/*
+ * Copyright (c) 2008, 2012 Oracle and/or its affiliates.
+ * All rights reserved. Use is subject to license terms.
+ *
+ * This file is available and licensed under the following license:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  - Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  - Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the distribution.
+ *  - Neither the name of Oracle Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package modena;
+
+import java.util.Random;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.geometry.Side;
+import javafx.scene.Node;
+import javafx.scene.chart.AreaChart;
+import javafx.scene.chart.BarChart;
+import javafx.scene.chart.BubbleChart;
+import javafx.scene.chart.CategoryAxis;
+import javafx.scene.chart.LineChart;
+import javafx.scene.chart.NumberAxis;
+import javafx.scene.chart.PieChart;
+import javafx.scene.chart.ScatterChart;
+import javafx.scene.chart.StackedAreaChart;
+import javafx.scene.chart.StackedBarChart;
+import javafx.scene.chart.XYChart;
+
+/**
+ * Helper class for creating charts for testing
+ */
+public class SamplePageChartHelper {
+    
+    static Node createAreaChart(Boolean stacked) {
+        NumberAxis xAxis = new NumberAxis("X Values", 1.0d, 9.0d, 2.0d);
+        xAxis.setTickLength(12.0f);
+        NumberAxis yAxis = new NumberAxis();
+        yAxis.setLabel("Y Values");
+        ObservableList<AreaChart.Series> areaChartData = FXCollections.observableArrayList(
+                new AreaChart.Series("Series 1",FXCollections.observableArrayList(
+                    new AreaChart.Data(0,4),
+                    new AreaChart.Data(2,5),
+                    new AreaChart.Data(4,4),
+                    new AreaChart.Data(6,2),
+                    new AreaChart.Data(8,6),
+                    new AreaChart.Data(10,8)
+                )),
+                new AreaChart.Series("Series 2", FXCollections.observableArrayList(
+                    new AreaChart.Data(0,8),
+                    new AreaChart.Data(2,2),
+                    new AreaChart.Data(4,9),
+                    new AreaChart.Data(6,7),
+                    new AreaChart.Data(8,5),
+                    new AreaChart.Data(10,7)
+                )),
+                new AreaChart.Series("Series 3", FXCollections.observableArrayList(
+                    new AreaChart.Data(0,2),
+                    new AreaChart.Data(2,5),
+                    new AreaChart.Data(4,8),
+                    new AreaChart.Data(6,6),
+                    new AreaChart.Data(8,9),
+                    new AreaChart.Data(10,7)
+                ))
+        );
+        Node areaChart;
+        if (stacked) {
+            areaChart = new StackedAreaChart(xAxis, yAxis, areaChartData);
+        } else {
+            areaChart = new AreaChart(xAxis, yAxis, areaChartData);
+        }
+        return areaChart;
+    }
+    
+    static Node createStackedBarChart(boolean horizontal, boolean simple) {
+        return createBarChart(horizontal, simple, true);
+    }
+    
+    static Node createBarChart(boolean horizontal, boolean simple) {
+        return createBarChart(horizontal, simple, false);
+    }
+    
+    static Node createBarChart(boolean horizontal, boolean simple, boolean stacked) {
+        final Random RANDOM = new Random(29782198273l);
+        String[] years = {"2001","2002","2003"};
+        String[] series;
+        if (simple) {
+            series = new String[]{"A","B","C"};
+        } else {
+            series = new String[]{"A","B","C","D","E","F","G","H"};
+        }
+        CategoryAxis xAxis = new CategoryAxis(FXCollections.<String>observableArrayList(years));
+        NumberAxis yAxis = new NumberAxis();
+        yAxis.setLabel("Units Sold");
+        ObservableList<BarChart.Series> barChartData = FXCollections.observableArrayList();
+        final double negative = stacked ? 0 : -500;
+        for (int s=0; s<series.length; s++) {
+            ObservableList<BarChart.Data> sd = FXCollections.observableArrayList();
+            for(int y=0; y<years.length; y++) {
+                if (horizontal) {
+                    sd.add(new BarChart.Data(negative+(2000*RANDOM.nextDouble()), years[y]));
+                } else {
+                    sd.add(new BarChart.Data(years[y], negative+(2000*RANDOM.nextDouble())));
+                }
+            }
+            barChartData.add(new BarChart.Series(series[s],sd));
+        }
+        Node barChart;
+        if (stacked) {
+            if (horizontal) {
+                barChart = new StackedBarChart(yAxis, xAxis, barChartData);
+            } else {
+                barChart = new StackedBarChart(xAxis, yAxis, barChartData);
+            }
+        } else {
+            if (horizontal) {
+                barChart = new BarChart(yAxis, xAxis, barChartData);
+            } else {
+                barChart = new BarChart(xAxis, yAxis, barChartData);
+            }
+        }
+        return barChart;
+    }
+    
+    static Node createBubbleChart(boolean useRightTopAxis) {