getting started with javafx + database operations started with javafx + database operations when i...

51
1 Getting Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations for campaign products every week. After the second week, I thought that I have to automate this task using a GUI based desktop program instead of using some DB scripts manually. Then, I started to search which solution I should choose. Finally, I ended up my decision with JavaFX. This is the starting point of my JavaFX journey. In my JavaFX post series, I will try to describe how to create a JavaFX application, how to use its core components, how to communicate with DB and so on. Before starting JavaFX post series, I want to thank Marko Jakob. I learned a lot stuff from his tutorial series and I suggest that check that tutorial series. Let’s get started! What is JavaFX? It is a next generation GUI toolkit and you can create rich GUI applications with JavaFX. You can also customize style using CSS and edit them with XML. Also, it includes a drag and drop design editor that is called as SceneBuilder. It is much easier to design GUIs with SceneBuilder. You can drag and drop GUI elements and then modify their style with CSS or edit them with XML. For more details please visit here. Prerequisites Install latest JAVA JDK 8 from here. Install IntelliJ, Eclipse or Netbeans IDE (I prefer IntelliJ) Install Scene Builder from here. Install Oracle Express Edition from here. Create a JavaFX Project Open IntelliJ and click File ->> New Project and then click Java FX and click Next button.

Upload: trinhdat

Post on 29-Apr-2018

223 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

1

Getting Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations for

campaign products every week. After the second week, I thought that I have to automate this

task using a GUI based desktop program instead of using some DB scripts manually. Then, I

started to search which solution I should choose. Finally, I ended up my decision with

JavaFX. This is the starting point of my JavaFX journey. In my JavaFX post series, I will try

to describe how to create a JavaFX application, how to use its core components, how to

communicate with DB and so on.

Before starting JavaFX post series, I want to thank Marko Jakob. I learned a lot stuff from

his tutorial series and I suggest that check that tutorial series.

Let’s get started!

What is JavaFX?

It is a next generation GUI toolkit and you can create rich GUI applications with JavaFX.

You can also customize style using CSS and edit them with XML. Also, it includes a drag

and drop design editor that is called as SceneBuilder. It is much easier to design GUIs with

SceneBuilder. You can drag and drop GUI elements and then modify their style with CSS or

edit them with XML. For more details please visit here.

Prerequisites

• Install latest JAVA JDK 8 from here.

• Install IntelliJ, Eclipse or Netbeans IDE (I prefer IntelliJ)

• Install Scene Builder from here.

• Install Oracle Express Edition from here.

Create a JavaFX Project

Open IntelliJ and click File ->> New Project and then click Java FX and click Next button.

Page 2: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

2

Type “First_JavaFX_Project” as Project name and set your Project Location as you want

and click Finish button.

Page 3: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

3

Thanks to IntelliJ, it automatically creates a JavaFX project structure and put a sample

Hello World code into Main class.

Page 4: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

4

We are going to write our code based on MVC (Model-View-Controller) principle. Thus, I

used three (plus one “util” package) packages. These are controller, model, and view. We

should move .fxml files into view package and controller classes in controller package. Also,

I added one extra package and called it as util. It is for utility classes such as DBUtil for

database connection operations. “model” package comprises “model” and

“DataAccessObject” classes. A sample application structure is shown below figure.

Also, we need to set SceneBuilder path. To do this, go to File ->> Settings, type “JavaFX”

in the search bar. Then, copy and paste SceneBuilder path as shown below and click OK.

Also, please check this link.

After setting the SceneBuilder path, go into sample.fxml file and right click, then you will see

“Open in SceneBuilder” option. When you click this option, the selected fxml file will open

in SceneBuilder. You can also check here.

Page 5: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

5

We have almost finished our setup. For our first example, we will use Oracle DB and default

HR schema. In second post, we will do some DML (Database Manipulation) operations

such as Create, Read, Update, Delete, Insert, etc. I also explained how to install and use

Oracle Express at the end of this post.

Now, let’s go to our project’s view folder and create EmployeeOperations.fxml and

RootLayout.fxml files manually. To do this, right click your mouse and create a new empty

text file and changed its name as EmployeeOperations.fxml (in next post, I will change its

name as EmployeeView.fxml) . Do the same for the RootLayout.fxml. If you want, you can

do this with SceneBuilder. Finally, in view folder we will have these two .fxml files.

Go to Windows Start and type SceneBuilder and then press Enter, then SceneBuilder will

open.

After that, click “File ->> Open” and open EmployeeOperations.fxml file.

Page 6: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

6

Actually, there are two ways to design user interface. One of them is using IntelliJ to

manipulate .fxml file or using SceneBuilder to design the UI. Using SceneBuilder when

creating and designing UI at the first time is much easier and reasonable. I generally use

intelliJ for manipulating UI at later stages.

First, open EmployeeOperations.fxml file and drag and drop Anchor Pane into the middle

pane of SceneBuilder.

Then, if you want you can modify its properties by using right pane.

Page 7: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

7

You can use left pane’s Controls section to add TextField, Label, TextArea, and button to

design your UI as shown below. The below figure is the draft version of the UI, not the final

version.

Page 8: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

8

You can also group UI elements. Select the UI elements that you want to group then go to

“Arrange > Wrap in” then click the appropriate choice. If elements are vertically listed, then

chose VBox. If they are horizontally listed, then chose HBox.

Page 9: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

9

After grouping those elements, you can change spaces of elements by using right pane

Layout section’s Spacing option.

Then, in order to use these components in the code, you should set fx:id values on the right

pane as shown below.

If you want to set prompt text and default text you can use the Properties section on the

right pane. You can change Prompt Text and Text values as shown below.

While designing UI, you can check its status by typing Ctrl + P.

Page 10: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

10

For more information about layout design, you should visit here and

https://dzone.com/refcardz/javafx-8-1 (I suggest you to visit DZone. They explained layout

design very well.)

Now, let’s design RootLayout. Open RootLayout.fxml with SceneBuilder.

This time drag and drop BorderPane.

Then, add to MenuBar into TOP slot.

Page 11: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

11

RootLayout’s final design is shown below.

Our aim is to show EmployeeOperations.fxml into RootLayout.fxml. Now, I want to

explain JavaFX application structure briefly. Our generated Main class code is shown

below.

package sample;

import javafx.application.Application;

import javafx.fxml.FXMLLoader;

import javafx.scene.Parent;

import javafx.scene.Scene;

import javafx.stage.Stage;

public class Main extends Application {

Page 12: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

12

@Override

public void start(Stage primaryStage) throws Exception{

Parent root = FXMLLoader.load(getClass().getResource("view/sample.fxml"));

primaryStage.setTitle("Hello World");

primaryStage.setScene(new Scene(root, 300, 275));

primaryStage.show();

}

public static void main(String[fusion_builder_container hundred_percent="yes"

overflow="visible"][fusion_builder_row][fusion_builder_column type="1_1"

background_position="left top" background_color="" border_size="" border_color=""

border_style="solid" spacing="yes" background_image="" background_repeat="no-

repeat" padding="" margin_top="0px" margin_bottom="0px" class="" id=""

animation_type="" animation_speed="0.3" animation_direction="left"

hide_on_mobile="no" center_content="no" min_height="none"][] args) {

launch(args);

}

}

This is the default (generated) Main class and it extends Application class. It has start and

main methods. The key method is here start method. It is automatically called with stage

parameter when application launched as you can see in main method.

As you can see below figure, the main container is Stage and it consists of a scene and

scene comprises all kinds of JavaFX elements such as text field, button, etc. All JavaFX

applications structure is like that. You can find more information here.

If we change main class code as shown below, we can open Employee Operations view

inside of the RootLayout Border Pane. I tried to add comments and make the code more

understandable.

package sample;

import javafx.application.Application;

Page 13: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

13

import javafx.fxml.FXMLLoader;

import javafx.scene.Scene;

import javafx.scene.layout.AnchorPane;

import javafx.scene.layout.BorderPane;

import javafx.stage.Stage;

import java.io.IOException;

//Main class which extends from Application Class

public class Main extends Application {

//This is our PrimaryStage (It contains everything)

private Stage primaryStage;

//This is the BorderPane of RootLayout

private BorderPane rootLayout;

@Override

public void start(Stage primaryStage) {

//1) Declare a primary stage (Everything will be on this stage)

this.primaryStage = primaryStage;

//Optional: Set a title for primary stage

this.primaryStage.setTitle("SW Test Academy - Sample JavaFX App");

//2) Initialize RootLayout

initRootLayout();

//3) Display the EmployeeOperations View

showEmployeeOperationsView();

}

//Initializes the root layout.

public void initRootLayout() {

try {

//First, load root layout from RootLayout.fxml

FXMLLoader loader = new FXMLLoader();

loader.setLocation(Main.class.getResource("view/RootLayout.fxml"));

rootLayout = (BorderPane) loader.load();

//Second, show the scene containing the root layout.

Scene scene = new Scene(rootLayout); //We are sending rootLayout to the

Scene.

Page 14: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

14

primaryStage.setScene(scene); //Set the scene in primary stage.

//Third, show the primary stage

primaryStage.show(); //Display the primary stage

} catch (IOException e) {

e.printStackTrace();

}

}

//Shows the employee operations view inside the root layout.

public void showEmployeeOperationsView() {

try {

//First, load EmployeeOperationsView from EmployeeOperations.fxml

FXMLLoader loader = new FXMLLoader();

loader.setLocation(Main.class.getResource("view/EmployeeOperations.fxml"));

AnchorPane employeeOperationsView = (AnchorPane) loader.load();

// Set Employee Operations view into the center of root layout.

rootLayout.setCenter(employeeOperationsView);

} catch (IOException e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

launch(args);

}

}

Result:

Page 15: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

15

Note: Above UI design is the draft version and in next post, we will change and finalize it. In

this post, I do not want to focus the final design of our UI.

When you click any .fxml file in IntelliJ, you can see its content as shown below.

Before start to coding, I want to explain how to install Oracle Express Database

First, you should visit this link and install Oracle Database Express Edition 11g Release 2.

Page 16: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

16

After you installing Oracle Express, please go to this link and UNLOCK HR sample user

account. In this tutorial, we will use HR schema and its tables.

Then, try to connect database with TOAD or Oracle SQL Developer. (I prefer TOAD)

You can see how to connect DB with TOAD in below figure.

Page 17: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

17

Now, we are ready to start coding. In next post, we will use DAO (Data Access Object)

Design Pattern and create EmployeeController controller (Business Class), Employee

model (Employee Model), EmployeeDAO (Data Access Class) classes, and DBUtil class

(DB Connection Utility) for DB connection operations.

Sumber: http://www.swtestacademy.com/getting-started-with-javafx/

Page 18: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

18

Database Operations in JavaFX

At first, part of JavaFX tutorial series, we created a sample JavaFX project, designed the draft

version of the UI and set up an Oracle XE database. In this post, we will create controller,

model, DAO, and Util classes to do DB operations. Before starting to code, I want to give

more information about our example project. The latest version of the UI is shown in the

figure below.

You can design UI using SceneBuilder. After drag and drop any element to the anchor pane,

you need to set their fx:id properties. These properties must be unique and you can use

elements in your code with their unique fx:id properties. Also, you can copy paste any

element on anchor pane then change its name and fx:id value. I demonstrated how to design a

GUI in the figure below.

Page 19: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

19

I listed details of the example below:

• Search an employee using employee’s id and show the result on table view and text area. (SELECT)

• Search all employees and show them on the table view. (SELECT * FROM)

• Update the e-mail address of an employee by using employee’s id. (UPDATE)

• Delete an employee by using employee’s id. (DELETE)

• Insert a new employee to the “employee table”. (INSERT)

• Show results of all operations on the Text Area (Print on Result Console)

We will use Oracle XE database and its default HR schema. In order to connect Oracle DB,

we will use JDBC driver. JDBC driver is a software component enabling a Java application

to interact with a database. To add JDBC driver in our project:

1) Go to your project, right-click, and then click Open Module Settings.

2) Click Libraries then click “+” sign, click “From Maven”

Page 20: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

20

3) Write “odjbc” on search bar and enter. Then, select the “oracle:ojdbc6:11.2.0.3” and

select sources and JavaDocs click OK.

4) Now, we can see ojdbc6:11.2.0.3 library in lib folder on IntelliJ.

Page 21: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

21

Finally, we are ready to start coding. As shown the picture below, I created 4 packages:

controller, model, view and util.

I used DAO Design Pattern to perform Employee operations. I want to explain DAO Pattern

briefly, for more information, I suggest that you check Jakop Jenkov’s DAO tutorial. In DAO

pattern, domain (business) logic does not directly communicate with the DB. It

communicates with DAO layer and DAO layer handles DB operations and sends the results to

the business layer.

The philosophy under DAO pattern is that if you need to change the underlying

persistence mechanism, you can do it in DAO layer, not all the places in the business layer.

It is also very important that no details of underlying DB related mechanism leak out of DAO

layer to business layer.

Page 22: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

22

DBUtil Class

I want to start to explain the code with DBUtil class. In our example, DBUtil class is

responsible for DB connection, DB disconnection, database query and update operations.

DAO Class (EmployeeDAO) uses DBUtil class’s methods to do higher-level DB operations.

In DBUtil Class:

– dbConnect() method connects to DB.

– dbDisconnect() method closes DB connection.

– dbExecuteQuery(String queryStmt) method executes given SQL statement and returns

cachedRowSet set. In order to eliminate “java.sql.SQLRecoverableException: Closed

Connection: next” error we return cachedRowSet instead of ResultSet. Thus, we can use

cachedRowSet in other classes and manipulate that data.

– dbExecuteUpdate(String sqlStmt) method executes given Update, Insert, Delete SQL

operations.

I tried to write explanatory comments in the code below. If you have questions please don’t

hesitate to write a comment. I will try to answer your questions.

DBUtil Class Code:

package sample.util;

import com.sun.rowset.CachedRowSetImpl;

import java.sql.*;

/**

* Created by ONUR BASKIRT on 22.02.2016.

*/

public class DBUtil {

//Declare JDBC Driver

private static final String JDBC_DRIVER = "oracle.jdbc.driver.OracleDriver";

//Connection

private static Connection conn = null;

//Connection String

//String connStr = "jdbc:oracle:thin:Username/Password@IP:Port/SID";

//Username=HR, Password=HR, IP=localhost, IP=1521, SID=xe

private static final String connStr =

"jdbc:oracle:thin:HR/HR@localhost:1521/xe";

//Connect to DB

public static void dbConnect() throws SQLException, ClassNotFoundException {

//Setting Oracle JDBC Driver

Page 23: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

23

try {

Class.forName(JDBC_DRIVER);

} catch (ClassNotFoundException e) {

System.out.println("Where is your Oracle JDBC Driver?");

e.printStackTrace();

throw e;

}

System.out.println("Oracle JDBC Driver Registered!");

//Establish the Oracle Connection using Connection String

try {

conn = DriverManager.getConnection(connStr);

} catch (SQLException e) {

System.out.println("Connection Failed! Check output console" + e);

e.printStackTrace();

throw e;

}

}

//Close Connection

public static void dbDisconnect() throws SQLException {

try {

if (conn != null && !conn.isClosed()) {

conn.close();

}

} catch (Exception e){

throw e;

}

}

//DB Execute Query Operation

public static ResultSet dbExecuteQuery(String queryStmt) throws SQLException,

ClassNotFoundException {

//Declare statement, resultSet and CachedResultSet as null

Statement stmt = null;

ResultSet resultSet = null;

CachedRowSetImpl crs = null;

try {

//Connect to DB (Establish Oracle Connection)

dbConnect();

System.out.println("Select statement: " + queryStmt + "\n");

Page 24: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

24

//Create statement

stmt = conn.createStatement();

//Execute select (query) operation

resultSet = stmt.executeQuery(queryStmt);

//CachedRowSet Implementation

//In order to prevent "java.sql.SQLRecoverableException: Closed

Connection: next" error

//We are using CachedRowSet

crs = new CachedRowSetImpl();

crs.populate(resultSet);

} catch (SQLException e) {

System.out.println("Problem occurred at executeQuery operation : " +

e);

throw e;

} finally {

if (resultSet != null) {

//Close resultSet

resultSet.close();

}

if (stmt != null) {

//Close Statement

stmt.close();

}

//Close connection

dbDisconnect();

}

//Return CachedRowSet

return crs;

}

//DB Execute Update (For Update/Insert/Delete) Operation

public static void dbExecuteUpdate(String sqlStmt) throws SQLException,

ClassNotFoundException {

//Declare statement as null

Statement stmt = null;

try {

//Connect to DB (Establish Oracle Connection)

dbConnect();

//Create Statement

stmt = conn.createStatement();

//Run executeUpdate operation with given sql statement

stmt.executeUpdate(sqlStmt);

Page 25: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

25

} catch (SQLException e) {

System.out.println("Problem occurred at executeUpdate operation : " +

e);

throw e;

} finally {

if (stmt != null) {

//Close statement

stmt.close();

}

//Close connection

dbDisconnect();

}

}

}

Employee Class (Model)

We need a model class to hold information about the employee. Add a new class to the model

package and called it Employee.

This class holds all fields of the Employee such as name, last name, email, etc. It contains set

and get methods and properties for all fields of a model class. A Property notifies us when

any variable such as name, last name, etc. is changed. This helps us keep the view in sync

with the data.

You can see the all fields of the employee from database as shown below.

Employee Class Code:

package sample.model;

import javafx.beans.property.*;

import java.sql.Date;

Page 26: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

26

/**

* Created by ONUR BASKIRT on 27.02.2016.

*/

public class Employee {

//Declare Employees Table Columns

private IntegerProperty employee_id;

private StringProperty first_name;

private StringProperty last_name;

private StringProperty email;

private StringProperty phone_number;

private SimpleObjectProperty<Date> hire_date;

private StringProperty job_id;

private IntegerProperty salary;

private DoubleProperty commission_pct;

private IntegerProperty manager_id;

private IntegerProperty department_id;

//Constructor

public Employee() {

this.employee_id = new SimpleIntegerProperty();

this.first_name = new SimpleStringProperty();

this.last_name = new SimpleStringProperty();

this.email = new SimpleStringProperty();

this.phone_number = new SimpleStringProperty();

this.hire_date = new SimpleObjectProperty<>();

this.job_id = new SimpleStringProperty();

this.salary = new SimpleIntegerProperty();

this.commission_pct = new SimpleDoubleProperty();

this.manager_id = new SimpleIntegerProperty();

this.department_id = new SimpleIntegerProperty();

Page 27: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

27

}

//employee_id

public int getEmployeeId() {

return employee_id.get();

}

public void setEmployeeId(int employeeId){

this.employee_id.set(employeeId);

}

public IntegerProperty employeeIdProperty(){

return employee_id;

}

//first_name

public String getFirstName () {

return first_name.get();

}

public void setFirstName(String firstName){

this.first_name.set(firstName);

}

public StringProperty firstNameProperty() {

return first_name;

}

//last_name

public String getLastName () {

return last_name.get();

Page 28: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

28

}

public void setLastName(String lastName){

this.last_name.set(lastName);

}

public StringProperty lastNameProperty() {

return last_name;

}

//email

public String getEmail () {

return email.get();

}

public void setEmail (String email){

this.email.set(email);

}

public StringProperty emailProperty() {

return email;

}

//phone_number

public String getPhoneNumber () {

return phone_number.get();

}

public void setPhoneNumber (String phoneNumber){

this.phone_number.set(phoneNumber);

}

Page 29: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

29

public StringProperty phoneNumberProperty() {

return phone_number;

}

//hire_date

public Object getHireDate(){

return hire_date.get();

}

public void setHireDate(Date hireDate){

this.hire_date.set(hireDate);

}

public SimpleObjectProperty<Date> hireDateProperty(){

return hire_date;

}

//job_id

public String getJobId () {

return job_id.get();

}

public void setJobId (String jobId){

this.job_id.set(jobId);

}

public StringProperty jobIdProperty() {

return job_id;

}

Page 30: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

30

//salary

public int getSalary() {

return salary.get();

}

public void setSalary(int salary){

this.salary.set(salary);

}

public IntegerProperty salaryProperty(){

return salary;

}

//commission_pct

public double getCommissionPct() {

return commission_pct.get();

}

public void setCommissionPct(double commissionPct){

this.commission_pct.set(commissionPct);

}

public DoubleProperty commissionPctProperty(){

return commission_pct;

}

//manager_id

public int getManagerId() {

return manager_id.get();

}

Page 31: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

31

public void setManagerId(int managerId){

this.manager_id.set(managerId);

}

public IntegerProperty managerIdProperty(){

return manager_id;

}

//department_id

public int getDepartmanId() {

return department_id.get();

}

public void setDepartmantId(int departmentId){

this.manager_id.set(departmentId);

}

public IntegerProperty departmentIdProperty(){

return department_id;

}

}

Employee DAO Class (Data Access Object)

Employee DAO class handles employee related database operations such as searching,

deleting, updating employee with declared SQL statements.

JavaFX view classes need to be informed about any changes made to the list of employees. It

is important for the view to be synchronized with the data. For this purpose, we use

ObservableList collection and hold the employee in this list.

• searchEmployee and searchEmployees methods use DBUtil class’s dbExecuteQuery() method.

• The other methods (update/delete/insert), use DBUtil class’s dbExecuteUpdate() method.

I tried to add descriptive inline comments in the code shown below.

Page 32: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

32

EmployeeDAO Class Code:

package sample.model;

import javafx.collections.FXCollections;

import javafx.collections.ObservableList;

import sample.util.DBUtil;

import java.sql.ResultSet;

import java.sql.SQLException;

public class EmployeeDAO {

//*******************************

//SELECT an Employee

//*******************************

public static Employee searchEmployee (String empId) throws SQLException, ClassNotFoundException {

//Declare a SELECT statement

String selectStmt = "SELECT * FROM employees WHERE employee_id="+empId;

//Execute SELECT statement

try {

//Get ResultSet from dbExecuteQuery method

ResultSet rsEmp = DBUtil.dbExecuteQuery(selectStmt);

//Send ResultSet to the getEmployeeFromResultSet method and get employee object

Employee employee = getEmployeeFromResultSet(rsEmp);

//Return employee object

return employee;

} catch (SQLException e) {

System.out.println("While searching an employee with " + empId + " id, an error occurred: " + e);

//Return exception

throw e;

}

}

Page 33: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

33

//Use ResultSet from DB as parameter and set Employee Object's attributes and return employee object.

private static Employee getEmployeeFromResultSet(ResultSet rs) throws SQLException

{

Employee emp = null;

if (rs.next()) {

emp = new Employee();

emp.setEmployeeId(rs.getInt("EMPLOYEE_ID"));

emp.setFirstName(rs.getString("FIRST_NAME"));

emp.setLastName(rs.getString("LAST_NAME"));

emp.setEmail(rs.getString("EMAIL"));

emp.setPhoneNumber(rs.getString("PHONE_NUMBER"));

emp.setHireDate(rs.getDate("HIRE_DATE"));

emp.setJobId(rs.getString("JOB_ID"));

emp.setSalary(rs.getInt("SALARY"));

emp.setCommissionPct(rs.getDouble("COMMISSION_PCT"));

emp.setManagerId(rs.getInt("MANAGER_ID"));

emp.setDepartmantId(rs.getInt("DEPARTMENT_ID"));

}

return emp;

}

//*******************************

//SELECT Employees

//*******************************

public static ObservableList<Employee> searchEmployees () throws SQLException, ClassNotFoundException {

//Declare a SELECT statement

String selectStmt = "SELECT * FROM employees";

//Execute SELECT statement

try {

//Get ResultSet from dbExecuteQuery method

ResultSet rsEmps = DBUtil.dbExecuteQuery(selectStmt);

Page 34: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

34

//Send ResultSet to the getEmployeeList method and get employee object

ObservableList<Employee> empList = getEmployeeList(rsEmps);

//Return employee object

return empList;

} catch (SQLException e) {

System.out.println("SQL select operation has been failed: " + e);

//Return exception

throw e;

}

}

//Select * from employees operation

private static ObservableList<Employee> getEmployeeList(ResultSet rs) throws SQLException, ClassNotFoundException {

//Declare a observable List which comprises of Employee objects

ObservableList<Employee> empList = FXCollections.observableArrayList();

while (rs.next()) {

Employee emp = new Employee();

emp.setEmployeeId(rs.getInt("EMPLOYEE_ID"));

emp.setFirstName(rs.getString("FIRST_NAME"));

emp.setLastName(rs.getString("LAST_NAME"));

emp.setEmail(rs.getString("EMAIL"));

emp.setPhoneNumber(rs.getString("PHONE_NUMBER"));

emp.setHireDate(rs.getDate("HIRE_DATE"));

emp.setJobId(rs.getString("JOB_ID"));

emp.setSalary(rs.getInt("SALARY"));

emp.setCommissionPct(rs.getDouble("COMMISSION_PCT"));

emp.setManagerId(rs.getInt("MANAGER_ID"));

emp.setDepartmantId(rs.getInt("DEPARTMENT_ID"));

//Add employee to the ObservableList

empList.add(emp);

}

//return empList (ObservableList of Employees)

return empList;

Page 35: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

35

}

//*************************************

//UPDATE an employee's email address

//*************************************

public static void updateEmpEmail (String empId, String empEmail) throws SQLException, ClassNotFoundException {

//Declare a UPDATE statement

String updateStmt =

"BEGIN\n" +

" UPDATE employees\n" +

" SET EMAIL = '" + empEmail + "'\n" +

" WHERE EMPLOYEE_ID = " + empId + ";\n" +

" COMMIT;\n" +

"END;";

//Execute UPDATE operation

try {

DBUtil.dbExecuteUpdate(updateStmt);

} catch (SQLException e) {

System.out.print("Error occurred while UPDATE Operation: " + e);

throw e;

}

}

//*************************************

//DELETE an employee

//*************************************

public static void deleteEmpWithId (String empId) throws SQLException, ClassNotFoundException {

//Declare a DELETE statement

String updateStmt =

"BEGIN\n" +

" DELETE FROM employees\n" +

" WHERE employee_id ="+ empId +";\n" +

" COMMIT;\n" +

"END;";

Page 36: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

36

//Execute UPDATE operation

try {

DBUtil.dbExecuteUpdate(updateStmt);

} catch (SQLException e) {

System.out.print("Error occurred while DELETE Operation: " + e);

throw e;

}

}

//*************************************

//INSERT an employee

//*************************************

public static void insertEmp (String name, String lastname, String email) throws SQLException, ClassNotFoundException {

//Declare a DELETE statement

String updateStmt =

"BEGIN\n" +

"INSERT INTO employees\n" +

"(EMPLOYEE_ID, FIRST_NAME, LAST_NAME, EMAIL, HIRE_DATE, JOB_ID)\n" +

"VALUES\n" +

"(sequence_employee.nextval, '"+name+"', '"+lastname+"','"+email+"', SYSDATE, 'IT_PROG');\n" +

"END;";

//Execute DELETE operation

try {

DBUtil.dbExecuteUpdate(updateStmt);

} catch (SQLException e) {

System.out.print("Error occurred while DELETE Operation: " + e);

throw e;

}

}

}

RootLayout FXML

Page 37: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

37

RootLayout contains a border pane and menu items. We need to bind it with

RootLayoutController class.

We have three menus: File, Operations, and Help.

File Menu has Close option to exit the program. Operations menu has “New Menu Item”

option. Help Menu has “About” option to show information about program.

RootLayout View Code:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Menu?>

<?import javafx.scene.control.MenuBar?>

<?import javafx.scene.control.MenuItem?>

<?import javafx.scene.layout.BorderPane?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="370.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.controller.RootLayoutController">

<top>

<MenuBar BorderPane.alignment="CENTER">

<menus>

<Menu mnemonicParsing="false" text="File">

<items>

<MenuItem mnemonicParsing="false" onAction="#handleExit" text="Close" />

</items>

</Menu>

<Menu mnemonicParsing="false" text="Edit">

<items>

<MenuItem mnemonicParsing="false" text="New Menu Item" />

</items>

</Menu>

<Menu mnemonicParsing="false" text="Help">

<items>

Page 38: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

38

<MenuItem mnemonicParsing="false" onAction="#handleHelp" text="About" />

</items>

</Menu>

</menus>

</MenuBar>

</top>

</BorderPane>

EmployeeView FXML

EmployeeView fxml file comprises of text fields, buttons, table view and text area for

employee related operations. We need to bind it with EmployeeController class.

As you see the picture below, we need to declare fx:id values, these values are unique for

each element and we can bind methods with these elements by OnAction tag. Methods must

start with “#” sign.

Employee View Code:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>

<?import javafx.scene.layout.*?>

<?import javafx.scene.text.*?>

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="344.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.controller.EmployeeController">

<children>

<TextField fx:id="empIdText" layoutX="193.0" layoutY="41.0" prefHeight="25.0" prefWidth="67.0" promptText="Emp ID" />

<Label layoutX="194.0" layoutY="21.0" text="Employee ID" />

<Button fx:id="searchEmpBtn" layoutX="194.0" layoutY="70.0" mnemonicParsing="false" onAction="#searchEmployee" prefHeight="25.0" prefWidth="56.0" text="Search" />

Page 39: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

39

<Button fx:id="deleteEmpBtn" layoutX="332.0" layoutY="70.0" mnemonicParsing="false" onAction="#deleteEmployee" prefHeight="25.0" prefWidth="56.0" text="Delete" />

<Button fx:id="updateEmpBtn" layoutX="263.0" layoutY="70.0" mnemonicParsing="false" onAction="#updateEmployeeEmail" prefHeight="25.0" prefWidth="56.0" text="Update" />

<Button fx:id="addEmpBtn" layoutX="82.0" layoutY="114.0" mnemonicParsing="false" onAction="#insertEmployee" text="Add Employee" />

<TextArea fx:id="resultArea" layoutX="7.0" layoutY="250.0" prefHeight="85.0" prefWidth="167.0" wrapText="true" />

<Label layoutX="9.0" layoutY="231.0" text="Result Console">

<font>

<Font name="System Bold" size="12.0" />

</font></Label>

<TextField fx:id="newEmailText" layoutX="268.0" layoutY="41.0" prefHeight="25.0" prefWidth="120.0" promptText="new email" />

<Label layoutX="270.0" layoutY="21.0" text="New Email" />

<VBox layoutX="97.0" layoutY="24.0" spacing="4.0">

<children>

<TextField fx:id="nameText" prefHeight="25.0" prefWidth="79.0" promptText="Name" />

<TextField fx:id="surnameText" prefHeight="25.0" prefWidth="79.0" promptText="Surname" />

<TextField fx:id="emailText" prefHeight="25.0" prefWidth="79.0" promptText="email" />

</children>

</VBox>

<VBox layoutX="9.0" layoutY="28.0" prefWidth="67.0" spacing="12.0">

<children>

<Label text="Name" />

<Label text="Surname" />

<Label text="Email" />

</children>

</VBox>

<Separator layoutY="14.0" prefHeight="4.0" prefWidth="600.0" />

<Separator layoutX="180.0" layoutY="14.0" orientation="VERTICAL" prefHeight="333.0" prefWidth="7.0" />

<TableView fx:id="employeeTable" editable="true" layoutX="193.0" layoutY="102.0" prefHeight="234.0" prefWidth="393.0" tableMenuButtonVisible="true">

<columns>

<TableColumn fx:id="empIdColumn" prefWidth="57.0" text="Id" />

<TableColumn fx:id="empNameColumn" prefWidth="75.0" text="Name" />

Page 40: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

40

<TableColumn fx:id="empLastNameColumn" prefWidth="73.0" text="LastName" />

<TableColumn fx:id="empEmailColumn" prefWidth="79.0" text="Email" />

<TableColumn fx:id="empPhoneNumberColumn" prefWidth="73.0" text="Phone" />

<TableColumn fx:id="empHireDateColumn" prefWidth="93.0" text="Hire Date" />

</columns>

</TableView>

<Button fx:id="searchEmpsBtn" layoutX="396.0" layoutY="70.0" mnemonicParsing="false" onAction="#searchEmployees" prefHeight="25.0" prefWidth="139.0" text="Search All Employees" />

</children>

</AnchorPane>

RootLayoutController Class

In RootLayoutController class, we handle exit and help methods. Exit method closes program

and help method gives information about program by using Alert class.

RootLayoutController Code:

package sample.controller;

import javafx.event.ActionEvent;

import javafx.scene.control.Alert;

import sample.Main;

public class RootLayoutController {

//Exit the program

public void handleExit(ActionEvent actionEvent) {

System.exit(0);

}

//Help Menu button behavior

public void handleHelp(ActionEvent actionEvent) {

Alert alert = new Alert (Alert.AlertType.INFORMATION);

alert.setTitle("Program Information");

alert.setHeaderText("This is a sample JAVAFX application for SWTESTACADEMY!");

Page 41: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

41

alert.setContentText("You can search, delete, update, insert a new employee with this

program.");

alert.show();

}

}

EmployeeController Class

In EmployeeController class, fields and methods have special @FXML annotation. We need

this annotation because fxml file needs to access private fields and private methods. After

these settings, application will automatically fill the variables when the fxml file is loaded.

EmployeeController Class handles below operations:

– searchEmployee() – Searches an employee with given employee id. Then, populate

employee’s information on table view and print the result on text area.

– searchEmployees() – Gets all employees information and populates them on table view.

– initialize() – Handles initialization. When the fxml file is loaded, it will be called

automatically.

– populateEmployee(Employee) – Populates employee on table view.

– setEmpInfoToTextArea(Employee) – Prints employee information on text area.

– populateEmployees(ObservableList<Employee>) – Populates employees.

– updateEmployeeEmail() – Updates employee email by using employee id

– insertEmployee() – Insert a new employee into employee table.

– deleteEmployee() – Deletes an employee with employee’s id.

Extra Explanations:

– Private fields and methods where the fxml file needs to access must be annotated with

@FXML annotation.

– After the fxml file has been loaded, the initialize() method will be called automatically.

– The setCellValueFactory(…) that we set on the table columns are used to determine which

field inside the Employee objects should be used for the particular column. The arrow ->

indicates that we are using a Java 8 feature called Lambdas. (Another option would be to

use a PropertyValueFactory).

– If you use a property which is different than StringProperty, such as IntegerProperty,

DoubleProperty, etc. the setCellValueFactory(…) must have an additional asObject()

method:

empIdColumn.setCellValueFactory(cellData ->

cellData.getValue().employeeIdProperty().asObject());

Note: Always use the javafx imports, NOT awt or swing!

EmployeeController Class Code:

package sample.controller;

Page 42: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

42

import javafx.collections.FXCollections;

import javafx.collections.ObservableList;

import javafx.event.ActionEvent;

import javafx.fxml.FXML;

import javafx.scene.control.TableColumn;

import javafx.scene.control.TableView;

import javafx.scene.control.TextArea;

import javafx.scene.control.TextField;

import sample.model.Employee;

import sample.model.EmployeeDAO;

import java.sql.Date;

import java.sql.SQLException;

/**

* Created by ONUR BASKIRT on 23.02.2016.

*/

public class EmployeeController {

@FXML

private TextField empIdText;

@FXML

private TextArea resultArea;

@FXML

private TextField newEmailText;

@FXML

private TextField nameText;

@FXML

private TextField surnameText;

@FXML

Page 43: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

43

private TextField emailText;

@FXML

private TableView employeeTable;

@FXML

private TableColumn<Employee, Integer> empIdColumn;

@FXML

private TableColumn<Employee, String> empNameColumn;

@FXML

private TableColumn<Employee, String> empLastNameColumn;

@FXML

private TableColumn<Employee, String> empEmailColumn;

@FXML

private TableColumn<Employee, String> empPhoneNumberColumn;

@FXML

private TableColumn<Employee, Date> empHireDateColumn;

//Search an employee

@FXML

private void searchEmployee (ActionEvent actionEvent) throws ClassNotFoundException,

SQLException {

try {

//Get Employee information

Employee emp = EmployeeDAO.searchEmployee(empIdText.getText());

//Populate Employee on TableView and Display on TextArea

populateAndShowEmployee(emp);

} catch (SQLException e) {

e.printStackTrace();

resultArea.setText("Error occurred while getting employee information from DB.\n" + e);

throw e;

}

}

Page 44: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

44

//Search all employees

@FXML

private void searchEmployees(ActionEvent actionEvent) throws SQLException,

ClassNotFoundException {

try {

//Get all Employees information

ObservableList<Employee> empData = EmployeeDAO.searchEmployees();

//Populate Employees on TableView

populateEmployees(empData);

} catch (SQLException e){

System.out.println("Error occurred while getting employees information from DB.\n" + e);

throw e;

}

}

//Initializing the controller class.

//This method is automatically called after the fxml file has been loaded.

@FXML

private void initialize () {

/*

The setCellValueFactory(...) that we set on the table columns are used to determine

which field inside the Employee 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

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():

*/

empIdColumn.setCellValueFactory(cellData ->

cellData.getValue().employeeIdProperty().asObject());

Page 45: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

45

empNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());

empLastNameColumn.setCellValueFactory(cellData -> cellData.getValue().lastNameProperty());

empEmailColumn.setCellValueFactory(cellData -> cellData.getValue().emailProperty());

empPhoneNumberColumn.setCellValueFactory(cellData ->

cellData.getValue().phoneNumberProperty());

empHireDateColumn.setCellValueFactory(cellData -> cellData.getValue().hireDateProperty());

}

//Populate Employee

@FXML

private void populateEmployee (Employee emp) throws ClassNotFoundException {

//Declare and ObservableList for table view

ObservableList<Employee> empData = FXCollections.observableArrayList();

//Add employee to the ObservableList

empData.add(emp);

//Set items to the employeeTable

employeeTable.setItems(empData);

}

//Set Employee information to Text Area

@FXML

private void setEmpInfoToTextArea ( Employee emp) {

resultArea.setText("First Name: " + emp.getFirstName() + "\n" +

"Last Name: " + emp.getLastName());

}

//Populate Employee for TableView and Display Employee on TextArea

@FXML

private void populateAndShowEmployee(Employee emp) throws ClassNotFoundException {

if (emp != null) {

populateEmployee(emp);

Page 46: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

46

setEmpInfoToTextArea(emp);

} else {

resultArea.setText("This employee does not exist!\n");

}

}

//Populate Employees for TableView

@FXML

private void populateEmployees (ObservableList<Employee> empData) throws

ClassNotFoundException {

//Set items to the employeeTable

employeeTable.setItems(empData);

}

//Update employee's email with the email which is written on newEmailText field

@FXML

private void updateEmployeeEmail (ActionEvent actionEvent) throws SQLException,

ClassNotFoundException {

try {

EmployeeDAO.updateEmpEmail(empIdText.getText(),newEmailText.getText());

resultArea.setText("Email has been updated for, employee id: " + empIdText.getText() + "\n");

} catch (SQLException e) {

resultArea.setText("Problem occurred while updating email: " + e);

}

}

//Insert an employee to the DB

@FXML

private void insertEmployee (ActionEvent actionEvent) throws SQLException,

ClassNotFoundException {

try {

EmployeeDAO.insertEmp(nameText.getText(),surnameText.getText(),emailText.getText());

Page 47: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

47

resultArea.setText("Employee inserted! \n");

} catch (SQLException e) {

resultArea.setText("Problem occurred while inserting employee " + e);

throw e;

}

}

//Delete an employee with a given employee Id from DB

@FXML

private void deleteEmployee (ActionEvent actionEvent) throws SQLException,

ClassNotFoundException {

try {

EmployeeDAO.deleteEmpWithId(empIdText.getText());

resultArea.setText("Employee deleted! Employee id: " + empIdText.getText() + "\n");

} catch (SQLException e) {

resultArea.setText("Problem occurred while deleting employee " + e);

throw e;

}

}

}

Main Class

At the end of the first JavaFX article, I described details of the main method. In here, I want

to explain it briefly. It starts the primary stage, sets its title, initializes the root layout and then

displays the “employee view”.

Main Class Code:

package sample;

import javafx.application.Application;

import javafx.fxml.FXMLLoader;

import javafx.scene.Scene;

import javafx.scene.layout.AnchorPane;

import javafx.scene.layout.BorderPane;

Page 48: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

48

import javafx.stage.Stage;

import java.io.IOException;

//Main class which extends from Application Class

public class Main extends Application {

//This is our PrimaryStage (It contains everything)

private Stage primaryStage;

//This is the BorderPane of RootLayout

private BorderPane rootLayout;

@Override

public void start(Stage primaryStage) {

//1) Declare a primary stage (Everything will be on this stage)

this.primaryStage = primaryStage;

//Optional: Set a title for primary stage

this.primaryStage.setTitle("SW Test Academy - Sample JavaFX App");

//2) Initialize RootLayout

initRootLayout();

//3) Display the EmployeeOperations View

showEmployeeView();

}

//Initializes the root layout.

public void initRootLayout() {

try {

Page 49: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

49

//First, load root layout from RootLayout.fxml

FXMLLoader loader = new FXMLLoader();

loader.setLocation(Main.class.getResource("view/RootLayout.fxml"));

rootLayout = (BorderPane) loader.load();

//Second, show the scene containing the root layout.

Scene scene = new Scene(rootLayout); //We are sending rootLayout to the Scene.

primaryStage.setScene(scene); //Set the scene in primary stage.

/*//Give the controller access to the main.

RootLayoutController controller = loader.getController();

controller.setMain(this);*/

//Third, show the primary stage

primaryStage.show(); //Display the primary stage

} catch (IOException e) {

e.printStackTrace();

}

}

//Shows the employee operations view inside the root layout.

public void showEmployeeView() {

try {

//First, load EmployeeView from EmployeeView.fxml

FXMLLoader loader = new FXMLLoader();

loader.setLocation(Main.class.getResource("view/EmployeeView.fxml"));

AnchorPane employeeOperationsView = (AnchorPane) loader.load();

// Set Employee Operations view into the center of root layout.

rootLayout.setCenter(employeeOperationsView);

} catch (IOException e) {

Page 50: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

50

e.printStackTrace();

}

}

public static void main(String[fusion_builder_container hundred_percent="yes"

overflow="visible"][fusion_builder_row][fusion_builder_column type="1_1"

background_position="left top" background_color="" border_size="" border_color=""

border_style="solid" spacing="yes" background_image="" background_repeat="no-repeat"

padding="" margin_top="0px" margin_bottom="0px" class="" id="" animation_type=""

animation_speed="0.3" animation_direction="left" hide_on_mobile="no" center_content="no"

min_height="none"][] args) {

launch(args);

}

}

We finished coding. It is time to run the code.

The result of the program is shown below.

Page 51: Getting Started with JavaFX + Database Operations Started with JavaFX + Database Operations When I started to work in my current position, one of my task is to do manual operations

51

Github: https://github.com/swtestacademy/javafxexample

The End