Getting Started With Javafx Database Operations
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.
1
Type “First_JavaFX_Project” as Project name and set your Project Location as you want
and click Finish button.
2
Thanks to IntelliJ, it automatically creates a JavaFX project structure and put a sample
Hello World code into Main class.
3
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.
4
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.
5
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.
6
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.
7
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.
8
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.
9
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.
10
RootLayout’s final design is shown below.
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
11
@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;
12
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;
@Override
public void start(Stage primaryStage) {
//1) Declare a primary stage (Everything will be on this stage)
this.primaryStage = primaryStage;
13
primaryStage.setScene(scene); //Set the scene in primary stage.
loader.setLocation(Main.class.getResource("view/EmployeeOperations.fxml"));
AnchorPane employeeOperationsView = (AnchorPane) loader.load();
Result:
14
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.
15
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.
16
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/
17
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.
18
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.
19
3) Write “odjbc” on search bar and enter. Then, select the “oracle:ojdbc6:11.2.0.3” and
select sources and JavaDocs click OK.
20
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.
21
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
22
try {
Class.forName(JDBC_DRIVER);
} catch (ClassNotFoundException e) {
System.out.println("Where is your Oracle JDBC Driver?");
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;
}
}
23
//Create statement
stmt = conn.createStatement();
//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;
}
24
} 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();
}
}
}
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.
import javafx.beans.property.*;
import java.sql.Date;
25
/**
*/
//Constructor
public Employee() {
26
}
//employee_id
return employee_id.get();
this.employee_id.set(employeeId);
return employee_id;
//first_name
return first_name.get();
this.first_name.set(firstName);
return first_name;
//last_name
return last_name.get();
27
}
this.last_name.set(lastName);
return last_name;
return email.get();
this.email.set(email);
return email;
//phone_number
return phone_number.get();
this.phone_number.set(phoneNumber);
28
public StringProperty phoneNumberProperty() {
return phone_number;
//hire_date
return hire_date.get();
this.hire_date.set(hireDate);
return hire_date;
//job_id
return job_id.get();
this.job_id.set(jobId);
return job_id;
29
//salary
return salary.get();
this.salary.set(salary);
return salary;
//commission_pct
return commission_pct.get();
this.commission_pct.set(commissionPct);
return commission_pct;
//manager_id
return manager_id.get();
30
public void setManagerId(int managerId){
this.manager_id.set(managerId);
return manager_id;
//department_id
return department_id.get();
this.manager_id.set(departmentId);
return department_id;
31
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;
//*******************************
//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;
32
//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";
33
//Send ResultSet to the getEmployeeList method and get employee object
ObservableList<Employee> empList = getEmployeeList(rsEmps);
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;
34
}
//*************************************
//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;";
//*************************************
//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;";
35
//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;";
RootLayout FXML
36
RootLayout contains a border pane and menu items. We need to bind it with
RootLayoutController class.
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?>
37
<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.
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
38
<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" />
39
<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;
System.exit(0);
alert.setTitle("Program Information");
40
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());
41
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;
/**
*/
@FXML
@FXML
@FXML
@FXML
@FXML
@FXML
42
private TextField emailText;
@FXML
@FXML
@FXML
@FXML
@FXML
@FXML
@FXML
//Search an employee
@FXML
try {
populateAndShowEmployee(emp);
} catch (SQLException e) {
e.printStackTrace();
throw e;
43
//Search all employees
@FXML
try {
populateEmployees(empData);
throw e;
//This method is automatically called after the fxml file has been loaded.
@FXML
/*
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.
We're only using StringProperty values for our table columns in this example.
*/
empIdColumn.setCellValueFactory(cellData ->
cellData.getValue().employeeIdProperty().asObject());
44
empNameColumn.setCellValueFactory(cellData -> cellData.getValue().firstNameProperty());
empPhoneNumberColumn.setCellValueFactory(cellData ->
cellData.getValue().phoneNumberProperty());
//Populate Employee
@FXML
empData.add(emp);
employeeTable.setItems(empData);
@FXML
@FXML
if (emp != null) {
populateEmployee(emp);
45
setEmpInfoToTextArea(emp);
} else {
@FXML
employeeTable.setItems(empData);
//Update employee's email with the email which is written on newEmailText field
@FXML
try {
EmployeeDAO.updateEmpEmail(empIdText.getText(),newEmailText.getText());
resultArea.setText("Email has been updated for, employee id: " + empIdText.getText() + "\n");
} catch (SQLException e) {
@FXML
try {
EmployeeDAO.insertEmp(nameText.getText(),surnameText.getText(),emailText.getText());
46
resultArea.setText("Employee inserted! \n");
} catch (SQLException e) {
throw e;
@FXML
try {
EmployeeDAO.deleteEmpWithId(empIdText.getText());
} catch (SQLException 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;
47
import javafx.stage.Stage;
import java.io.IOException;
@Override
this.primaryStage = primaryStage;
initRootLayout();
showEmployeeView();
try {
48
//First, load root layout from RootLayout.fxml
loader.setLocation(Main.class.getResource("view/RootLayout.fxml"));
Scene scene = new Scene(rootLayout); //We are sending rootLayout to the Scene.
controller.setMain(this);*/
} catch (IOException e) {
e.printStackTrace();
try {
loader.setLocation(Main.class.getResource("view/EmployeeView.fxml"));
rootLayout.setCenter(employeeOperationsView);
} catch (IOException e) {
49
e.printStackTrace();
launch(args);
50
Github: https://github.com/swtestacademy/javafxexample
The End
51