Developing an Enterprise Application with JavaFX 2.0 and Java EE 7
Overview
Purpose
This tutorial covers how to build an enterprise application client with JavaFX 2.0 and JavaFX Scene Builder. It also covers how to build a RESTful web service that provides data to the enterprise application. The client application uses the JAX-RS 2.0 Client and the Java API for JSON Processing, both new APIs in Java Platform, Enterprise Edition 7 (Java EE 7).Time to Complete
Approximately 90 minutes
Introduction
JavaFX is a front-end tool that allows developers to create rich
internet applications (RIAs). JavaFX is designed to provide a
lightweight, hardware-accelerated platform for enterprise
applications that allows developers to build their applications
entirely in the Java language.
In this tutorial, you perform the following to create a JavaFX
application:
On the server side:
- Create a RESTful web service to extract data from a DB and
publish it through the web service. To do this, you create the
web service, an entity
Customer
, and an Enterprise JavaBeans (EJB)CustomerFacade
class to retrieve data from the DB. - Run the web service locally.
On the client side:
- Create the application UI by using JavaFX Scene Builder.
- Create the business logic by creating classes like the
Customer
class, theCustomerMessageBodyReader
class (which parses JSON data from the web service by using the new Java API for JSON Processing), and theSampleController
class (which uses the new JAX-RS 2.0 Client API to communicate with the web service).
Hardware and Software Requirements
The following is a list of hardware and software requirements:
- Download and install the latest JDK from this link.
- Download and install JavaFX Scene Builder from this link. The version used in this tutorial is 1.1.
- Download and install NetBeans 7.3.1 with Java EE 7, which includes GlassFish 4.0, from this link. During installation, be sure to select the check box to install GlassFish. JUnit is an optional installation and is not required for this tutorial.
Prerequisites
Before starting this tutorial, you should:
- Have installed the required software.
- Ensure that NetBeans is running.
Creating the RESTful Web Service
In this section, you create a RESTful web service that provides data to the enterprise application client.
Creating the Project
-
In NetBeans, select File > New Project.
-
In the New Project dialog box, perform the following steps on the Choose Project page:
- Select Java Web from Categories.
- Select Web Application from Projects.
- Click Next.
-
On the Name and Location page, enter ServerSide as the project name and click Next.
-
On the Server and Settings page, click Finish.
The ServerSide
project is created in NetBeans.
Creating the Entity Class
Customers
table, which is a table in the default database schema in
NetBeans.
-
Right-click the
Source Packages
folder and select New > Other. -
In the New File dialog box, perform the following steps on the Choose File Type page:
- Select Persistence from Categories.
- Select Entity Classes from Database from File Types.
- Click Next.
-
In the New Entity Classes from Database dialog box, perform the following steps on the Database Tables page:
- Select jdbc/sample from Data Source.
- Select CUSTOMER table from Available Tables and move it to Selected Tables.
- Deselect the Include Related Tables check box.
- Click Next.
-
In the New Entity Classes from Database dialog box, perform the following steps on the Entity Classes page:
- Enter com.samples.entity as the package name.
- Make sure that the Generate Named Query Annotations for Persistent Fields check box and the Generate JAXB Annotations check box are not selected.
- Click Finish.
The Customer.java
entity class is created under
the com.samples.entity
folder.
Creating the RESTful Web Service
CUSTOMER
table in JSON format.
-
Right-click the project and select New > Other.
-
In the New File dialog box, perform the following steps on the Choose File Type page:
- Select Web Services from Categories.
- Select RESTful Web Services from Patterns from File Types.
- Click Next.
-
In the New RESTful Web Services from Patterns dialog box, click Next on the Select Pattern page.
-
Perform the following steps on the Specify Resource Classes page:
- Enter com.samples.rest as the resource package name.
- Enter customer as the path.
- Enter CustomerREST as the class name.
- Select application/json from MIME Type.
- Click Finish.
NetBeans creates the
CustomerREST
andApplicationConfig
classes under thecom.samples.rest
folder. -
In the
CustomerREST
class, enter the following lines of code:@RequestScoped @Inject private CustomerFacade customerFacade;
-
Press Ctrl + Shift + I to solve imports. Be sure to select
javax.enterprise.context.RequestScoped
if import options are listed forRequestScoped
.
TheCustomerFacade
class is not resolved until the class is created. -
In the same
CustomerREST
class, update thegetJson
method as follows:@GET @Produces({"application/json"}) public List<Customer> getJson() { return customerFacade.findAll(); }
-
In the same
CustomerREST
class, add thefindByName
method:@GET @Path("/search/{name}") @Produces({"application/json"}) public List<Customer> findByName(@PathParam("name") String name) { return customerFacade.findByName(name); }
-
Press Ctrl + Shift + I to solve imports.
-
Right-click the
com.samples.rest
folder and select New > Other. -
In the New File dialog box, perform the following steps on the Choose File Type page:
- Select Enterprise JavaBeans from Categories.
- Select Session Bean from File Types.
- Click Next.
-
In the New Session Bean dialog box, on the Name and Location page, enter CustomerFacade for EJB Name and click Finish.
NetBeans creates a stateless session bean. This bean is the interface between the DB and its operations.
-
Add the following code to the
CustomerFacade
class:@PersistenceContext(unitName = "ServerSidePU") private EntityManager em; public List<Customer> findAll() { return em.createQuery("select c from Customer c").getResultList(); } public List<Customer> findByName(String name) { return em.createQuery("select c from Customer c where UPPER(c.name) LIKE :custName"). setParameter("custName", "%" + name.toUpperCase() + "%").getResultList(); }
In this file, you create an
EntityManager
that is associated with a Persistent Context and a Persistent Unit (PU) namedServerSidePU
. The PU is defined in thepersistence.xml
file.
You also create two methods:findAll
andfindByName
. The first method returns data from theCustomer
table, and the second method returns only the names that match the name received. -
Press Ctrl + Shift + I to solve imports.
-
Right-click the project and select Run.
GlassFish runs and the project is deployed on Glassfish. NetBeans launches the default browser with the http://localhost:8080/ServerSide URL.
-
Enter the following address in the recently opened browser and then press Enter:
http://localhost:8080/ServerSide/webresources/customerWhen you call this URL, the
getJson()
method from theCustomerREST
class is invoked. -
Enter the following URL and then press Enter:
http://localhost:8080/ServerSide/webresources/customer/search/JohnWhen you call this URL, the
findByName()
method from theCustomerREST
class is invoked and sendsJohn
as a parameter.
Creating the Client Application with JavaFX
In this section, you create the search desktop application that displays the information delivered by the web service.
Creating the JavaFX Project
-
In NetBeans, select File > New Project.
-
In the New Project dialog box, perform the following steps on the Choose Project page:
- Select JavaFX from Categories.
- Select JavaFX FXML Application from Projects.
- Click Next.
-
In the New JavaFX Application dialog box, perform the following steps on the Name and Location page:
- Enter JavaFXApplicationCustomerSearch for Project Name.
- Enter CustomerSearch for FXML name.
- Click Finish.
-
Right-click the project that you just created and select Run.
The project compiles and executes and shows a window with a button. This is the application that is created by default:
NetBeans creates three files within the project:
CustomerSearch.fxml
, which is the user interface in FXML language;CustomerSearchController.java
, which is associated with the graphic elements of the FXML document and coordinates the behavior of these elements; and theJavaFXApplicationCustomerSearch.java
class, which is the entry point for the application: -
Open the
JavaFXApplicationCustomerSearch.java
file and add the following code:stage.setTitle("JavaFX Demo"); stage.setWidth(650); stage.setHeight(650);
Creating the User Interface
-
Right-click the
CustomerSearch.fxml
FXML file and select Open.NetBeans opens the file in Scene Builder showing the main pane (AnchorPane) with a Click Me! button on it.
-
In Scene Builder, perform the following steps:
- Click the AnchorPane.
- Press Ctrl + 8 to show the right panel.
- In the Layout section of the right panel, enter 620 in the Pref Width field and 600 in the Pref Height field.
- Press Enter.
-
Move the Click Me! button to the upper-right corner of the pane.
Hint: By pressing Ctrl + 8, you can hide and show the right panel; and Ctrl + 7 for the left panel.
-
Click the Click Me! button and then perform the following steps:
- In the Properties section of the right panel, enter Search in the Text field.
- Press Enter.
-
In the Code section, enter buttonSearch in the fx:id field and handleSearchAction in the On Action field.
-
Select and drag a Text Field element from the left panel to the upper-left corner of the AnchorPane.
-
Resize the text field to your preferred size.
-
Perform the following steps:
- Click the Text Field.
- In the Code section of the right panel, enter textFieldSearch in the fx:id field and handleSearchAction in the On Action field.
- Press Enter.
-
Select and drag a Table View element from the left panel to the AnchorPane.
-
In the AnchorPane, select the table view and drag its bottom right corner to adjust the table size.
-
Perform the following steps:
- Under
TableView
from the left panel, select and right-click anyTableColumn
. - Select Duplicate from the shortcut menu.
The table now has an extra column.
- Under
-
Resize the columns in the table by performing the following steps:
- Select the first
TableColumn
from the left panel. - Enter 170 in the Pref Width field, under the Layout section in the right panel.
- Press Enter.
- Repeat steps a, b, and c for the second and third columns, assigning them a width of 190 and 210, respectively.
- Select the first
-
Click the Table View in the pane and under the Code section from the right panel, enter tableView in the fx:id field.
-
Name the three
TableColumn
in the left panel by entering Name, Address, and Email, respectively. -
Press Ctrl + S to save the file. (You can also select File > Save). Disregard possible warnings.
-
Perform the following steps to manually add the
<cellValueFactory>
XML tag to each<TableColumn>
tag in theCustomerSearch.fxml
file:- Go to NetBeans.
- Right-click the
CustomerSearch.fxml
file. - Select Edit.
-
Perform the following steps:
-
Add the following code to the file:
<?import javafx.scene.control.cell.*?> <cellValueFactory> <PropertyValueFactory property="name" /> </cellValueFactory> <cellValueFactory> <PropertyValueFactory property="addressline1" /> </cellValueFactory> <cellValueFactory> <PropertyValueFactory property="email" /> </cellValueFactory>
- Remove the slash (/) from the
<TableColumn>
elements and add </TableColumn> instead (because<cellValueFactory>
is added as a child of<TableColumn>
. - Make sure that the import line goes under the
<xml>
tag.
The
<cellValueFactory>
element under<TableColumn>
binds the columns in the UI with the columns from theCustomer
table in the DB. -
Developing the Controller
CustomerSearchController.java
class, which instantiates the javax.ws.rs.client.Client
class to make RESTful web service calls.
-
From the following link, download the file, and extract the folder to your disk. The
lib
folder contains some Java EE 7 libraries, like the JAX-RS 2.0 Client. -
Right-click the
Libraries
folder and select Add JAR/Folder. -
Select all JARs in the lib folder and click Open.
-
In NetBeans, open the
CustomerSearchController.java
file and perform the following steps:- Replace the name of the
handleButtonAction
method with handleSearchAction. - Delete the input parameter from this method.
- Replace the name of the
-
Replace the existing code in the
handleSearchAction()
method with the following code:WebTarget clientTarget; ObservableList<Customer> data = tableView.getItems(); data.clear(); Client client = ClientBuilder.newClient(); client.register(CustomerMessageBodyReader.class); if (textFieldSearch.getText().length() > 0) { clientTarget = client.target("http://localhost:8080/ServerSide/webresources/customer/search/{beginBy}"); clientTarget = clientTarget.resolveTemplate("beginBy", textFieldSearch.getText()); } else { clientTarget = client.target("http://localhost:8080/ServerSide/webresources/customer"); } GenericType<List<Customer>> listc = new GenericType<List<Customer>>() { }; List<Customer> customers = clientTarget.request("application/json").get(listc); for (Customer c : customers) { data.add(c); System.out.println(c.toString()); }
-
Press Ctrl + Shift + I to solve imports. Some classes are not resolved until they are created.
-
In the same file, add the following lines of code:
@FXML private TextField textFieldSearch; @FXML private Button buttonSearch; @FXML private TableView<Customer> tableView;
-
Press Ctrl + Shift + I to solve imports. The
Customer
class is not resolved until the class is created. -
In the same
CustomerSearchController
class, add the following line of code to theinitialize
method:handleSearchAction();
The
CustomerSearchController
class contains two classes that are not yet defined:Customer
andCustomerMessageBodyReader
. You create these classes in the next section.
Creating the Parser with the Java API for JSON Processing
Customer
class
and the JSON parser by using the new Java API for JSON
processing in Java EE 7.
-
Right-click the
javafxapplicationcustomersearch
folder and select New > Java Class. -
In the New Java Class dialog box, on the Name and Location page, enter Customer for Class Name and click Finish.
-
In the
Customer.java
file, add the following code:import java.io.Serializable; implements Serializable private String name; private String addressline1; private String email;
-
Perform the following steps:
- Place your cursor after the variables declaration and press Alt + Insert to show the Insert Code window.
- Select Getter and Setter.
-
In the Generate Getters and Setters dialog box, select
addressline1 : String
,email : String
, andname : String
, and then click Generate. -
Save your file.
-
Right-click the
javafxapplicationcustomersearch
folder and select New > Java Class. -
In the New Java Class dialog box, on the Name and Location page, enter CustomerMessageBodyReader for Class Name and click Finish.
-
Enter the following code in the
CustomerMessageBodyReader
class:@Provider @Consumes({"application/json"}) implements MessageBodyReader<List<Customer>> @Override public boolean isReadable(Class<?> type, Type type1, Annotation[] antns, MediaType mt) { return true; }
-
Press Ctrl + Shift + I to fix imports. Be sure to select
java.lang.reflect.Type
for Type when import options are listed. -
Enter the following method code in the same
CustomerMessageBodyReader
class:@Override public List<Customer> readFrom(Class<List<Customer>> type, Type type1, Annotation[] antns, MediaType mt, MultivaluedMap<String, String> mm, InputStream in) throws IOException, WebApplicationException { if (mt.getType().equals("application") && mt.getSubtype().equals("json")) { Customer customer = new Customer(); List<Customer> customers = new ArrayList(); JsonParser parser = Json.createParser(in); while (parser.hasNext()) { JsonParser.Event event = parser.next(); switch (event) { case START_OBJECT: customer = new Customer(); break; case END_OBJECT: customers.add(customer); break; case KEY_NAME: String key = parser.getString(); parser.next(); switch (key) { case "name": customer.setName(parser.getString()); break; case "addressline1": customer.setAddressline1(parser.getString()); break; case "email": customer.setEmail(parser.getString()); break; default: break; } break; default: break; } } return customers; } throw new UnsupportedOperationException("Not supported MediaType: " + mt); }
-
Press Ctrl + Shift + I to fix imports.
-
Right-click the project and select Build.
Launching the Application
- Right-click the
JavaFXApplicationCustomerSearch.java
file. -
Select Run File.
The application launches and gets data from the RESTful web service. To search for data, enter a name in the text field and click the Search button.
Summary
In this tutorial, you learned to:
- Create a RESTful web service that gets data from a DB through a Facade class and by using JPA
- Create the application's UI by using JavaFX Scene Builder
- Create the application's business logic by using the JAX-RS 2.0 Client and JSON 1.0 APIs
- Link the application logic (controller) with the user interface (FXML)
Resources
Credits
- Curriculum Developer: Edgar Martinez
- Editor: Susan Moxley
- QA: Juan Quezada
To navigate this Oracle by Example tutorial, note the following:
- Topic List:
- Click a topic to navigate to that section.
- Expand All Topics:
- Click the button to show or hide the details for the sections. By default, all topics are collapsed.
- Hide All Images:
- Click the button to show or hide the screenshots. By default, all images are displayed.
- Print:
- Click the button to print the content. The content that is currently displayed or hidden is printed.
To navigate to a particular section in this tutorial, select the topic from the list.