Archive

Author Archive

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;
}
Categories: Java FX 2 Tags:

MySQL Workbench SSH Connection on Joyent Server

April 7, 2012 Leave a comment

Here is how I was able to setup MySQL Workbench to manage the MySQL databases on my Joyent SmartOS web server.

In my opinion, the most confusing part I had to understand was creating a MySQL user that connects “locally”. By locally, I mean the user that is created is connecting from the server itself. This is in contrast to what I was expecting which was creating a user that connects from a remote location (work or home).

What you will need to know:
Public IP Address – Your public IP Address was assigned to you by Joyent when you provisioned your machine. This can be found in your Joyent Cloud administration located under Machines tab. I will use 64.65.66.100 in this example.

SSH Hostname – This will be your public IP Address combined with port #22. Port 22 is typically the SSH port. In this example, the hostname is 64.65.66.100:22.

SSH Username and Password – The username/password of the account you will use to SSH into your Joyent machine. For example, I will use the admin account which has some elevated privileges.

MySQL Hostname – Enter your public IP address here. I am assuming that MySQL server is installed on the same server.

MySQL Server Port – Typically this is 3306. You can validate this by checking the configuration file. See below.

Username & Password – Enter the username and password of the MySQL user here. Since we are using SSH to securely connect to the server, the MySQL user is going to be a local user. Again this is local to the Server, not to the remote location you are connecting from. See below. In this example, the username is ‘yourUserName@abc123.local’.

Check which port number MySQL Server is using:
SSH into your server and view your MySQL configuration file. If you aren’t sure where it is located – use the find command.

#Use the find command to locate my.cnf
sudo find / -name my.cnf 2>/dev/null

#Open the configuration file to find the port number.
sudo vi /etc/my.cnf

You will see the port number in two locations. Honestly, I am not sure the difference but I suspect it relates to the client and mysql daemon. You should see: port = 3306 in either case. At this time, I am not interested in researching it.

Create a “local” MySQL user:
At your terminal window prompt, connect to MySQL server to create a new user.

#First find the local hostname (in this example is abc123.local). Type
#the hostname command at terminal prompt. The output is used in your
#MySQL username.

$ hostname
$ abc123.local
$ _

#Connect to MySQL Server
$ mysql -u root -p

#Create a user
mysql> create user ‘yourUserName’@’abc123.local’ identified by ‘password’;

#Grant Privileges
mysql> grant all privileges on *.* to ‘yourUsername’@’abc123.local’ identified by ‘password’;

Set your bind address:
You will need to set the bind address to the public IP address. I’ve read on the web that there should not be a bind address of 127.0.0.1. I don’t understand why. So I have changed it to the public IP address.

#Open the configuration file for editing.
sudo vi /etc/my.cnf

#Change the bind-address value to the public IP Address. Save and quit.
bind-address = 64.65.66.100

In MySQL Workbench, Create a new Server Instance Profile:
1. In MySQL Workbench, click the “New Server Instance” link to create a connection to your server.

2. Choose “Remote Host” and enter the Joyent public IP address. Click next.

3. Fill out the connection details below.

Connection Name: Change to a meaningful name if you like. Ex: “My Connection”
Connection Method: Choose Standard TCP/IP over SSH
SSH Hostname: Set to public IP address
SSH Username: Enter username of your SSH account. I used admin in this example.
SSH Password: Store the password of the user in the vault.
SSH Keyfile: I kept blank.
MySQL Hostname: Set to the public IP address
Username: Set to the username you created. Use only the username (without hostname appended). For example, if the MySQL user is “yourUserName@abc123.local”, use “yourUserName” here. In the photo below I used “you@abc123.local” which is the same idea.
Password: Store the password in vault. In this example, I set the password to “password”. See SQL scripts.
Default Schema: I kept blank.

4. Proceed through rest of the Setup wizard…

Hopefully you should be ready to start querying the database. You can do so by double clicking the Connection located under SQL Development on the Home Tab.

Categories: MySQL 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;
}

Working with JavaFX 2 Layout Managers

March 22, 2012 5 comments

My original objective was to work with the GridPane layout manager. During my learning process I ended up working with the VBox, HBox, BorderPane and GridPane.

Below is the code. Please see attached PDFs. I have two versions of each PDF with our without line numbers. Also consider taking a look at several tutorials on other layout managers in JavaFX 2 on javadesk.co website.

Screen shots

PDFs of JavaFX 2 Code

JavaFX 2 application (no line numbers)This version of the source code does not contain line numbers. Use this version for copy / paste.

JavaFX 2 CSS style sheet (no line numbers)This version of the CSS style sheet used with application does not contain line numbers. Use this version for copy / paste.

JavaFX 2 application (with line numbers)This version of the source code contains line numbers. Use this version for printing.

JavaFX 2 CSS style sheet (with line numbers)This version of the CSS style sheet used with application contains line numbers. Use this version for printing.

Demo1.java

package ui.layouts.GridPane;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Screen;
import javafx.stage.Stage;

/**
 * Demo1. Entry point into demonstration application.
 */
public class Demo1 extends Application {

    private BorderPane layout;
    private Scene scene;
    private TextField txtFirstName, txtLastName;

    @Override
    public void start(Stage stage) {

        //Create BorderPane layout manager.
        layout = new BorderPane();  //This is the "root node".

        //Give Root Node a CSS ID Attribute
        layout.setId("appContainer");

        //Set Scene Properties.
        setSceneProperties();

        //Build Demo App Layout
        buildLeft();
        buildTop();

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

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

    /**
     * buildLeft. This method builds the Left Region of BorderPane.
     * This is a BorderPane with VBox containing buttons and border.
     */
    private void buildLeft() {

        BorderPane leftLayout = new BorderPane();

        // Create a faux border-right effect using a Label.
        Label divider = new Label();
        divider.setId("divider1");
        divider.setPrefWidth(1);
        divider.setMinHeight(Screen.getPrimary().getBounds().getHeight());
        leftLayout.setRight(divider);

        //Place all demonstration buttons in a Vercial Box.
        VBox buttonBox = new VBox();

        //Set Alignment of Buttons in VBox Container.
        buttonBox.setAlignment(Pos.TOP_CENTER);

        //Give VBox a CSS ID
        buttonBox.setId("buttonMenuContainer");

        //Create some vertical spacing b/n buttons
        buttonBox.setSpacing(10);

        //Add Demonstration Buttons
        Button btnExample1 = new Button();

        //Set Button Text
        btnExample1.setText("Example 1");

        //Set All Buttons to the same size.
        btnExample1.setMaxWidth(Double.MAX_VALUE);

        //Add Click Event.
        btnExample1.setOnAction(new EventHandler() {

            @Override
            public void handle(ActionEvent event) {
                System.out.println("Example 1 Button Clicked.");
                layout.setCenter(example1());
            }
        });

        //Create Button 2
        Button btnExample2 = new Button();
        btnExample2.setText("Useless Button");
        btnExample2.setMaxWidth(Double.MAX_VALUE);
        btnExample2.setOnAction(new EventHandler() {

            @Override
            public void handle(ActionEvent event) {
                System.out.println("Example 2 Button Clicked.");
            }
        });

        //Create Button 3
        Button btnExample3 = new Button();
        btnExample3.setText("Useless Button");
        btnExample3.setMaxWidth(Double.MAX_VALUE);
        btnExample3.setOnAction(new EventHandler() {

            @Override
            public void handle(ActionEvent event) {
                System.out.println("Example 3 Button Clicked.");
            }
        });

        buttonBox.getChildren().addAll(btnExample1, btnExample2, btnExample3);

        //Add VBox to leftLayout.
        leftLayout.setCenter(buttonBox);

        //Place into Application.
        layout.setLeft(leftLayout);

    }

    /**
     * buildTop. Create a Title Bar.
     */
    private void buildTop() {

        BorderPane topLayout = new BorderPane();

        //Add CSS Style ID.
        topLayout.setId("topLayoutContainer");

        // Create a faux border-bottom effect using a Label.
        Label divider = new Label();
        divider.setId("divider2");
        divider.setMaxHeight(1);
        divider.setMinHeight(1);
        divider.setMinWidth(Screen.getPrimary().getBounds().getWidth());
        topLayout.setBottom(divider);

        //Create an HBox to hold title.
        //We use the HBox to set text alignment to TOP LEFT
        HBox titleBox = new HBox();
        titleBox.setAlignment(Pos.TOP_LEFT);
        titleBox.setId("titleBox");

        //Create title.
        Label title = new Label();
        title.setText("GridPane Demo");
        title.setId("appTitle");

        //Add Title label to titleBox
        titleBox.getChildren().add(title);

        //Add Title Box (with label) to topLayout
        topLayout.setCenter(titleBox);

        //Add topLayout (a BorderPane Manager) to App Layout.
        layout.setTop(topLayout);

    }

    /**
     * setSceneProperties. This simply sets app to almost full size.
     * It also is where the css stylesheet is attached to app.
     */

    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("Demo1.css").toExternalForm();
        scene.getStylesheets().add(css);

    }

    /**
     * example1. This method just creates a simple GridPane with 2
     * rows and 2 columns. This example demonstrates the use of
     * showing gridLines.
     * @return
     */
    private VBox example1() {

        //Create a container to fill 100% space in Center Region of
        //App BorderPane (layout).
        VBox exContainer = new VBox();
        exContainer.setId("exContainer");

        //Create a new GridPane.
        GridPane gridPane = new GridPane();

        //Turn on GridLines so we can see what is going on.
        gridPane.setGridLinesVisible(true);

        //Give the GridPane an ID for CSS Styles.
        gridPane.setId("gridPane_Example1");

        //Add some spacing between each control.
        //Comment the next 2 lines out to see what happens when this is
        //not explicitly set. It will remove the padding you specified.
        gridPane.setHgap(5);
        gridPane.setVgap(5);

        //Add a description of what we are doing to GridPane.
        //This description starts in Row 0, Col 0 and spans
        //2 columns and one row.
        Label label = new Label("Turn on the grid lines to see results.");
        gridPane.add(label, 0,0,2,1);

        //Add A Label. The label starts in Col 0, Row 1 and does not
        //span any columns or rows.
        gridPane.add(new Label("First Name"), 0, 1);

        //Add a TextField. The textfield starts in Col 1, Row 1 and
        //does not span any columns or rows.
        txtFirstName = new TextField();
        txtFirstName.setId("txtFirstName");
        gridPane.add(txtFirstName, 1,1);

        //Add Last Name label in Col 0, Row 2
        gridPane.add(new Label("Last Name"), 0,2);

        //Add Last Name Text Field in Col 1, Row 2.
        txtLastName = new TextField();
        txtLastName.setId("txtLastName");
        gridPane.add(txtLastName, 1,2);

        //Add a Submit Button.
        Button submitButton = new Button("Submit");
        submitButton.setOnAction(new EventHandler() {

            @Override
            public void handle(ActionEvent event) {
                System.out.printf("Submit Button Clicked. Hi there %s %s",
                        txtFirstName.getText(), txtLastName.getText());
            }
        });
        gridPane.add(submitButton, 1,3);

        //Align the Submit Button to Right.
        gridPane.setHalignment(submitButton, HPos.RIGHT);

        //Add GridPane to container.
        exContainer.getChildren().add(gridPane);

        //Return Container
        return exContainer;
    }
}

Demo1.css

/*
    Document   : Demo1
    Created on : Mar 22, 2012, 11:20:14 AM
    Description: Style our JavaFX 2 application demo.
                 Put this css style sheet in same package
                 (or directory) as Java class.
*/

/**
 * This is the root node. In demo this is the BorderPane that is passed
 * into the Scene constructor.
 */
#appContainer {
    -fx-background-color: linear-gradient(to bottom, #464646, #5f5f5f);
}

/**
 * This CSS style is for the buttonBox in Left region of BorderPane.
 * It sets a linear gradient background color and applies a 1px padding
 * around the VBox inner edges.
 */
#buttonMenuContainer {
    -fx-background-color: linear-gradient(to bottom, #737373, #595959);
    -fx-padding: 10px;
}

/**
 * Give the buttonBox container a subtle hover effect.
 */
#buttonMenuContainer:hover {
    -fx-background-color: linear-gradient(to bottom, #717171, #515151);
}

/**
 * This is a makeshift border. #divider1 creates the right border inside
 * The Application's Left Region. #divider2 creates the bottom border
 * for the title.
 *
 * The idea was to use a Blank Label. For example, for the Title, which is
 * located in the BorderPane Top Region; I've set the Labels minWidth
 * property to the screen size. This creates the effect of a bottom border.
 *
 * Set the background color here.
 */
#divider1, #divider2{
    -fx-background-color: linear-gradient(to bottom, #dad9d9, #ffffff);
}

/**
 * the topLayoutContainer is a BorderPane manager that is placed inside the
 * application's layout container (root node). This is how I was able to
 * create the bottom border effect (#divider2).
 */
#topLayoutContainer {
    -fx-background-color: linear-gradient(to bottom, #ebeced, #b5bcc6);
}

/**
 * appTitle text.
 */
#appTitle {
    -fx-text-fill: linear-gradient(to bottom, #717171, #515151);
    -fx-font-family: verdana;
    -fx-font-size: 24px;
}

/**
 * This class is a HBox used to set the alignment of the appTitle Text
 * The padding is set to push the title down and to the right from the
 * container edges.
 */
#titleBox {
    -fx-padding: 10px 0 0 15px;
}

/*
 * In this css style, we are applying styles to a GridPane.
 * We apply a border with radius. We also need to apply the
 * background radius. This creates the rounded corners when
 * the first button is clicked. Remember to set both background
 * and border radius.
 */
#gridPane_Example1 {
    -fx-border-color: #ffffff;
    -fx-border-width: 1px;
    -fx-border-radius: 4;
    -fx-background-radius: 4;
    -fx-background-color: linear-gradient(to bottom, #b5bcc6, #dee3e4);
    -fx-padding: 15;

}

/**
 * exContainer ID is applied to a VBox. This VBox is what is physically
 * loaded into the Applications Center region (root node). I use the VBox
 * so content automatically fills available space. 100% width and height.
 */
#exContainer {
    -fx-padding: 10px;
}

/**
 * First Name TextField.
 */
#txtFirstName {
    -fx-border-color: #939393;
    -fx-border-radius: 5px;
    -fx-background-radius: 5px;
    -fx-background-color: linear-gradient(to bottom, #cccccc, #f2f2f2);
}

/**
 * The focused effect.
 */
#txtFirstName:focused {
    -fx-border-color: linear-gradient(to left, #ff0000, #7d1e15);
}

/**
 * The hover effect.
 */
#txtFirstName:hover {
    -fx-border-color: linear-gradient(to left, #ffca45, #f8a70f);
}

/**
 * Keep the focused coloring when mouse is still hovering over
 * text field while active.
 */
#txtFirstName:focused:hover {
    -fx-border-color: linear-gradient(to left, #ff0000, #7d1e15);
}

/**
 * Apply this style to all Label objects.
 */
Label {
    -fx-font-size: 12px;
    -fx-font-weight: lighter;
}

Linking a CSS Style Sheet to JavaFx Scene Graph

March 21, 2012 Leave a comment

The recommended way to link your CSS styles to a Scene Graph in your application is through the stylesheets variable.

Set your css paths relative to your application’s concrete class. This is the class that will extend Application. In the sample project pictured below, the Concrete Application Class is my Driver.java file.

For more information on working with CSS Style Sheets in JavaFX 2 applications please see my article on JavaDesk website. I provide an example where a user can swap Style Sheets dynamically using a ChangeListener.

Driver.java has the class declaration:

public class Driver extends Application {public static void main(String[] args) {
launch(args);
}@Override
public void start(Stage primaryStage) {}
}

Example 1: Connect to CSS Style Sheet in same Package

//Demonstrate in one long line of code.
scene.getStylesheets().add(this.getClass()
.getResource(“Styles.css”).toExternalForm());

//Break up into two lines of code.
String cssURL = this.getClass().getResource(“Styles.css”)
.toExternalForm();
scene.getStylesheets().add(cssURL);

//Replace this keyword with full URL of main class.
scene.getStylesheets().add(ui.Driver.class.getResource(“Styles.css”)
.toExternalForm());

Example 2: Connect to CSS Style Sheet in another Package

//Get a style sheet that is not in same package as Driver.
scene.getStylesheets().add(this.getClass().
getResource(“/cssStyles/base.css”).toExternalForm());

Example 3: Get Multiple CSS Style Sheets

//Use addAll() to attach several stylesheets.
String cssFile1 = this.getClass().getResource(“x.css”)
.toExternalForm();String cssFile2 = this.getClass().getResource(“Styles.css”)
.toExternalForm();String cssFile3 = this.getClass().getResource(“/cssStyles/base.css”)
.toExternalForm();scene.getStylesheets().addAll(cssFile1, cssFile2, cssFile3);

Categories: Java FX 2 Tags:

Apache Web Server on Joyent

March 2, 2012 Leave a comment

Apache Web Server comes installed by default on the SmartOSPlus installation. When I provisioned my machine I had a difficult time finding the Apache directory. To my surprise, it took some time exploring the file system to find the necessary files. Joyent takes a different approach for installing Apache Web Server. Log files are placed with other log files, configuration files are with other configuration files, etc.

It seems most of the the tutorials on the Internet revolve around installing Apache Web Server for personal use. These tutorials expect you to keep the directory structure intact which is clearly different from a Joyent installation.

The important directories are below. This applies to the SmartOSPlus (32 bit) image that Joyent offers. Other OS images may have a different directory structure.

Apache Server Configuration Files:
/opt/local/etc/httpd/

For example, the httpd.conf configuration file is located at:
/opt/local/etc/httpd/httpd.conf

Virtual Host Configuration Files:
/opt/local/etc/httpd/virtualhosts/

For example, the Apache Virtual Host Directive for each of your websites is stored here. If I am hosting http://www.apache.org it would be located at:
/opt/local/etc/httpd/virtualhosts/apache.org.conf

Apache Modules Directory:
/opt/local/lib/httpd/

This is where you will install the mod_jk.so connector for using Tomcat in Apache Web Server.
/opt/local/lib/httpd/mod_jk.so

You will also find mod_alias.so and mod_rewrite.so for URL Rewrites.

Apache Log Files
/var/log/httpd/

You will find access log, error log, module logs, etc. This is a good place to put your mod_jk connector log file and mod_rewrite log files (use mod_rewrite logging for development purposes only).

Setup SSH to connect to Joyent Server

March 2, 2012 Leave a comment

The first step after provisioning your Joyent Server is to connect to it. Please read up on the wiki articles provided at Joyent for setting up a SSH connection. See tutorial for Windows, Mac, Ubuntu Desktop.

Once you have established your connection with your Joyent server, you have several options for logging in via different users. These include:

root
root user is all powerful and should not be used.

admin
admin has elevated privileges which is the account i use for configuring the server.

jill
The user jill is a general purpose user.

Setup SSH Connection using Windows.

Connecting to your Joyent server is an essential part of managing the web server. On Windows computers a terminal emulator is needed for connecting to Joyent servers. This uses SSH (Secure SHell) which is a safe and secure way to connect. For Windows, Joyent recommends you download the PuTTY application as well as PuTTYgen tool.
Install both PuTTY and PuTTYgen with default installation settings. You can download both putty.exe and puttygen.exe from:
http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

Follow this video tutorial on using puttygen to create a public/private key.

Once your public key is created; copy it to the clipboard and paste in Joyent Administration control panel under SSH Keys. This is where you register your SSH Keys for each computer that is connecting to the server.

SSH Key Settings for Joyent Server:
Key Type: SSH-2 RSA
Number of Bits: 4096

Joyent SSH Key Settings

Configure PuTTY to Connect to Joyent (Windows)

Configuring Putty to connect to Joyent Server is simple.

1. IP Address. Enter your Joyent Public IP Address in the Host Name text field.

2. Port. Set port to 22

3. Connection Type. Select SSH as Connection Type.

4. Private Key File.In “Category” TreeView component, open SSH node, select Auth Node. Under authentication parameters, browse to your private key file that you created using the puttygen tool. This file will have a .ppk file extension. [See image 2].

5. Save. Go back to main screen by selecting Session Node in the tree view and click Save to save your connection details.

Connect to Joyent using PuTTY

Finally, double click your Session to connect. You will enter the terminal session as shown in second photo below. On Windows, you will enter your username; such as root, admin, or any other users. Next enter passphrase for that user.

Joyent Server, Tomcat, Apache Web Server and mod_jk Connector

February 15, 2012 Leave a comment

I just setup a new Joyent Server Smart Machine. I have to admit it was a challenge for me to get it up and running. I am a novice to Linux so this setup came with a steep learning curve. But I say it was worth it from how much I learned. Here is what I did – I hope that something here helps you.

Server Details:
I am running the SmartOSPlus (32bit) Image. This version is recommended for those who want a quick setup and minimal configuration. This package comes with most Linux based tools. Note that a few are different since these machines run Sun Solaris.

SmartOS vs Linux.

At Joyent you have the option of a Linux or Solaris (SmartOS) installation. Here are some factors to consider that might help you make a decision on which OS to choose.

Linux instances run on top of KVM Hypervisor on SmartOS in the Joyent Cloud.  By doing this, a lot of the built in performance/instant scalability features of SmartOS are disabled as they do not work beyond the hypervisor.  The specifics are listed out below:

SmartOS gives you several advantages over Linux.  They include:

  1. ARC for caching of files in memory on each server
  2. CPU bursting for flash incidents that require more compute – no cost for this.
  3. Live resize w/o reboot of RAM (up and down) via API or my.joyentcloud.com dashboard
  4. Full and deep integration of Cloud Analytics.  Linux does not have as deep of integration as SmartOS does.
  5. SmartOS is still UNIX so your typical LAMP stack works the same way.
  6. SmartOS security patching is done by Joyent as the maintainer of the OS.  Patching of Linux would be your responsibility
  7. SmartOS machines can come preloaded with LAMP stack and has a large repository of additional packages precompiled.
  8. Many GNU tools come loaded to give it the ease of use that Linux has.

My Objective:
Setup a web server. My goal is to migrate from Windows Server running Visual Basic .net web pages to a Linux based platform. I’m freeing my dependency on Microsoft products one day at a time. Yeah! We all will get there when ready, right?

I will discuss each of these:
ssh Connection
Apache Web Server
Tomcat 6
Tomcat Auto Startup/Shutdown
– mod_jk Connector
– MySQL Database Server
– MySQL Workbench
– Website Setup
– SFTP Connection

Useful Links to use during Setup

  • Joyent Wiki
    http://wiki.joyent.com/display/jpc2/JoyentCloud+Home
    This is the wiki provided by Joyent. It provides updated information that pertains to the SmartOS machines.
  • Joyent Administration Settings
    https://my.joyentcloud.com/
    The administration control panel for billing, server credentials, and SSH keys.
  • Virtual/Webmin login
    MY.PUBLIC.IP.ADDRESS:10000
    The virtualmin control panel is located on port 10000 of your public IP address provided by Joyent or any domain name you have pointed to your Joyent Server.

Terms that might be useful:

Here are a couple of terms that you might find beneficial. These terms are specific to Joyent Servers and configurations (im not trying to insult you).

ip address:
Joyent provides two IP addresses. One is the private and the other is public. These can be found in your Administration Settings (my.joyentcloud.com). Login to account settings, click “Machines” Tab, click on your smart machine to view the details. You will see both public and private IP addresses. Your private IP address will start with 192.168.xxx.xxx. The other is your public IP address.

private ip address:
The private IP address is for internal use such as connecting to a dedicated database server, mail server, etc. If you only purchased one server; I dont believe you will be using the private IP address.

public ip address:
The public IP address is the IP address used for pointing all websites you manage. This is also used in SSH connections, MySQL workbench connections, and SFTP connections.

Server reboot.
There are two ways to reboot your server on a Joyent machine. You can reboot from the Joyent Administration control panel (my.joyentcloud.com). Login to your Joyent control panel, navigate to Machine Details and click the “reboot” button. You can update the status by clicking the “refresh status” button as well.

The second option is when logged in a bash shell prompt. This is the better option of the two. This is a graceful reboot. Finish editing any files and get to the point where you are ready for server to reboot.Type:

sudo shutdown -y -i6 -g0

Apache reboot.
To reboot Apache Web Server on Joyent Server. See Apache HTTP Server Control Interface Docs or use one of the commands below:
Reboot Apache:

sudo apachectl restart

Stop Apache:

sudo apachectl stop

Start Apache:

sudo apachectl start

Create SSH Key for Joyent Server

February 13, 2012 Leave a comment

An SSH key consists of a pair of files. One is the private key, which you should never give to anyone. The other is the public key. You will need a public key to log into most machines you provision.

To generate an SSH key in Ubuntu 11, follow these steps.

  1. Enter the following command in the Terminal window.
    gregg@workstation1:~$ ssh-keygen -t rsa

    This starts the key generation process. The -t option specifies what type of SSH key to generate. When you execute this command, the ssh-keygen tool prompts you to indicate where to store the key.

    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/gregg/.ssh/id_rsa):
  2. Press the ENTER key to accept the default.
  3. The ssh-keygen utility prompts you for a passphrase. Enter a phrase you can remember. You can use a key without a passphrase, but this is not recommended.
    Enter passphrase (empty for no passphrase):
  4. You need to enter the passphrase a second time to continue.
    Enter same passphrase again:

    After you confirm the passphrase, the command generates the key pair

    Your identification has been saved in /home/gregg/.ssh/id_rsa.
    Your public key has been saved in /home/gregg/.ssh/id_rsa.pub.
    The key fingerprint is:
    ae:89:72:0b:85:da:5a:f4:7c:1f:c2:43:fd:c6:44:38 gregg@workstation1
    The key's randomart image is:
    +--[ RSA 2048]----+
    |                 |
    |         .       |
    |        E .      |
    |   .   . o       |
    |  o . . S .      |
    | + + o . +       |
    |. + o = o +      |
    | o...o * o       |
    |.  oo.o .        |
    +-----------------+

Your private key is saved to a file named id_rsa in the .ssh directory.

Never share your private key with anyone!

Your public key is saved to a file named id_rsa.pub. This file contains the information you will add to your JoyentCloud account.

cat ~/.ssh/id_rsa.pub

Categories: Solaris 10

Boot Tomcat at Server Startup/Reboot

February 12, 2012 Leave a comment

I am running Sun Solaris 11 on a Joyent Machine. This may not apply to typical Tomcat setups.

My resources that helped achieve this. Both Peter Black and Peter Tribble are much more articulate in technical writing. So have a look:
1. Joyent Wiki, i forget which article.
2. Peter black: Solaris 10 manifest for starting up tomcat.
3. Peter Tribble: Peter’s Solaris Zone

Create a Manifest File which will be registered with Solaris. Mine looks like this:

<?xml version="1.0" ?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type='manifest' name='Tomcat6'>
  <service name='application/servers/tomcat' type='service' version='1'>
    <create_default_instance enabled='false' />
       <single_instance/>
       <exec_method type='method' name='start' exec='/opt/local/java/tomcat6/bin/startup.sh' timeout_seconds='30' >
         <method_context>
           <method_credential user='tomcat' group='tomcat' privileges='basic,net_privaddr' />
           <method_environment>
             <envvar name="CATALINA_BASE" value="/opt/local/java/tomcat6" />
             <envvar name="CATALINA_HOME" value="/opt/local/java/tomcat6" />
             <envvar name="CATALINA_TMPDIR" value="/opt/local/java/tomcat6/temp" />
             <envvar name="JAVA_HOME" value="/opt/local/java/sun6" />
           </method_environment>
         </method_context>
       </exec_method>
       <exec_method type='method' name='stop' exec='/opt/local/java/tomcat6/bin/shutdown.sh' timeout_seconds='60' >
         <method_context>
           <method_credential user='tomcat' group='tomcat' />
           <method_environment>
             <envvar name="CATALINA_BASE" value="/opt/local/java/tomcat6" />
             <envvar name="CATALINA_HOME" value="/opt/local/java/tomcat6" />
             <envvar name="CATALINA_TMPDIR" value="/opt/local/java/tomcat6/temp" />
             <envvar name="JAVA_HOME" value="/opt/local/java/sun6" />
           </method_environment>
         </method_context>
       </exec_method>
       <stability value='Unstable' />
       <template>
         <common_name>
           <loctext xml:lang='C'> Tomcat </loctext>
         </common_name>
       </template>
   </service>
</service_bundle>

How to customize this manifest file:

Give the service manifest a meaningful name. I chose tomcat6. This can be found in the xml node:

<service_bundle type=’manifest’ name=’Tomcat6‘>

Set the path to file (i think). Here I’ve created the servers directory. And file name is tomcat.xml Note that the .xml extension isnt included in name attribute.
<service name=’application/servers/tomcat‘ type=’service’ version=’1′>

This file is stored in the vendor recommended location on the filesystem:

/var/svc/manifest/application/

And the complete path including the directory and file that I manually created:

/var/svc/manifest/application/servers/tomcat.xml

Next fill in all information regarding your configuration. Such as startup.sh, shutdown.sh scripts and environment variables. Read the Peter Black article for specifics.

Register the Manifest File.

Once the manifest file has been created and saved in the /var/svc/manifest/application/… directory; register it with the Service Management Facility (smf).

To begin, import the file. At terminal command prompt:

svccfg -v import /var/svc/manifest/application/servers/tomcat.xml

A successful import may look like the following:

svccfg: Taking “initial” snapshot for svc:/application/servers/tomcat:default svccfg: Taking “last-import” snapshot for svc:/application/servers/tomcat:default svccfg: Refreshed svc:/application/servers/tomcat:default svccfg: Successful import

Debugging a Manifest File

Originally I had some errors. This required some exploration to understand. Here is what i concluded and this is where Peter Tribble’s Solaris Zone is extremely useful. Specifically he helped me understand how to “correct a fault in a manifest file”.

I attempted to start tomcat svcadm enable tomcat in which nothing happened. So to begin isolating the error I looked at the log file for my service. Take a look:

First attempt to enable my Tomcat service. At this point the manifest file above has been imported. Using the svcadm tool, lets enable tomcat service, check the status, notice its in maintenance mode which means its not running. Then check the logs to determine why its not running and fix accordingly.

svcadm enable tomcat

svcs -lp tomcat

svcs -lp tomcat
fmri svc:/application/servers/tomcat:default
name Apache Tomcat 6.0.35
enabled true
state maintenance
next_state none
state_time February 5, 2012 08:59:59 PM UTC
logfile /var/svc/log/application-servers-tomcat:default.log
restarter svc:/system/svc/restarter:default contract_id

As you can see in the code above, the Tomcat service is in maintenance mode. So Tomcat isnt running. Time to view the log file to see what the issue is. In my case, the environment variables weren’t defined.

cat /var/svc/log/application-servers-tomcat:default.log

I see the log entry below:

Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
At least one of these environment variable is needed to run this program
[ Feb  5 20:59:59 Method “start” exited with status 1. ]

My fix was to add the environment variables in the manifest file shown above. So hopefully you will not see this error. I was able to add the environment variables to the manifest file and startup the service without any other problems.

At this point, I believe that adding environment variables to any of the traditional files (.bashrc,  .bash_profile, /etc/.profile, etc) is not necessary.

Some commands that might be useful:

Start/Stop Tomcat service.
svcadm enable tomcat
svcadm disable tomcat

View Status of a specific service.
svcs -lp tomcat

View Status of all services.
svcs -a

When the tomcat service is enabled, Apache Tomcat Server will start up when the Server is rebooted.

To correct errors in a manifest file:

1. Edit the manifest file.
sudo vi /var/svc/manifest/application/servers/tomcat.xml

2. Disable the entry:
svcadm -v disable svc:/application/web/tomcat:default

3. Delete the entry:
svccfg -v delete svc:/application/web/tomcat:default

4. Import updated manifest file:
svccfg -v import /var/svc/manifest/application/servers/tomcat.xml

5. Start up entry.
svcadm enable tomcat