Archive

Posts Tagged ‘Java FX 2’

Java FX 2 Ribbon Menu

April 8, 2012 10 comments

Get the NetBeans Project:

RibbonBarDemo.zip

Please take a look at a new site I am working on. It focuses on Java FX 2 application development. Thanks!

I created my own version of a Ribbon Menu. I hope you find it useful.

Personally, I believe the coloring may be too light on the ribbon menu itself. I decided to leave it alone and just post it on WordPress as is. It should be easy for you to manipulate the colors in the CSS style sheet. Also the icons do not seem to render very well. The icons I have selected are too large so they are scaled down. That could be the problem.

Please be mindful that I am no expert programmer – so take this for what it is…some buttons and such on the screen. Here we go!

My Design Approach:
I decided to separate out the code into distinct parts. There is the RibbonBar class which is to be dropped into the main application. Next are the Tab classes which include the Home Tab and Commerce Tab.  Then there are the individual regions on the tabs such as Actions, Clipboard, Font, etc.

Visual Issues:
When running the program you will notice some visual issues. I didnt spend a lot of time making it very professional. I believe I did enough to serve the purpose of learning what I wanted. For example, you will notice I didnt style the SplitMenuButton or ChoiceBoxes. However, I did style some other buttons. My goals were to continue working with layout managers and CSS styles.

Worth Noting:
None of the buttons do anything except print to console. However I would like to share a few notes.

1. SplitMenuButton.
I used a SplitMenuButton in the “Clipboard” region on the Home Tab. As pointed out in the JavaDocs, the SplitMenuButton is divided into two sections: a Button and Menu. You will need to program for the Button’s Event Handler as well as the MenuItem Event Handlers.

When a menu item has been selected, the event is not transferred to the buttons event handler. So the Button does not retain the last selected menu event.

In the sample code below, a SplitMenuButton with a “Clipboard” icon and 3 menu items is created. In this example there are 4 events that are assigned to the SplitMenuButton. Three of these are for each menuItem and the last is for the Button itself.

The clipboard image is retrieved from the images folder and stored in an Image object. The image is then added to an ImageView so it can be rendered on the button. You will see I resized the image to 24H x 24W.

The setGraphicTextGap sets the vertical spacing between the text and image. Based on what I am able to determine, if the GraphicTextGap is not specified, the default is 3 pixels between the icon and Button text. In the example photo, I compare the difference between no GraphicTextGap and 20 pixel text gap.

    /**
     * Creating a SplitMenuButton.
     */
    private void buildSplitMenuButton() {

        //Create button and set text.
        this.pasteButton = new SplitMenuButton();
        this.pasteButton.setText("Paste");

        //Set alignment of button to text. This puts btn text below the image icon.
        this.pasteButton.setContentDisplay(ContentDisplay.TOP);

        //Retrieve and set image of clipboard. I will set image size to 24x24,
        //preserve the ratio and enable smoothing in the Image constructor.
        String imgPath = "/ui/common/images/clipboard.png";
        Image clipboard = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);

        //Create an ImageView for showing image.
        ImageView imageView = new ImageView(clipboard);

        //Set the gap b/n graphic and text. Assign the ImageView to the button.
        this.pasteButton.setGraphicTextGap(5.0);
        this.pasteButton.setGraphic(imageView);

        //Paste Menu Item
        MenuItem mnuPaste = new MenuItem("Paste");
        mnuPaste.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Paste clicked.");
            }

        });

        //Paste Special Menu Item
        MenuItem mnuPasteSpecial = new MenuItem("Paste Special...");
        mnuPasteSpecial.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Paste Special clicked.");
            }

        });

        //Paste As Hyperlink Menu Item
        MenuItem mnuPasteHyperlink = new MenuItem("Paste as Hyperlink");
        mnuPasteHyperlink.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Paste as Hyperlink clicked.");
            }

        });

        //Add all MenuItems to the MenuSplitButton's menu options.
        this.pasteButton.getItems().addAll(mnuPaste, mnuPasteSpecial, 
                mnuPasteHyperlink);

        //Set the click event of the Button itself. 
        this.pasteButton.setOnAction(new EventHandler() {
            @Override
            public void handle(Event arg0) {
                System.out.println("Button Clicked.");
            }
        });

    }

2. ToggleButtons
I created two types of ToggleButtons. One type is for the Bold, Italics, and Underline buttons. These are independent ToggleButtons that allow each to be selected or deselected.

The other series of ToggleButtons are grouped together in a ToggleGroup. For example, the Superscript and Subscript buttons should not be mutually independent of each other. If one is selected the other should be removed.

As for grouping them together as if one seamless series of buttons is done in CSS styles. I use a GridPane layout manager to group them together. The CSS stylesheet (tabs.css) applies the rounded border on the ends. It also applies a top and bottom border for middle buttons.

/**
  * Middle Toggle Button
  */
.middleToggleButton {
    -fx-background-insets: 0 0 0 1, 1 0 1 0, 2 0 2 0;
    -fx-background-radius: 0 0 0 0, 0 0 0 0, 0 0 0 0;
}

 /**
  * Left side Toggle Button
  */
.leftToggleButton {
    -fx-background-insets: 0 0 0 1, 1 0 1 1, 2 0 2 2;
    -fx-background-radius: 0 0 0 5, 4 0 0 4, 3 0 0 3;
}

 /**
  * Right side Toggle Button
  */
.rightToggleButton {
    -fx-background-insets: 0 1 0 0, 1 1 1 0, 2 2 2 0 ;
    -fx-background-radius: 0 5 0 0, 0 4 4 0, 0 3 3 0;  
}

3. Ribbon Container Background
To style the ribbon strip background, I created a an HBox. Each component added to an HBox will be positioned side by side so it seems to be the appropriate container. I set the spacing between each node that is added by calling the setSpacing() method. I set spacing to 5px.

container.setSpacing(5);

The gradient can be found in the tabs.css style sheet. There are 5 color stops to create the multiple gradient effects. It looks like this:

#container {
    -fx-padding: 3px;
    -fx-background-color: 
        linear-gradient(#ffffff 0%, #ced3da 4%, #c1c6cf 17%, 
        #b4bbc5 18%, #e5ebeb 100%);
}

4. Ribbon Component Group
I’m not sure what to call the group of related controls. So I will go with a component group. This group is similar to the container background shown above. The primary difference is that I chose to use a VBox as the root node for each component. The CSS styles apply the gradient and rounded corners.

.toolbarContainer {
    -fx-background-color: 
        linear-gradient(#dae0e7 0%, #ced4dd 14%, 
        #c8ced7 15%, #dfe5e6 100%),
        linear-gradient(#bdbfc1 0%, #9a9c9f 14%, 
        #888b90 15%, #838686 100%),
        linear-gradient(#eef1f6 0%, #e1e6ee 14%, 
        #d5dbe7 15%, #eef4f4 79%, 
        #ced4e6 79%, #afb6c8 100%);

    -fx-background-insets: 1 0 1 1, 1, 2;
    -fx-background-radius: 5,4,3;
    -fx-padding: 4 8 0 8;
}

I am excited about this one because I used Jasper’s technique of manipulating the background radius and background insets. Specifically, I added a white shadow effect to the right side of each component. I will explain that one another day. A user would probably never notice but its the details that make a nice presentation. Would you agree? I will explain the CSS styles and how I pieced them together another day.

I hope you like the demonstration! Gregg

Driver.java

package ribbonbardemo;

import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Screen;
import javafx.stage.Stage;
import ui.layouts.ribbonBar.RibbonBar;

/**
 * Driver. The Application starts here.
 */
public class Driver extends Application {

    private Scene scene;
    private BorderPane layout;

    /**
     * start. Build UI and show here.
     * @param stage 
     */
    @Override
    public void start(Stage stage) {

        //Initalize layout
        layout = new BorderPane();
        layout.setId("app");

        //Set BorderPane Regions
        RibbonBar r = new RibbonBar();
        layout.setTop(r.get());

        //Set Scene properties.
        setSceneProperties();

        //Set a few properties of our Application Window
        stage.setScene(scene);
        stage.setTitle("Ribbon Menu Demo");
        stage.show();
    }

    /**
     * Application Entry Point. Program starts here.
     * @param args 
     */
    public static void main(String[] args) {
        launch();
    }

    /**
     * setSceneProperties. This method sets the app to almost full size. It also
     * is where CSS style sheet is attached.
     */
    private void setSceneProperties()
    {
        //The percentage values are used as multipliers for screen width/height.
        double percentageWidth = 0.98;
        double percentageHeight = 0.90;

        //Calculate the width / height of screen.
        Rectangle2D screenSize = Screen.getPrimary().getBounds();
        percentageWidth *= screenSize.getWidth();
        percentageHeight *= screenSize.getHeight();

        //Create a scene object. Pass in the layout and set
        //the dimensions to 98% of screen width & 90% screen height.
        this.scene = new Scene(layout, percentageWidth, percentageHeight);

        //Add CSS Style Sheet (located in same package as this class).
        String css = this.getClass().getResource("App.css").toExternalForm();

        //Add CSS for Tabs.
        String tabsURL = "/ui/layouts/ribbonBar/tabs/tabs.css";
        String tabsCSS = this.getClass().getResource(tabsURL).toExternalForm();

        scene.getStylesheets().addAll(css, tabsCSS);

    }
}

RibbonBar.java

package ribbonbardemo;

import javafx.scene.control.TabPane;
import ui.layouts.ribbonBar.tabs.commerce.CommerceTab;
import ui.layouts.ribbonBar.tabs.home.HomeTab;

/**
 * Ribbon Bar.
 */
public class RibbonBar {

    private TabPane tabPane;

    public RibbonBar() {

        tabPane = new TabPane();

        buildTabs();
    }

    /**
     * get. Return instance of the RibbonBar (TabPane).
     * @return 
     */
    public TabPane get() {
        return this.tabPane;
    }

    private void buildTabs() {

        HomeTab homeTab = new HomeTab();
        CommerceTab insertTab = new CommerceTab();

        tabPane.getTabs().addAll(homeTab.get(), insertTab.get());
    }
}

ColorfulIcons.java

package ui.layouts.ribbonBar.tabs.commerce;

import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;

/**
 * ColorfulIcons. Add some colorful icons for fun.
 */
public class ColorfulIcons {

    private Button btnGiftWrap, btnNotes, btnMagicWand, 
            btnContactDetails;

    private VBox root;

    /**
     * Default Constructor.
     */
    public ColorfulIcons() {
        this.root = new VBox();
        build();
    }

    /**
     * get. Returns the VBox to be placed on the Ribbon Bar.
     * @return 
     */
    public VBox get() {
        return this.root;
    }

    /**
     * build. Helper method to build the layout.
     */
    private void build() {

        //GridPane used to layout the components.
        GridPane layout = new GridPane();

        //Grid Lines to help layout buttons.
        layout.setGridLinesVisible(false);
        layout.setHgap(5);

        //Build UI Controls
        this.buildGiftWrapButton();
        this.buildMagicWandButton();
        this.buildNotesButton();
        this.buildCustomerDetailsButton();

        //Add All Componets to the GridPane.
        layout.add(this.btnGiftWrap, 0, 0);
        layout.add(this.btnMagicWand, 1, 0);
        layout.add(this.btnNotes, 2, 0);
        layout.add(this.btnContactDetails, 3, 0);

        //Build the Toolbar Container Label.
        Label label = new Label("Colorful Icons...");
        label.getStyleClass().add("ribbonLabel");
        label.setTooltip(new Tooltip("Here are a few icons for fun"));

        //TODO: find a better way to center a label.
        VBox vbox = new VBox();
        vbox.getChildren().add(label);
        VBox.setVgrow(label, Priority.ALWAYS);
        vbox.setAlignment(Pos.BOTTOM_CENTER);
        vbox.setStyle("-fx-padding: 5 0 0 0");
        layout.add(vbox, 0, 2, 4, 1);

        //Center alignment in the VBox, add GridPane, set VBox CSS Selector.
        this.root.setAlignment(Pos.CENTER);
        this.root.getChildren().add(layout);
        this.root.getStyleClass().add("toolbarContainer");
    }

    /**
     * buildGiftWrapButton. Helper method to build Gift Wrap Button.
     */
    private void buildGiftWrapButton() {

        String imgPath = "/ui/common/images/giftWrap.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);

        this.btnGiftWrap = new Button("Gift Wrap");
        this.btnGiftWrap.setContentDisplay(ContentDisplay.TOP);
        this.btnGiftWrap.setGraphic(imageView);
        this.btnGiftWrap.getStyleClass().add("ribbonToggleButton");
        this.btnGiftWrap.setTooltip(new Tooltip("Giftwrap, who knew?"));

        this.btnGiftWrap.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Gift Wrap Button clicked.");

            }

        });
    }

    /**
     * buildNotesButton. Helper method to build a Button.
     */
    private void buildNotesButton() {

        String imgPath = "/ui/common/images/notepad.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);

        this.btnNotes = new Button("Notes");
        this.btnNotes.setContentDisplay(ContentDisplay.TOP);
        this.btnNotes.setGraphic(imageView);
        this.btnNotes.getStyleClass().add("ribbonToggleButton");
        this.btnNotes.setTooltip(new Tooltip("Add Note"));

        this.btnNotes.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Notes Button clicked.");

            }

        });
    }

    /**
     * buildCustomerDetailsButton. Helper method to build a Button.
     */
    private void buildCustomerDetailsButton() {

        String imgPath = "/ui/common/images/customerDetails.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);

        this.btnContactDetails = new Button("Customer");
        this.btnContactDetails.setContentDisplay(ContentDisplay.TOP);
        this.btnContactDetails.setGraphic(imageView);
        this.btnContactDetails.getStyleClass().add("ribbonToggleButton");
        this.btnContactDetails.setTooltip(new Tooltip("Customer Details"));

        this.btnContactDetails.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Customer Details Button clicked.");

            }

        });
    }

    /**
     * buildMagicWandButton. Helper method to build a Button.
     */
    private void buildMagicWandButton() {

        String imgPath = "/ui/common/images/magicWand.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);

        this.btnMagicWand = new Button("Magic");
        this.btnMagicWand.setContentDisplay(ContentDisplay.TOP);
        this.btnMagicWand.setGraphic(imageView);
        this.btnMagicWand.getStyleClass().add("ribbonToggleButton");
        this.btnMagicWand.setTooltip(new Tooltip("How about a magic trick?"));

        this.btnMagicWand.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Magic Wand Button clicked.");

            }

        });
    }

}

CommerceTab.java

package ui.layouts.ribbonBar.tabs.commerce;

import javafx.scene.control.Tab;
import javafx.scene.layout.HBox;

/**
 * InsertTab. This class represents the "Commerce Tab".
 */
public class CommerceTab {

    private Tab tab;

    /**
     * Default Constructor.
     */
    public CommerceTab() {
        tab = new Tab("Commerce");
        buildTab();
    }

    /**
     * get. Returns an instance of the Commerce Tab. This will be added to the 
     * TabPane in the RibbonBar class.
     * @return 
     */
    public Tab get() {
        return this.tab;
    }

    /**
     * buildTab. Helper method to build the Commerce Tab UI.
     */
    private void buildTab() {

        //Do not allow tab to close.
        tab.setClosable(false);

        //The container holds all toolbar sections specific to a Tab.
        HBox container = new HBox();

        //Set ID (for CSS styles)
        container.setId("container");

        //Set preferred height.
        container.setPrefHeight(90);

        //Put 10px spacing b/n each toolbar block
        container.setSpacing(5);

        //Add Colorful Icons Ribbon Component.
        ColorfulIcons colorfulIcons = new ColorfulIcons();
        container.getChildren().add(colorfulIcons.get());

        //Add Payment Ribbon Component.
        Payment payment = new Payment();
        container.getChildren().add(payment.get());

        //Add Container.
        tab.setContent(container); 
    }

}

Payment.java

package ui.layouts.ribbonBar.tabs.commerce;

import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;

/**
 * Tables. This class represents the Payment Method Ribbon Bar Component.
 */
public class Payment {

    private ToggleButton btnV, btnMC, btnA, btnD, btnP;
    private VBox root;

    /**
     * Default Constructor.
     */
    public Payment() {
        this.root = new VBox();
        build();
    }

    /**
     * get. Returns the VBox to be placed on the Ribbon Bar.
     * @return 
     */
    public VBox get() {
        return this.root;
    }

    /**
     * build. Helper method to build the layout.
     */
    private void build() {

        //GridPane used to layout the components.
        GridPane layout = new GridPane();

        //Grid Lines to help layout buttons.
        layout.setGridLinesVisible(false);

        //Build UI Controls
        this.buildVisaButton();
        this.buildMasterCardButton();
        this.buildAmericanExpressButton();
        this.buildDiscoverButton();
        this.buildPayPalButton();

        //Group Toggle Buttons together so only one maybe selected.
        ToggleGroup group = new ToggleGroup();
        this.btnA.setToggleGroup(group);
        this.btnD.setToggleGroup(group);
        this.btnMC.setToggleGroup(group);
        this.btnV.setToggleGroup(group);
        this.btnP.setToggleGroup(group);

        //Add All Componets to the GridPane.
        layout.add(this.btnV, 0, 0);
        layout.add(this.btnMC, 1, 0);
        layout.add(this.btnA, 2, 0);
        layout.add(this.btnD, 3, 0);
        layout.add(this.btnP, 4, 0);

        //Build the Toolbar Container Label.
        Label label = new Label("Payment Method");
        label.getStyleClass().add("ribbonLabel");
        label.setTooltip(new Tooltip("How to pay..."));

        //TODO: find a better way to center a label.
        VBox vbox = new VBox();
        vbox.getChildren().add(label);
        VBox.setVgrow(label, Priority.ALWAYS);
        vbox.setAlignment(Pos.BOTTOM_CENTER);
        vbox.setStyle("-fx-padding: 5 0 0 0");
        layout.add(vbox, 0, 2, 5, 1);

        //Center alignment in the VBox, add GridPane, set VBox CSS Selector.
        this.root.setAlignment(Pos.CENTER);
        this.root.getChildren().add(layout);
        this.root.getStyleClass().add("toolbarContainer");
    }

    /**
     * buildVisaButton. Helper method to build a Button.
     */
    private void buildVisaButton() {

        //Create button with text.
        this.btnV = new ToggleButton("Visa");

        //Set the Image above the text.
        this.btnV.setContentDisplay(ContentDisplay.TOP);

        //Add image.
        String imgPath = "/ui/common/images/visa.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);
        this.btnV.setGraphic(imageView);

        //Set CSS Styles. 
        this.btnV.getStyleClass().add("ribbonToggleButton");
        this.btnV.getStyleClass().add("leftToggleButton");

        //Set Tooltip
        this.btnV.setTooltip(new Tooltip("Visa"));

        //Set simple Click Event Handler.
        this.btnV.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Visa Toggle Button clicked.");

            }

        });
    }

    /**
     * buildMasterCardButton. Helper method to build a Button.
     */
    private void buildMasterCardButton() {

        //Create button with text.
        this.btnMC = new ToggleButton("MasterCard");

        //Set the Image above the text.
        this.btnMC.setContentDisplay(ContentDisplay.TOP);

        //Add image.
        String imgPath = "/ui/common/images/mastercard.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);
        this.btnMC.setGraphic(imageView);

        //Set CSS Styles. 
        this.btnMC.getStyleClass().add("ribbonToggleButton");
        this.btnMC.getStyleClass().add("middleToggleButton");

        //Set Tooltip
        this.btnMC.setTooltip(new Tooltip("MasterCard"));

        //Set simple Click Event Handler.
        this.btnMC.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("MasterCard Toggle Button clicked.");

            }

        });
    }

    /**
     * buildAmericanExpressButton. Helper method to build a Button.
     */
    private void buildAmericanExpressButton() {

        //Create button with text.
        this.btnA = new ToggleButton("Amex");

        //Set the Image above the text.
        this.btnA.setContentDisplay(ContentDisplay.TOP);

        //Add image.
        String imgPath = "/ui/common/images/amex.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);
        this.btnA.setGraphic(imageView);

        //Set CSS Styles. 
        this.btnA.getStyleClass().add("ribbonToggleButton");
        this.btnA.getStyleClass().add("middleToggleButton");

        //Set Tooltip
        this.btnA.setTooltip(new Tooltip("American Express"));

        //Set simple Click Event Handler.
        this.btnA.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("American Express Toggle Button clicked.");

            }

        });
    }

    /**
     * buildDiscoverButton. Helper method to build a Button.
     */
    private void buildDiscoverButton() {

        //Create button with text.
        this.btnD = new ToggleButton("Discover");

        //Set the Image above the text.
        this.btnD.setContentDisplay(ContentDisplay.TOP);

        //Add image.
        String imgPath = "/ui/common/images/discover.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);
        this.btnD.setGraphic(imageView);

        //Set CSS Styles. 
        this.btnD.getStyleClass().add("ribbonToggleButton");
        this.btnD.getStyleClass().add("middleToggleButton");

        //Set Tooltip
        this.btnD.setTooltip(new Tooltip("Discover Card"));

        //Set simple Click Event Handler.
        this.btnD.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Discover Card Toggle Button clicked.");

            }

        });
    }

    /**
     * buildPayPalButton. Helper method to build a Button.
     */
    private void buildPayPalButton() {

        //Create button with text.
            this.btnP = new ToggleButton("PayPal");

        //Set the Image above the text.
        this.btnP.setContentDisplay(ContentDisplay.TOP);

        //Add image.
        String imgPath = "/ui/common/images/paypal.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);
        this.btnP.setGraphic(imageView);

        //Set CSS Styles. 
        this.btnP.getStyleClass().add("ribbonToggleButton");
        this.btnP.getStyleClass().add("rightToggleButton");

        //Set Tooltip
        this.btnP.setTooltip(new Tooltip("PayPal"));

        //Set simple Click Event Handler.
        this.btnP.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("PayPal Toggle Button clicked.");

            }

        });
    }

}

Actions.java

package ui.layouts.ribbonBar.tabs.home;

import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;

/**
 * Tables. This class represents the Actions Ribbon Bar Component.
 */
public class Actions {

    private Button btnNew, btnOpen, btnEmail, btnPrint, btnPDF, btnDelete;
    private VBox root;

    /**
     * Default Constructor.
     */
    public Actions() {
        this.root = new VBox();
        build();
    }

    /**
     * get. Returns the VBox to be placed on the Ribbon Bar.
     * @return 
     */
    public VBox get() {
        return this.root;
    }

    /**
     * build. Helper method to build the layout.
     */
    private void build() {

        //GridPane used to layout the components.
        GridPane layout = new GridPane();

        //Grid Lines to help layout buttons.
        layout.setGridLinesVisible(false);

        //Set horizontal spacing.
        layout.setHgap(5);

        //Build UI Controls
        this.buildNewButton();
        this.buildOpenButton();
        this.buildEmailButton();
        this.buildPDFButton();
        this.buildPrintButton();
        this.buildDeleteButton();

        //Add All Componets to the GridPane.
        layout.add(this.btnNew, 0, 0);
        layout.add(this.btnOpen, 1, 0);
        layout.add(this.btnDelete, 2, 0);
        layout.add(this.btnEmail, 3, 0);
        layout.add(this.btnPrint, 4, 0);
        layout.add(this.btnPDF, 5, 0);

        //Build the Toolbar Container Label.
        Label label = new Label("Actions");
        label.getStyleClass().add("ribbonLabel");
        label.setTooltip(new Tooltip("Order related stuff..."));

        //TODO: find a better way to center a label.
        VBox vbox = new VBox();
        vbox.getChildren().add(label);
        VBox.setVgrow(label, Priority.ALWAYS);
        vbox.setAlignment(Pos.BOTTOM_CENTER);
        vbox.setStyle("-fx-padding: 5 0 0 0");
        layout.add(vbox, 0, 2, 6, 1);

        //Center alignment in the VBox, add GridPane, set VBox CSS Selector.
        this.root.setAlignment(Pos.CENTER);
        this.root.getChildren().add(layout);
        this.root.getStyleClass().add("toolbarContainer");
    }

    /**
     * buildNewButton. Helper method to build a Button.
     */
    private void buildNewButton() {

        //Create button with text.
        this.btnNew = new Button("New");

        //Set the Image above the text.
        this.btnNew.setContentDisplay(ContentDisplay.TOP);

        //Add image.
        String imgPath = "/ui/common/images/new.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);
        this.btnNew.setGraphic(imageView);

        //Set CSS Styles. 
        this.btnNew.getStyleClass().add("ribbonToggleButton");

        //Set Tooltip
        this.btnNew.setTooltip(new Tooltip("New Order"));

        //Set simple Click Event Handler.
        this.btnNew.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("New Order Button clicked.");

            }

        });
    }

    /**
     * buildOpenButton. Helper method to build a Button.
     */
    private void buildOpenButton() {

        //Create button with text.
        this.btnOpen = new Button("Open");

        //Set the Image above the text.
        this.btnOpen.setContentDisplay(ContentDisplay.TOP);

        //Add image.
        String imgPath = "/ui/common/images/open.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);
        this.btnOpen.setGraphic(imageView);

        //Set CSS Styles. 
        this.btnOpen.getStyleClass().add("ribbonToggleButton");

        //Set Tooltip
        this.btnOpen.setTooltip(new Tooltip("Open Order"));

        //Set simple Click Event Handler.
        this.btnOpen.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Open Exist Order Button clicked.");

            }

        });
    }

    /**
     * buildEmailButton. Helper method to build a Button.
     */
    private void buildEmailButton() {

        //Create button with text.
        this.btnEmail = new Button("Email");

        //Set the Image above the text.
        this.btnEmail.setContentDisplay(ContentDisplay.TOP);

        //Add image.
        String imgPath = "/ui/common/images/email.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);
        this.btnEmail.setGraphic(imageView);

        //Set CSS Styles. 
        this.btnEmail.getStyleClass().add("ribbonToggleButton");

        //Set Tooltip
        this.btnEmail.setTooltip(new Tooltip("Email Order"));

        //Set simple Click Event Handler.
        this.btnEmail.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Email Order Button clicked.");

            }

        });
    }

    /**
     * buildPrintButton. Helper method to build a Button.
     */
    private void buildPrintButton() {

        //Create button with text.
        this.btnPrint = new Button("Print");

        //Set the Image above the text.
        this.btnPrint.setContentDisplay(ContentDisplay.TOP);

        //Add image.
        String imgPath = "/ui/common/images/print.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);
        this.btnPrint.setGraphic(imageView);

        //Set CSS Styles. 
        this.btnPrint.getStyleClass().add("ribbonToggleButton");

        //Set Tooltip
        this.btnPrint.setTooltip(new Tooltip("Print Order"));

        //Set simple Click Event Handler.
        this.btnPrint.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Print Invoice Button clicked.");

            }

        });
    }

    /**
     * buildDeleteButton. Helper method to build a Button.
     */
    private void buildDeleteButton() {

        //Create button with text.
        this.btnDelete = new Button("Delete");

        //Set the Image above the text.
        this.btnDelete.setContentDisplay(ContentDisplay.TOP);

        //Add image.
        String imgPath = "/ui/common/images/delete.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);
        this.btnDelete.setGraphic(imageView);

        //Set CSS Styles. 
        this.btnDelete.getStyleClass().add("ribbonToggleButton");

        //Set Tooltip
        this.btnDelete.setTooltip(new Tooltip("Delete Order"));

        //Set simple Click Event Handler.
        this.btnDelete.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Delete Order Button clicked.");

            }

        });
    }

    /**
     * buildPDFButton. Helper method to build a Button.
     */
    private void buildPDFButton() {

        //Create button with text.
        this.btnPDF = new Button("Export");

        //Set the Image above the text.
        this.btnPDF.setContentDisplay(ContentDisplay.TOP);

        //Add image.
        String imgPath = "/ui/common/images/pdf.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);
        ImageView imageView = new ImageView(image);
        this.btnPDF.setGraphic(imageView);

        //Set CSS Styles. 
        this.btnPDF.getStyleClass().add("ribbonToggleButton");

        //Set Tooltip
        this.btnPDF.setTooltip(new Tooltip("Export Order to PDF"));

        //Set simple Click Event Handler.
        this.btnPDF.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("PDF Export Button clicked.");

            }

        });
    }

}

Clipboard.java

package ui.layouts.ribbonBar.tabs.home;

import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;

/**
 * Clipboard. This class represents the clipboard section.
 */
public class Clipboard {

    private SplitMenuButton pasteButton;
    private Button cutButton, copyButton;
    private GridPane layout;
    private VBox root;  //Root Node for the Clipboard region.

    /**
     * Default Constructor.
     */
    public Clipboard() {
        this.layout = new GridPane();
        this.root = new VBox();
        this.pasteButton = new SplitMenuButton();
        this.cutButton = new Button();
        this.copyButton = new Button();

        build();
    }

    /**
     * get. Returns the instance of the HBox which contains the layout of the
     * clipboard region.
     * @return 
     */
    public VBox get() {
        return this.root;
    }

    /**
     * build. Helper method to build the Clipboard layout.
     */
    private void build() {
        this.layout.setId("clipboard");
        this.layout.setGridLinesVisible(false);
        this.layout.setVgap(5);
        this.layout.setHgap(5);

        //Build UI Controls
        buildPasteButton();
        buildCutButton();
        buildCopyButton();

        //Add the "Paste" SplitMenuButton, Cut and Copy Buttons.
        this.layout.add(this.pasteButton, 0, 0, 1, 2); //Spans two rows, 1 col.
        this.layout.add(this.cutButton, 1, 0); //Row 0, Col 1.
        this.layout.add(this.copyButton, 1, 1); //Row 1, COl 1.

        Label label = new Label("Clipboard");
        label.getStyleClass().add("ribbonLabel");
        label.setTooltip(new Tooltip("Cut, Copy, Paste"));

        //TODO: find a better way to center a label.
        VBox vbox = new VBox();
        vbox.getChildren().add(label);
        VBox.setVgrow(label, Priority.ALWAYS);
        vbox.setAlignment(Pos.BOTTOM_CENTER);
        vbox.setStyle("-fx-padding: 5 0 0 0");
        this.layout.add(vbox, 0, 2, 2, 1);

        //Center child nodes in VBox.
        this.root.setAlignment(Pos.CENTER);
        this.root.getChildren().add(layout);
        this.root.getStyleClass().add("toolbarContainer");

    }

    /**
     * pasteButton. Helper method to build the SplitMenuButton.
     */
    private void buildPasteButton() {

        //Create button and set text.
        this.pasteButton = new SplitMenuButton();
        this.pasteButton.setText("Paste");

        //Set alignment of button to text.
        this.pasteButton.setContentDisplay(ContentDisplay.TOP);

        //Retrieve and set image of clipboard. I will set image size to 24x24,
        //preserve the ratio and enable smoothing in the Image constructor.
        String imgPath = "/ui/common/images/clipboard.png";
        Image clipboard = new Image(this.getClass().getResourceAsStream(imgPath),
                24.0, 24.0, true, true);

        //Create an ImageView for showing image.
        ImageView imageView = new ImageView(clipboard);

        //Set the gap b/n graphic and text. Assign the ImageView to the button.
        this.pasteButton.setGraphicTextGap(5.0);
        this.pasteButton.setGraphic(imageView);

        //Paste Menu Item
        MenuItem mnuPaste = new MenuItem("Paste");
        mnuPaste.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Paste clicked.");
            }

        });

        //Paste Special Menu Item
        MenuItem mnuPasteSpecial = new MenuItem("Paste Special...");
        mnuPasteSpecial.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Paste Special clicked.");
            }

        });

        //Paste As Hyperlink Menu Item
        MenuItem mnuPasteHyperlink = new MenuItem("Paste as Hyperlink");
        mnuPasteHyperlink.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Paste as Hyperlink clicked.");
            }

        });

        //Add all MenuItems to the MenuSplitButton's menu options.
        this.pasteButton.getItems().addAll(mnuPaste, mnuPasteSpecial, 
                mnuPasteHyperlink);

        //Set the click event of the Button itself. Note that the JavaDocs
        //points out that MenuItem click events are not transferred to the
        //Buttons click event. So button doesnt reflect the last menu option
        //selected in the drop down portion of the SplitMenuButton.
        this.pasteButton.setOnAction(new EventHandler() {
            @Override
            public void handle(Event arg0) {
                System.out.println("Button Clicked.");
            }
        });

    }

    /**
     * cutButton. Helper method to build cut button.
     */
    private void buildCutButton() {

        String imgPath = "/ui/common/images/cut.png";
        Image cut = new Image(this.getClass().getResourceAsStream(imgPath),
                16.0, 16.0, true, true);
        ImageView imageView = new ImageView(cut);

        this.cutButton.setTooltip(new Tooltip("Cut"));
        this.cutButton.setGraphic(imageView);
        this.cutButton.setOnAction(new EventHandler() {
            @Override
            public void handle(Event event) {
                System.out.println("Cut Button Clicked.");
            }
        });
    }

    /**
     * copyButton. Helper method to build copy button.
     */
    private void buildCopyButton() {

        String imgPath = "/ui/common/images/copy.png";
        Image copy = new Image(this.getClass().getResourceAsStream(imgPath),
                16.0, 16.0, true, true);
        ImageView imageView = new ImageView(copy);

        this.copyButton.setTooltip(new Tooltip("Copy"));
        this.copyButton.setGraphic(imageView);
        this.copyButton.setOnAction(new EventHandler() {
            @Override
            public void handle(Event event) {
                System.out.println("Copy Button Clicked.");
            }
        });
    }

}

Font.java

package ui.layouts.ribbonBar.tabs.home;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;

/**
 * Font. This class represents the Font Ribbon Bar Component.
 */
public class Font {

    private ToggleButton btnBold, btnItalics, btnUnderline, btnSuper, btnSub;
    private Button btnEraser, btnIncreaseFontSize, btnDecreaseFontSize;

    private ChoiceBox cbxFontFamily, cbxFontSize;
    private VBox root;

    /**
     * Default Constructor.
     */
    public Font() {
        this.btnBold = new ToggleButton();
        this.btnItalics = new ToggleButton();
        this.btnUnderline = new ToggleButton();
        this.btnSuper = new ToggleButton();
        this.btnSub = new ToggleButton();
        this.btnEraser = new Button();
        this.btnIncreaseFontSize = new Button();
        this.btnDecreaseFontSize = new Button();
        this.cbxFontFamily = new ChoiceBox();
        this.cbxFontSize = new ChoiceBox();
        this.root = new VBox();

        build();
    }

    /**
     * get. Returns the VBox to be placed on the Ribbon Bar.
     * @return 
     */
    public VBox get() {
        return this.root;
    }

    /**
     * build. Helper method to build the layout.
     */
    private void build() {

        //GridPane used to layout the components.
        GridPane layout = new GridPane();

        //Grid Lines to help layout buttons.
        layout.setGridLinesVisible(false);

        //Set vertical spacing b/n ChoiceBox and ToggleButtons
        layout.setVgap(2);

        //Build UI Controls
        buildFontFamilyChoiceBox();
        buildFontSizeChoiceBox();
        buildBoldButton();
        buildItalicsButton();
        buildUnderlineButton();
        buildSuperScriptButton();
        buildSubScriptButton();
        buildEraserButton();
        buildIncreaseFontSizeButton();
        buildDecreaseFontSizeButton();

        //Group the Superscript and Subscript buttons into a ToggleGroup.
        ToggleGroup group = new ToggleGroup();
        group.getToggles().addAll(this.btnSuper, this.btnSub);

        //layout3 GridPane is for increase/decrease font size buttons.
        GridPane layout3 = new GridPane();
        layout3.add(this.btnIncreaseFontSize, 3, 0);
        layout3.add(this.btnDecreaseFontSize, 4, 0);

        //layout2 GridPane is for top row of choiceBoxes and layout3.
        GridPane layout2 = new GridPane();
        layout2.setHgap(5);
        layout2.add(this.cbxFontFamily, 0, 0);
        layout2.add(this.cbxFontSize, 1, 0);
        layout2.add(this.btnEraser, 2, 0);
        layout2.add(layout3, 3, 0);

        //Add All Componets to the GridPane.
        layout.add(layout2, 0, 0, 6, 1);
        layout.add(this.btnBold, 1, 1);
        layout.add(this.btnItalics, 2, 1);
        layout.add(this.btnUnderline, 3, 1);
        layout.add(this.btnSuper, 4, 1);
        layout.add(this.btnSub, 5, 1);

        //Build the Toolbar Container Label.
        Label label = new Label("Font");
        label.getStyleClass().add("ribbonLabel");
        label.setTooltip(new Tooltip("Specify font styles."));

        //TODO: find a better way to center a label.
        VBox vbox = new VBox();
        vbox.getChildren().add(label);
        VBox.setVgrow(label, Priority.ALWAYS);
        vbox.setAlignment(Pos.BOTTOM_CENTER);
        vbox.setStyle("-fx-padding: 5 0 0 0");
        layout.add(vbox, 0, 2, 6, 1);

        //Center alignment in the VBox, add GridPane, set VBox CSS Selector.
        this.root.setAlignment(Pos.CENTER);
        this.root.getChildren().add(layout);
        this.root.getStyleClass().add("toolbarContainer");
    }

    /**
     * buildFontFamilyChoiceBox. Helper method to add values to ChoiceBox 
     * and set ChangeListener.
     */
    private void buildFontFamilyChoiceBox() {
        this.cbxFontFamily.getItems().addAll(
                FXCollections.observableArrayList("Arial", "Courier", "Tahoma", 
                "Times New Roman", "Verdana", "Vivaldi", "Wide Latin"));

        //Select Verdana to show selection Model (Zero based seleted Index).
        this.cbxFontFamily.getSelectionModel().select(4);

        //Set ChoiceBox width to match the formatting buttons.
        this.cbxFontFamily.setMaxWidth(Double.MAX_VALUE);
        this.cbxFontFamily.setId("fontFamilyChoiceBox");

        //Proceed with caution here. The ChangeListener is new to me.
        this.cbxFontFamily.getSelectionModel().selectedIndexProperty()
                .addListener(new ChangeListener() {

            @Override
            public void changed(ObservableValue value, 
            Object prevValue, Object nextValue) {

                //Retrieve previous Selected Index (if necessary).
                int oldValue = (int) prevValue;

                //Retrieve new Selected Index. ?
                int currValue = (int) nextValue;

                String oldFont = cbxFontFamily.getItems().get(oldValue).toString();
                String newFont = cbxFontFamily.getItems().get(currValue).toString();
                System.out.printf("The original font selection was: %s\n", 
                        oldFont);
                System.out.printf("The current font selection is: %s\n", 
                        newFont);
            }

        });
    }

    /**
     * buildFontSizeChoiceBox. Helper method to add values to ChoiceBox 
     * and set ChangeListener.
     */
    private void buildFontSizeChoiceBox() {
        this.cbxFontSize.getItems().addAll(
                FXCollections.observableArrayList(8,10,12,14,16,18,24,36,48,72));

        //Select 12px to show selection Model (Zero based seleted Index).
        this.cbxFontSize.getSelectionModel().select(2);

        //Set CSS ID
        this.cbxFontSize.setId("fontSizeChoiceBox");

        //Proceed with caution here. The ChangeListener is new to me.
        this.cbxFontSize.getSelectionModel().selectedIndexProperty()
                .addListener(new ChangeListener() {

            @Override
            public void changed(ObservableValue value, 
            Object prevValue, Object nextValue) {

                //Retrieve previous Selected Index (if necessary).
                int oldValue = (int) prevValue;

                //Retrieve new Selected Index. ?
                int currValue = (int) nextValue;

                String oldFont = cbxFontSize.getItems().get(oldValue).toString();
                String newFont = cbxFontSize.getItems().get(currValue).toString();
                System.out.printf("The original font size was: %s\n", 
                        oldFont);
                System.out.printf("The current font size is: %s\n", 
                        newFont);
            }

        });
    }

    /**
     * buildBoldButton. Helper method to build bold button.
     */
    private void buildBoldButton() {
        String imgPath = "/ui/common/images/bold.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                16.0, 16.0, true, true);
        ImageView imageView = new ImageView(image);
        this.btnBold.setGraphic(imageView);

        //Set CSS Styles. Since we added a CSS style selector, the coordinating 
        //CSS styles are .ribbonToggleButton and .leftToggleButton.
        this.btnBold.getStyleClass().add("ribbonToggleButton");
        this.btnBold.getStyleClass().add("leftToggleButton");

        //Set Tooltip
        this.btnBold.setTooltip(new Tooltip("Bold"));

        //Set simple Click Event Handler.
        this.btnBold.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                if (btnBold.isSelected())
                    System.out.println("Bold Style Selected.");
                else
                    System.out.println("Bold Style Deselected.");

            }

        });
    }

    /**
     * buildItalicsButton. Helper method to build italics button.
     */
    private void buildItalicsButton() {
        String imgPath = "/ui/common/images/italics.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                16.0, 16.0, true, true);
        ImageView imageView = new ImageView(image);

        this.btnItalics.setGraphic(imageView);
        this.btnItalics.getStyleClass().add("ribbonToggleButton");
        this.btnItalics.getStyleClass().add("middleToggleButton");
        this.btnItalics.setTooltip(new Tooltip("Italics"));
        this.btnItalics.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                if (btnItalics.isSelected())
                    System.out.println("Italics Style Selected.");
                else
                    System.out.println("Italics Style Deselected.");
            }

        });
    }

    /**
     * buildUnderlineButton. Helper method to build underline button.
     */
    private void buildUnderlineButton() {
        String imgPath = "/ui/common/images/underline.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                16.0, 16.0, true, true);
        ImageView imageView = new ImageView(image);

        this.btnUnderline.setGraphic(imageView);
        this.btnUnderline.getStyleClass().add("ribbonToggleButton");
        this.btnUnderline.getStyleClass().add("middleToggleButton");
        this.btnUnderline.setTooltip(new Tooltip("Underline"));
        this.btnUnderline.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                if (btnUnderline.isSelected())
                    System.out.println("Underline Style Selected.");
                else
                    System.out.println("Underline Style Deselected.");
            }

        });
    }

    /**
     * buildSuperScriptButton. Helper method to build superscript button.
     */
    private void buildSuperScriptButton() {

        String imgPath = "/ui/common/images/superscript.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                16.0, 16.0, true, true);
        ImageView imageView = new ImageView(image);

        this.btnSuper.setGraphic(imageView);
        this.btnSuper.getStyleClass().add("ribbonToggleButton");
        this.btnSuper.getStyleClass().add("middleToggleButton");
        this.btnSuper.setTooltip(new Tooltip("Superscript"));
        this.btnSuper.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                if (btnSuper.isSelected())
                    System.out.println("SuperScript Style Selected.");
                else
                    System.out.println("SuperScript Style Deselected.");
            }

        });
    }

    /**
     * buildSubScriptButton. Helper method to build subscript button.
     */
    private void buildSubScriptButton() {
        String imgPath = "/ui/common/images/subscript.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                16.0, 16.0, true, true);
        ImageView imageView = new ImageView(image);

        this.btnSub.setGraphic(imageView);
        this.btnSub.getStyleClass().add("ribbonToggleButton");
        this.btnSub.getStyleClass().add("rightToggleButton");
        this.btnSub.setTooltip(new Tooltip("Subscript"));
        this.btnSub.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                if (btnSub.isSelected())
                    System.out.println("SubScript Style Selected.");
                else
                    System.out.println("SubScript Style Deselected.");
            }

        });
    }

    /**
     * buildEraserButton. Helper method to build eraser button.
     */
    private void buildEraserButton() {
        String imgPath = "/ui/common/images/eraser.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                16.0, 16.0, true, true);
        ImageView imageView = new ImageView(image);

        this.btnEraser.setGraphic(imageView);
        this.btnEraser.getStyleClass().add("ribbonToggleButton");
        this.btnEraser.setTooltip(new Tooltip("Clear Font Styles"));
        this.btnEraser.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Clear Font Styles Button Selected.");
            }

        });
    }

    /**
     * buildIncreaseFontSizeButton. Helper method to build increase font size button.
     */
    private void buildIncreaseFontSizeButton() {
        String imgPath = "/ui/common/images/increaseFont.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                16.0, 16.0, true, true);
        ImageView imageView = new ImageView(image);

        this.btnIncreaseFontSize.setGraphic(imageView);
        this.btnIncreaseFontSize.getStyleClass().add("ribbonToggleButton");
        this.btnIncreaseFontSize.getStyleClass().add("leftToggleButton");
        this.btnIncreaseFontSize.setTooltip(new Tooltip("Increase Font Size"));
        this.btnIncreaseFontSize.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Increase Font Size Button Selected.");
            }

        });
    }

    /**
     * buildDecreaseFontSizeButton. Helper method to build decrease font size button.
     */
    private void buildDecreaseFontSizeButton() {
        String imgPath = "/ui/common/images/decreaseFont.png";
        Image image = new Image(this.getClass().getResourceAsStream(imgPath),
                16.0, 16.0, true, true);
        ImageView imageView = new ImageView(image);

        this.btnDecreaseFontSize.setGraphic(imageView);
        this.btnDecreaseFontSize.getStyleClass().add("ribbonToggleButton");
        this.btnDecreaseFontSize.getStyleClass().add("rightToggleButton");
        this.btnDecreaseFontSize.setTooltip(new Tooltip("Decrease Font Size"));
        this.btnDecreaseFontSize.setOnAction(new EventHandler() {

            @Override
            public void handle(Event event) {
                System.out.println("Decrease Font Size Button Selected.");
            }

        });
    }

}

HomeTab.java

package ui.layouts.ribbonBar.tabs.home;

import javafx.scene.control.Tab;
import javafx.scene.layout.HBox;

/**
 * HomeTab. This class represents the "Home Tab"; where common functions
 * might be placed.
 */
public class HomeTab {

    private Tab tab;

    /**
     * Default Constructor.
     */
    public HomeTab() {
        tab = new Tab("Home");
        buildTab();
    }

    /**
     * get. Returns an instance of the Home Tab. This will be added to the 
     * TabPane in the RibbonBar class.
     * @return 
     */
    public Tab get() {
        return this.tab;
    }

    /**
     * buildTab. Helper method to build the Home Tab UI.
     */
    private void buildTab() {

        //Do not allow tab to close.
        tab.setClosable(false);

        //The container holds all toolbar sections specific to a Tab.
        HBox container = new HBox();

        //Set ID (for CSS styles)
        container.setId("container");

        //Set preferred height.
        container.setPrefHeight(90);

        //Put spacing b/n each toolbar block
        container.setSpacing(5);

        //Add the Actions Ribbon Component
        Actions actions = new Actions();
        container.getChildren().add(actions.get());

        //Add the Clipboard Ribbon Component.
        Clipboard clipboard = new Clipboard();
        container.getChildren().add(clipboard.get());

        //Add the Fonts Ribbon Component.
        Font font = new Font();
        container.getChildren().add(font.get());

        //Add Container.
        tab.setContent(container);

    }

}

App.css

/* 
    Document   : App
    Created on : Mar 23, 2012, 1:53:13 PM
    Description:
        Some general styles not related to Ribbon Menu could go here. 
*/

/**
 * Set the background color of the Scene.
 */
#app { 
    -fx-background-color: #333;
}

tabs.css

/* 
    Document   : tabs
    Created on : Mar 23, 2012, 2:12:26 PM
    Description:
        Style the Ribbon Bar.
*/

/**
 * This style creates the gradient effect across the entire "Ribbon Strip"
 * background. This is an HBox in FX application. You will find the HBox 
 * container in the HomeTab.java and InsertTab.java classes.
 */
#container {
    -fx-padding: 3px;
    -fx-background-color: 
        linear-gradient(#ffffff 0%, #ced3da 4%, #c1c6cf 17%, #b4bbc5 18%, #e5ebeb 100%);

}

/**
 * This style creates the gradient effect and rounded borders for each content
 * area in Ribbon Strip. This is a VBox in FX application. You will find this 
 * style in all classes like Clipboard.java, Font.java, InsertTab.java and 
 * Tables.java.
 */
.toolbarContainer {
    -fx-background-color: 
        linear-gradient(#dae0e7 0%, #ced4dd 14%, #c8ced7 15%, #dfe5e6 100%),
        linear-gradient(#bdbfc1 0%, #9a9c9f 14%, #888b90 15%, #838686 100%),
        linear-gradient(#eef1f6 0%, #e1e6ee 14%, #d5dbe7 15%, #eef4f4 79%, 
        #ced4e6 79%, #afb6c8 100%);

    -fx-background-insets: 1 0 1 1, 1, 2 ;
    -fx-background-radius: 5,4,3;
    -fx-padding: 4 8 0 8;
}

/**
 * This selector simply applies a font color to each label in the Toolbar 
 * Container Areas. These include labels like Clipboard, Font, Insert, Colorful
 * Icons, etc...
 */
.ribbonLabel {
    -fx-text-fill: #535459;
}

/**
 * Selector for each toggle button. This is a general style. Find examples
 * of use in the Font.java class.
 */
.ribbonToggleButton {
    -fx-text-fill: #000000;
    -fx-background-color: 
        linear-gradient(#dae0e7 0%, #ced4dd 14%, #c8ced7 15%, #dfe5e6 100%),
        linear-gradient(#bdbfc1 0%, #9a9c9f 14%, #888b90 15%, #838686 100%),
        linear-gradient(#eef1f6 0%, #e1e6ee 14%, #d5dbe7 15%, #eef4f4 79%, 
        #ced4e6 79%, #afb6c8 100%);

    -fx-background-insets: 1 0 1 1, 1, 2 ;
    -fx-background-radius: 5,4,3;
    -fx-padding: 5 6 5 6;

}

/**
 * Hover effect for the toggle button.
 */
.ribbonToggleButton:hover {
    -fx-background-color: 
        linear-gradient(#dae0e7 0%, #ced4dd 14%, #c8ced7 15%, #dfe5e6 100%),
        linear-gradient(#bdbfc1 0%, #9a9c9f 14%, #888b90 15%, #838686 100%),
        linear-gradient(#fef7d5 0%, #fae5a8 14%, #ffd048 15%, #ffe59f 78%, 
        #ffe498 79%, #fff9cc 100%);    
}

/**
 * Selected (when pressed) effect for the toggle button.
 */
.ribbonToggleButton:selected {
    -fx-background-color: 
        linear-gradient(#dae0e7 0%, #ced4dd 14%, #c8ced7 15%, #dfe5e6 100%),
        linear-gradient(#bdbfc1 0%, #9a9c9f 14%, #888b90 15%, #838686 100%),
        linear-gradient(#fbdbb5 0%, #fec778 14%, #ffa636 15%, #fdeb9f 78%, 
        #dfcd82 79%, #f0e7bf 100%);
}

/**
 * To create the effect of having multiple toggle buttons grouped together, I 
 * adjusted the background insets and radius. Basically I am ajusting the 
 * TOP, RIGHT, BOTTOM, LEFT of each layer. So each layer is separated by a
 * comma and CSS statement is terminated by ending semi colon. The bottom layer
 * is first and each subsequent layer is stacked on top.
 */

 /**
  * Middle Toggle Button
  */
.middleToggleButton {
    -fx-background-insets: 0 0 0 1, 1 0 1 0, 2 0 2 0;
    -fx-background-radius: 0 0 0 0, 0 0 0 0, 0 0 0 0;
}

 /**
  * Left side Toggle Button
  */
.leftToggleButton {
    -fx-background-insets: 0 0 0 1, 1 0 1 1, 2 0 2 2;
    -fx-background-radius: 0 0 0 5, 4 0 0 4, 3 0 0 3;
}

 /**
  * Right side Toggle Button
  */
.rightToggleButton {
    -fx-background-insets: 0 1 0 0, 1 1 1 0, 2 2 2 0 ;
    -fx-background-radius: 0 5 0 0, 0 4 4 0, 0 3 3 0;  
}

 /**
  * I added some padding to make the ChoiceBoxes a little taller.
  */
#fontFamilyChoiceBox {
    -fx-padding: 3 5 3 5;
}

#fontSizeChoiceBox {
    -fx-padding: 3 5 3 5;
}
Advertisements
Categories: Java FX 2 Tags:

Java FX 2 Linear Gradients

March 23, 2012 3 comments

I really didnt understand the concept of multiple linear gradients so I decided to study Jasper’s demo on styling fx buttons with CSS. I picked the example “Large iPad Dark Grey” for this demonstration.

As you can see, multiple gradients make up the glossy button effect. I am visual person so to me this example is stunning.

I was pleasantly surprised at the simplicity after reviewing the CSS styles that create these buttons. I suspect its one thing to say it looks easy but I am sure it requires creativity to blend the colors.

The concept behind building this button is working with multiple linear gradients. The trick is creating multiple layers, each with their own gradient effect and adjusting the background radius and background insets.

#ipad-dark-grey {
    -fx-background-color:
        linear-gradient(#686868 0%, #232723 25%, #373837 75%, #757575 100%),
        linear-gradient(#020b02, #3a3a3a),
        linear-gradient(#9d9e9d 0%, #6b6a6b 20%, #343534 80%, #242424 100%),
        linear-gradient(#8a8a8a 0%, #6b6a6b 20%, #343534 80%, #262626 100%),
        linear-gradient(#777777 0%, #606060 50%, #505250 51%, #2a2b2a 100%);
    -fx-background-insets: 0,1,4,5,6;
    -fx-background-radius: 9,8,5,4,3;
    -fx-padding: 15 30 15 30;
    -fx-font-family: "Helvetica";
    -fx-font-size: 18px;
    -fx-font-weight: bold;
    -fx-text-fill: white;
    -fx-effect: dropshadow( three-pass-box , rgba(255,255,255,0.2) ,
                1, 0.0 , 0 , 1);
}

Take notice that there is a background inset and background radius that is paired with each linear gradient. In this example there are 5 linear gradients, 5 background-radius settings, and background-insets settings.

The [unattractive] example below color coordinates the matching linear-gradient and background properties together. I hope it helps to visualize the relationship between the linear-gradient and its inset and radius.

In theory, Jasper has layered multiple background fills on top of each other. With each overlay he has reduced the radius and increased the background inset.

-fx-background-color:
    linear-gradient(#686868 0%, #232723 25%, #373837 75%, #757575 100%),
    linear-gradient(#020b02, #3a3a3a),
    linear-gradient(#9d9e9d 0%, #6b6a6b 20%, #343534 80%, #242424 100%),
    linear-gradient(#8a8a8a 0%, #6b6a6b 20%, #343534 80%, #262626 100%),
    linear-gradient(#777777 0%, #606060 50%, #505250 51%, #2a2b2a 100%);
-fx-background-insets: 0,1,4,5,6;
-fx-background-radius: 9,8,5,4,3;

How a linear gradient works

Using the example above in orange, here is how a linear gradient works. Starting from the top to the bottom, the first color is #686686 and transitions into color #232723. This consumes the first 25% of the button’s vertical space.

The next color #373837 will consume the next 50% of the button’s vertical space. And finally the color range stops at #757575.

Here is a demo program to show the layering effect one gradient at a time. I go into more detail with CSS button styles for JavaFX 2 apps on my website. Please have a look.

ButtonDemo.java

package ui.layouts.buttons;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ButtonDemo extends Application {

    private VBox layout; // This is the root node.

    /**
     * start. Build and show the JavaFX application.
     * @param stage
     */
    @Override
    public void start(Stage stage) {

        layout = new VBox();

        //Set CSS ID
        layout.setId("app");

        //Center in VBox.
        layout.setAlignment(Pos.CENTER);

        //Set Spacing b/n each button.
        layout.setSpacing(10);

        Button b1 = new Button("Example 1");
        b1.setId("b1");

        Button b2 = new Button("Example 2");
        b2.setId("b2");

        Button b3 = new Button("Example 3");
        b3.setId("b3");

        Button b4 = new Button("Example 4");
        b4.setId("b4");

        Button b5 = new Button("Example 5");
        b5.setId("b5");

        layout.getChildren().addAll(b1, b2, b3, b4, b5);

        //Create Scene, add css stylesheet.
        Scene scene = new Scene(layout, 250, 325);
        String cssURL = "ButtonsDemo.css";
        String css = this.getClass().getResource(cssURL).toExternalForm();
        scene.getStylesheets().add(css);

        //Set stage properties.
        stage.setScene(scene);
        stage.setTitle("CSS Buttons");
        stage.show();
    }

    /**
     * Application Entry Point.
     * @param args
     */
    public static void main(String[] args) {
        launch();
    }
}

ButtonsDemo.css

#app {
    -fx-background-color:
    linear-gradient(to bottom, #f2f2f2, #d4d4d4);
}

#b1 {
    -fx-text-fill:white;
    -fx-padding: 15 30 15 30;
    -fx-font-family: "Helvetica";
    -fx-font-size: 18px;
    -fx-font-weight: bold;

    -fx-background-color:
    linear-gradient(#686868 0%, #232723 25%, #373837 75%, #757575 100%);
    -fx-background-insets: 0;
    -fx-background-radius: 9;
}

#b2 {
    -fx-text-fill:white;
    -fx-padding: 15 30 15 30;
    -fx-font-family: "Helvetica";
    -fx-font-size: 18px;
    -fx-font-weight: bold;

    -fx-background-color:
    linear-gradient(#686868 0%, #232723 25%, #373837 75%, #757575 100%),
    linear-gradient(#020b02, #3a3a3a);
    -fx-background-insets: 0,1;
    -fx-background-radius: 9,8;
}

#b3 {
    -fx-text-fill:white;
    -fx-padding: 15 30 15 30;
    -fx-font-family: "Helvetica";
    -fx-font-size: 18px;
    -fx-font-weight: bold;

    -fx-background-color:
    linear-gradient(#686868 0%, #232723 25%, #373837 75%, #757575 100%),
    linear-gradient(#020b02, #3a3a3a),
    linear-gradient(#9d9e9d 0%, #6b6a6b 20%, #343534 80%, #242424 100%);
    -fx-background-insets: 0,1,4;
    -fx-background-radius: 9,8,5;
}

#b4 {
    -fx-text-fill:white;
    -fx-padding: 15 30 15 30;
    -fx-font-family: "Helvetica";
    -fx-font-size: 18px;
    -fx-font-weight: bold;

    -fx-background-color:
    linear-gradient(#686868 0%, #232723 25%, #373837 75%, #757575 100%),
    linear-gradient(#020b02, #3a3a3a),
    linear-gradient(#9d9e9d 0%, #6b6a6b 20%, #343534 80%, #242424 100%),
    linear-gradient(#8a8a8a 0%, #6b6a6b 20%, #343534 80%, #262626 100%);
    -fx-background-insets: 0,1,4,5;
    -fx-background-radius: 9,8,5,4;
}

#b5 {
    -fx-text-fill:white;
    -fx-padding: 15 30 15 30;
    -fx-font-family: "Helvetica";
    -fx-font-size: 18px;
    -fx-font-weight: bold;

    -fx-background-color:
    linear-gradient(#686868 0%, #232723 25%, #373837 75%, #757575 100%),
    linear-gradient(#020b02, #3a3a3a),
    linear-gradient(#9d9e9d 0%, #6b6a6b 20%, #343534 80%, #242424 100%),
    linear-gradient(#8a8a8a 0%, #6b6a6b 20%, #343534 80%, #262626 100%),
    linear-gradient(#777777 0%, #606060 50%, #505250 51%, #2a2b2a 100%);
    -fx-background-insets: 0,1,4,5,6;
    -fx-background-radius: 9,8,5,4,3;
}