An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it. Common examples include compass directions (values of
NORTH,SOUTH,EAST, andWEST) and the days of the week.Because they are constants, the names of an enum type's fields are in uppercase letters. In the Java programming language, you define an enum type by using the
enumkeyword. For example, you would specify a days-of-the-week enum type as:public enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY }You should use enum types any time you need to represent a fixed set of constants. That includes natural enum types such as the planets in our solar system and data sets where you know all possible values at compile time—for example, the choices on a menu, command line flags, and so on. -- Java Tutorial
Note that while enumerations are usually a simple set of fixed values, Java enumerations can have behaviors too. To learn how to implement enumerations, read this tutorial (from Oracle)
Adapted (with permissions) from Marco Jakob's JavaFX 8 tutorial.
This tutorial will teach you how to create a new JavaFX application in IntelliJ, and to use the SceneBuilder to create a layouts for your application.
                  
                  Do remember the installation path to SceneBuilder 8 as we will need it to configure IntelliJ in a later step.
If this is the first time using IntelliJ, you need to tell IntelliJ where to find JDK 8 and SceneBuilder.
Configure → Project Default → Project Structure.
                  
                  File → Close Project.Project SDK:, press New... → JDK.OK.
                  
                  OK again.Configure → Settings.Languages & Frameworks → JavaFXPath to SceneBuilder:, select the path to where SceneBuilder is installed (e.g. C:\Users\Admin\AppData\Local\SceneBuilder\SceneBuilder.exe on Windows)
                  
                  The JavaDocs will come in handy when writing your own JavaFX applications:
Additionally, Oracle also has a tutorial on JavaFX if you are interested.
Create New Project.File → New → Project....JavaFX. Make sure that the Project SDK is set to 1.8 and JavaFX Application is selected.
                  
                  Next.AddressApp), and specify a suitable location.Finish. If prompted to create a new directory, just press OK.Remove the sample package and its content. We will manually create our own package and resources in our tutorial.
In We will create a package for each of the component. Ensure that your Project pane is open (Alt+1). Right click on the src folder, and select New → Package:
seedu.address - contains the controller classes (i.e. the part that deals with the business logic)seedu.address.model - contains the model classes (i.e. the part that deals with data)seedu.address.view - contains the views (i.e. the part that deals with presenting the data to the user)
                  
                  In subsequent tutorials, our view package will also contain some controllers that are directly related to a single view. We will call them view-controllers.
There are two ways to create the UI:
We will use FXML for most parts, so that we can separate the view and controller from each other. Furthermore, we are able to use the Scene Builder tool to edit our FXML file. That means we will not have to directly work with XML.
Right click on the view package, and press New → FXML file. For the file name, type PersonOverview.fxml.
Right-click on PersonOverview.fxml and choose Open with Scene Builder. Now you should see the Scene Builder with just an AnchorPane (visible under Hierarchy on the left).
If IntelliJ prompts for a location of the SceneBuilder executable, make sure to point to where you install SceneBuilder.
Anchor Pane in your Hierarchy, and adjust the size under Layout (right side). (Pref Width: 600, Pref Height: 300)
                  
                  Split Pane (Horizontal Flow) (under Containers) by dragging it from the Library into the main area. Right-click the Split Pane in the Hierarchy view and select Fit to Parent.
                  
                  TableView (under Controls in Library view) into the left side of the SplitPane. Select the TableView (not a Column) and set the following layout constraints in the Inspector
                      to the TableView. Inside an AnchorPane you can always set anchors to the four borders (see this page for more information
                      on Layouts).
                  
                  Go to the menu Preview → Show Preview in Window to see whether the layout configuration is done correctly. Try resizing the window. The TableView should resize together with the window as it
                        is anchored to the borders.
Change the column text (under Properties) to "First Name" and "Last Name".
                  
                  TableView and choose constrainted-resize for the 'Column Resize Policy'. This ensures that the columns will always fill up the entire available space.
                  
                  Label on the right side with the text "Person Details:". Adjust the layout using anchors (Top: 5, Left: 5. Right: Blank, Bottom: Blank).
                  
                  You can use the Search Bar at the top of Library/Inspector to find the respective controls/properties.
GridPane on the right side. Select it, and adjust its layout using anchors (Top: 30, Left: 5, Right: 5, Bottom: Blank).
                  
                  | First Name | Label | 
|---|---|
| Last Name | Label | 
| Street | Label | 
| City | Label | 
| Postal Code | Label | 
| Birthday | Label | 
To add a row to the GridPane, select an existing row number, right click the row number and choose "Add Row Below".
                  
                  
                  
                  ButtonBar at the bottom. Add three buttons to the bar ("New...", "Edit...","Delete"). Adjust the anchors so that it stays at the bottom right (Top: Blank, Left: Blank, Right: 10, Bottom:
                      5).
                  
                  Preview menu to test its resizing behaviour.
                  
                  .fxml file.The PersonOverview.fxml that we just created only contains the content of our entire application. We need another FXML for our root layout, which will contain a menu bar and wraps PersonOverview.fxml.
view package, and press New → FXML file. For the file name, type RootLayout.fxml.RootLayout.fxml and choose Open with Scene Builder.AnchorPane. We will use another pane for our root layout.
                  
                  BorderPane by dragging it from the Library view into the main area.
                  
                  BorderPane (Pref Width: 600, Pref Height: 400)
                  
                  MenuBar into the insert TOP slot. We will not implement menu functionality for now.
                  
                  Now, we need to create the main Java class that starts up our application with the RootLayout.fxml and adds the PersonOverview.fxml in the center.
Right-click on your seedu.address package, and choose New → JavaFXApplication. For the class name, type MainApp.
The generated MainApp.java class extends from Application and contains two methods. This is the basic structure that we need to start a JavaFX Application. The most important part for us is the start(Stage primaryStage)                    method. It is automatically called when the application is launch() from within the main() method.
As you see, the start(...) method receives a Stage as parameter. The following graphic illustrates the structure of every JavaFX application:
                  
                  Image Source: http://www.oracle.com
It's like a theater play: The Stage is the main container which is usually a Window with a border and the typical minimize, maximize and close buttons. Inside the Stage you add a Scene                    which can, of course, be switched out by another Scene. Inside the Scene the actual JavaFX nodes like AnchorPane, TextBox, etc. are added.
See this page fore more info on working with the JavaFX Scene Graph.
Open MainApp.java and replace the code with the following:
MainApp.java
package seedu.address;
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class MainApp extends Application {
    private Stage primaryStage;
    private BorderPane rootLayout;
    @Override
    public void start(Stage primaryStage) {
        this.primaryStage = primaryStage;
        this.primaryStage.setTitle("AddressApp");
        initRootLayout();
        showPersonOverview();
    }
    /**
     * Initializes the root layout.
     */
    public void initRootLayout() {
        try {
            // Load root layout from fxml file.
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(MainApp.class.getResource("view/RootLayout.fxml"));
            rootLayout = loader.load();
            // Show the scene containing the root layout.
            Scene scene = new Scene(rootLayout);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * Shows the person overview inside the root layout.
     */
    public void showPersonOverview() {
        try {
            // Load person overview.
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(MainApp.class.getResource("view/PersonOverview.fxml"));
            AnchorPane personOverview = loader.load();
            // Set person overview into the center of root layout.
            rootLayout.setCenter(personOverview);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * Returns the main stage.
     */
    public Stage getPrimaryStage() {
        return primaryStage;
    }
    public static void main(String[] args) {
        launch(args);
    }
}
                  The various comments should give you some hints about what's going on.
If you run the application now (right click MainApp.java and select Run MainApp.main()), you should see something like this:
                  
                  If JavaFx fails to load PersonOverview.fxml, you might get the following error message:
javafx.fxml.LoadException:
/.../AddressApp/out/production/AddressApp/seedu/address/view/PersonOverview.fxml:15
                  To solve this issue, open PersonOverview.fxml normally in IntelliJ and ensure that there is no such attribute around:
fx:controller="seedu.address.view.PersonOverview"
In this tutorial, we will create the other parts of the application (mainly the model and the controller). We will also use ObservableList and *Property to bind our list of new model's Persons,
                    and their individual details, to the view, with the controller as the "middleman".
                  
                  We need a model class in order to hold information about the people in our address book. Add a new class to the model package (seedu.address.model) called Person. The Person class will
                    encapsulate the details of an individual person such as name, address and birthday. Add the following code to the class. The JavaFX specifics will be explained after the code snippet.
Person.java
package seedu.address.model;
import java.time.LocalDate;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
 * Model class for a Person.
 */
public class Person {
    private final StringProperty firstName;
    private final StringProperty lastName;
    private final StringProperty street;
    private final IntegerProperty postalCode;
    private final StringProperty city;
    private final ObjectProperty< LocalDate > birthday;
    /**
     * Default constructor.
     */
    public Person() {
        this(null, null);
    }
    /**
     * Constructor with some initial data.
     */
    public Person(String firstName, String lastName) {
        this.firstName = new SimpleStringProperty(firstName);
        this.lastName = new SimpleStringProperty(lastName);
        // Some initial dummy data, just for convenient testing.
        this.street = new SimpleStringProperty("some street");
        this.postalCode = new SimpleIntegerProperty(1234);
        this.city = new SimpleStringProperty("some city");
        this.birthday = new SimpleObjectProperty< LocalDate >(LocalDate.of(1999, 2, 21));
    }
    public String getFirstName() {
        return firstName.get();
    }
    public void setFirstName(String firstName) {
        this.firstName.set(firstName);
    }
    public StringProperty firstNameProperty() {
        return firstName;
    }
    public String getLastName() {
        return lastName.get();
    }
    public void setLastName(String lastName) {
        this.lastName.set(lastName);
    }
    public StringProperty lastNameProperty() {
        return lastName;
    }
    public String getStreet() {
        return street.get();
    }
    public void setStreet(String street) {
        this.street.set(street);
    }
    public StringProperty streetProperty() {
        return street;
    }
    public int getPostalCode() {
        return postalCode.get();
    }
    public void setPostalCode(int postalCode) {
        this.postalCode.set(postalCode);
    }
    public IntegerProperty postalCodeProperty() {
        return postalCode;
    }
    public String getCity() {
        return city.get();
    }
    public void setCity(String city) {
        this.city.set(city);
    }
    public StringProperty cityProperty() {
        return city;
    }
    public LocalDate getBirthday() {
        return birthday.get();
    }
    public void setBirthday(LocalDate birthday) {
        this.birthday.set(birthday);
    }
    public ObjectProperty< LocalDate > birthdayProperty() {
        return birthday;
    }
}
                  *Property for all fields of a model class. A Property allows us, for example, to automatically be notified when the lastName or any other variable is changed.
                      This helps us keep the view in sync with the data.*Property, refer to Using JavaFX Properties and BindingLocalDate, the type that we are using for birthday, is part of the new Date and Time API for JDK 8The main data that our application manages is simply a bunch of persons. Let's create a list of Person objects inside the MainApp class. All other controller classes will later get access to that central list
                    inside the MainApp.
We are working with JavaFX view classes that need to be informed about any changes made to the list of persons. This is important, since otherwise the view would not be in sync with the data. For this purpose, JavaFX introduces some new Collection classes.
Among all these collections, we need the ObservableList. To create a new ObservableList, add the following code at the beginning of the MainApp class. We'll also add a constructor that creates some
                    sample data and a public getter method:
MainApp.java
// ... AFTER THE OTHER VARIABLES ...
/**
* The data as an observable list of {@link Person}.
*/
private ObservableList< Person > personData = FXCollections.observableArrayList();
    /**
     * Constructor
     */
    public MainApp() {
        // Add some sample data
        personData.add(new Person("Hans", "Muster"));
        personData.add(new Person("Ruth", "Mueller"));
        personData.add(new Person("Heinz", "Kurz"));
        personData.add(new Person("Cornelia", "Meier"));
        personData.add(new Person("Werner", "Meyer"));
        personData.add(new Person("Lydia", "Kunz"));
        personData.add(new Person("Anna", "Best"));
        personData.add(new Person("Stefan", "Meier"));
        personData.add(new Person("Martin", "Mueller"));
    }
    /**
     * Returns the data as an observable list of {@link Person}.
     */
    public ObservableList< Person > getPersonData() {
        return personData;
    }
    // ... THE REST OF THE CLASS ...
                  We have our model and view. Let's get our data into our table. We'll need a controller for our PersonOverview.fxml to act as a "middleman" for the model and view.
Create a normal Java class inside the view package called PersonOverviewController.
Note: We must put the class inside the same package as PersonOverview.fxml, otherwise the SceneBuilder won't be able to find it.
We will add some instance variables that give us access to the table and the labels inside the view. The fields and some methods have a special @FXML annotation. This is necessary in order for the .fxml file
                    to have access to private fields and private methods. After we have everything set up in the .fxml file, the application will automatically fill the variables when the .fxml file is loaded.
So let's add the following code:
Note: Remember to always use the javafx imports, NOT awt or swing.
PersonOverviewController.java
package seedu.address.view;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import seedu.address.MainApp;
import seedu.address.model.Person;
public class PersonOverviewController {
    @FXML
    private TableView< Person> personTable;
    @FXML
    private TableColumn< Person, String> firstNameColumn;
    @FXML
    private TableColumn< Person, String> lastNameColumn;
    @FXML
    private Label firstNameLabel;
    @FXML
    private Label lastNameLabel;
    @FXML
    private Label streetLabel;
    @FXML
    private Label postalCodeLabel;
    @FXML
    private Label cityLabel;
    @FXML
    private Label birthdayLabel;
    // Reference to the main application.
    private MainApp mainApp;
    /**
     * The constructor. It is called before the initialize() method.
     */
    public PersonOverviewController() {
    }
    /**
     * Initializes the controller class. This method is automatically called
     * after the fxml file has been loaded.
     */
    @FXML
    private void initialize() {
        // Initialize the person table with the two columns.
        firstNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());
        lastNameColumn.setCellValueFactory(cellData -> cellData.getValue().lastNameProperty());
    }
    /**
     * Is called by the main application to give a reference back to itself.
     */
    public void setMainApp(MainApp mainApp) {
        this.mainApp = mainApp;
        // Add observable list data to the table
        personTable.setItems(mainApp.getPersonData());
    }
}
                  .fxml file needs access must be annotated with @FXML.
                      initialize() method is automatically called after the .fxml file has been loaded. At this time, all the FXML fields should have been initialized already.setCellValueFactory(...) that we set on the table colums are used to determine which field inside the Person objects should be used for the particular column. The arrow -> indicates that
                      we're using a Java 8 feature called Lambdas. (Another option would be to use a PropertyValueFactory, but this is not type-safe).Note:
We're only using StringProperty values for our table columns in this example. When you want to use IntegerProperty or DoubleProperty, the setCellValueFactory(...) must have an additional
                      asObject():
myIntegerColumn.setCellValueFactory(cellData ->
    cellData.getValue().myIntegerProperty().asObject());
                    This is necessary because of a bad design decision of JavaFX (see this discussion for more details).
The setMainApp(...) method must be called by the MainApp class. This gives us a way to access the MainApp object and get the list of Persons and other things. Add the following three
                    lines to showPersonOverview() the method:
MainApp.java - additional lines to add to showPersonOverview() method
// (.... root layout statement goes here ....)
// Give the controller access to the main app.
    PersonOverviewController controller = loader.getController();
    controller.setMainApp(this);
// (.... catch statement goes here ....)
                  Your showPersonOverview() method in MainApp should now look like this:
MainApp.java - new showPersonOverview() method
/**
* Shows the person overview inside the root layout.
*/
public void showPersonOverview() {
    try {
        // Load person overview.
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(MainApp.class.getResource("view/PersonOverview.fxml"));
        AnchorPane personOverview = loader.load();
        // Set person overview into the center of root layout.
        rootLayout.setCenter(personOverview);
        // Give the controller access to the main app.
        PersonOverviewController controller = loader.getController();
        controller.setMainApp(this);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
                  We're almost there! But one thing is missing: We haven't told our PersonOverview.fxml file which controller to use, and which element should match to which field inside the controller.
PersonOverview.fxml with the SceneBuilder.seedu.address.view.PersonOverviewController as the controller class.
                  
                  TableView in the Hierarchy group.personTable.
                  
                  firstNameColumn and lastNameColumn for the 'fx:id' respectively.
                  
                  .fxml file.When you start your application now, you should see something like this:
                  
                  Congratulations! The application now shows the list of Persons in the view!
You may notice that selecting a person in the TableView does nothing to the labels at the right side. That is because the user interaction portion has not been programmed yet, which we will cover in the next part of the
                    tutorial.
Java 8 introduced a number of new features (e.g. Lambdas, Streams) that are not trivial to learn but also extremely useful to know.
Here is an overview of new Java 8 features . (written by Benjamin Winterberg)
Tutorials:
A video tutorial by well-known Java coach Venkat Subramaniam