OOP Lab05 JavaFX&ExeptionHandling
OOP Lab05 JavaFX&ExeptionHandling
0 Assignment Submission
For this lab class, you will have to turn in your work before 23h59, 07/06/2026.
You should include your work on all sections of this lab, and push it to a branch called
“release/lab05” of the valid repository.
After completing all the exercises in the lab, you have to update the use case
diagram and the class diagram of the AIMS project.
Each student is expected to turn in his or her work and not give or receive unpermitted aid.
Otherwise, we would apply extreme methods for measurement to prevent cheating. Please write
down answers for all questions into a text file named “[Link]” and submit it within your
repository.
1
1.1 Install plugin for JavaFX
To work with JavaFX in Eclipse, you need to install some plugins. The most popular one is
e(fx)clipse.
- Open Eclipse, on the Menu bar, choose Help → Eclipse MarketPlace → search e(fx)clipse
and click Install.
- Follow the instructions and restart Workspace.
- Check after installation: After successful installation and restarting Eclipse, you can
check the result of the installation. In Eclipse select: File/New/Others... There are
Wizards which allow you to carry out JavaFX programming
2
1.3 Add JavaFX to Eclipse
In this part, you will create a user library for JavaFX in Eclipse.
- Open Eclipse, on the Menu bar, choose Window → Preferences → search User Libraries
→ New → Name it as “JavaFX”
- Click “Add External JARs” then navigate to the folder where you extracted JavaFX in the
previous step, choose the “lib” folder and add all .jar files. Click “Apply and Close”.
- Right-click on the project → Build Path → Configure Build Path → Classpath → Add
Library → User Library → JavaFX
3
Figure 2. Configure Eclipse to use Scene Builder (1)
4
Figure 4. Configure Eclipse to use Scene Builder (3)
5
3 JavaFX API
Note: For the exercises in this lab (excluding the AIMS exercises), you will continue to use the
GUIProject, and put all your source code in a package called
“[Link]” for DS & AI. You might need to add the JavaFX library to
this project if you are using the JDK version after 1.8.
Note: From this section onwards, it is assumed that you are a DS-AI student, so your folder
structure will contain the “dsai” package. If you are an HEDSPI or ICT student, you should
replace the “dsai” string with “hedspi” or “globalict”.
Recall the basic structure of a JavaFX application: It uses the metaphor of a theater to model the
graphics application. A stage (defined by the [Link] class) represents the
top-level container (window). The individual controls (or components) are contained in a scene
(defined by the [Link] class). An application can have more than one scene,
but only one of the scenes can be displayed on the stage at any given time. The contents of a
6
scene is represented in a hierarchical scene graph of nodes (defined by
[Link]).
Like any other JavaFX application, there are 3 steps for creating this Painter app as follows:
- Create the FXML file “[Link]” (we will be using Scene Builder)
- Create the controller class PainterController
- Create the application class Painter
The FXML file lays out the UI components in the scene graph. The controller adds interactivity
to these components by providing even-handling methods. Together, they complete the
construction of the scene graph. Finally, the application class creates a scene with the scene
graph and adds it to the stage.
7
Figure 8. Create a new FXML in Eclipse(1)
Name the file “Painter” and choose BorderPane as the root element as in Figure 4
A new file is created. Right-click on it in Project Explorer and select Open with SceneBuilder
8
Figure 10. Open FXML with SceneBuilder from Eclipse
For the right-side section, we use a regular Pane. On the other hand, for the left-side section,
since we want to arrange subsequent items below the previous ones vertically, we use a VBox
layout.
Step 1. Configuring the BorderPane – the root element of the scene
- We set the GridPane’s Pref Width and Pref Height properties to 640 and 480 respectively.
Recall that the stage’s size is determined based on the size of the root node in the FXML
document
- Set the BorderPane’s Padding property to 8 to insert it from the stage’s edges
9
Figure 12. Configuring the BorderPane
Figure 15. Configuring the Pane
11
● Change its text to “Clear” and set its Max Width property to MAX_VALUE so that it fills
the VBox’s width.
● Specify clearButtonPressed as the On Action event handler. This method will be
implemented in the controller.
Now that all the elements are set, you can preview them by selecting Preview > Show Preview in
Window
3.2 Create the controller class
In the same package as the FXML, create a Java class called PainterController. You can
also utilize Scene Builder for coding the controller as follows: Select View > Show Sample
Controller Skeleton. A window like in XXX will appear:
12
Figure 17. Auto-generated skeleton code for the controller
You can choose to copy the skeleton and paste it into your [Link] file.
Remember to replace the class name in the skeleton code with your actual class name
(PainterController). The results look roughly like this:
13
a dot) to the Pane at that same position. We do this by getting the Pane’s children list – which
is an ObservableList - and adding the UI object to the list.
For the clearButtonPressed() method, we simply need to clear all the Circle objects
on the Pane. Again, we have to access the Pane’s children list through
[Link]().
The source code for the controller is complete, however, to ensure that an object of the controller
class is created when the app loads the FXML file at runtime, you must specify the controller
class’s name in the FXML file using Scene Builder, in the lower right corner under Document
menu > Controller.
Figure 21. Specify the controller for the FXML file in Scene Builder
14
Figure 22. Painter source code
15
Figure 23. Choose another MouseEvent handling entry
Hint:
16
● For the interface design: use TitledPane and RadioButton. Using Scene Builder,
set the Toggle Group properties of the RadioButtons as identical, so only one of them can
be selected at a time.
● For the implementation of Eraser: One approach is to implement an eraser just like the
pen above, but use white ink color (canvas color) instead.
Figure 25. New packages for ICT class
17
5 Build View Store Screen for AIMS Customer Application with
JavaFX
5.1 Set up View Store Screen with Scene Builder
Like the previous exercise, we start by creating an FXML file named “[Link]” in the
package [Link] with VBox being the root node. The View Store Screen
contains two main parts:
● An Hbox contains a label AIMS and a button View Cart
● A ScrollPane contains GridPane to show all the items in the store
18
Figure 28. Structure of [Link] file
In this section, we will create the GUI components (i.e, the FXML file) only. The controller of
ViewStoreScreen will be implemented later.
5.1.1 Set up the VBox
- Properties:
▪ Alignment: CENTER
- Layout:
▪ Pref Width: 1024
▪ Pref Height: 768
▪ Padding: 20 Left
5.1.2 Set up the HBox
Step 1. Set up HBox Properties and Layout
- Properties:
▪ Alignment: CENTER
- Layout:
▪ Pref Height: 100
Step 2. Add a Label to the HBox
- Properties:
▪ Text: AIMS
▪ Font: 50px
▪ Text Fill: #004cff
- Layout:
▪ Padding: 10 Left
Step 3. Add a Region to the HBox
- Layout:
▪ Hgrow: ALWAYS
Step 3. Add a Button to the HBox
- Properties:
▪ Text: View Cart
- Layout:
▪ Margin: 20 Right
▪ Pref Width: 100
19
▪ Pref Height: 50
- Code:
▪ On Action: btnViewCartPressed
5.1.3 Set up the ScrollPane:
Step 1. Add a ScrollPane to the VBox, under the HBox
- Layout:
▪ Pref Width: 1024
▪ Pref Height: 760
Step 2. Add a GridPane to the ScrollPane
- Because the number of items in the store can be changed, therefore we will create a
dynamic GridPane that updates the view along with the change of the Store.
- Firstly, we will create an “empty” GridPane. Drag a GridPane to the ScrollPane. Delete
given rows and columns in the GridPane by right click on the row/column to be deleted,
choose Delete. The final dimension of the GridPane is (0 x 1).
Figure 29. Configure GridPane
- Set up Layout:
▪ Pref Width: 0
▪ Pref Height: 0
- Code:
▪ fx:id: gridPane
5.2 Set up Item in the Store
In the View Store Screen, we already created an empty GridPane. In this section, we will create
an FXML component to display the information of media and dynamically add it to the
GridPane.
5.2.1 Create [Link] file
In package [Link], create the [Link] file, choose the root node to be
AnchorPane.
The structure of this file is shown as below:
20
Figure 30. Structure of [Link] file
21
▪ Text: Add to Cart
- Layout:
▪ Pref Width: 305
▪ Pref Height: 50
- Code:
▪ fx:id: btnAddToCart
▪ On Action: btnAddToCartClicked
❖ Button 2:
- Properties:
▪ Text: Play
- Layout:
▪ Pref Width: 305
▪ Pref Height: 50
- Code:
▪ fx:id: btnPlay
▪ On Action: btnPlayClicked
5.2.2 Create ItemController class
The fxml file just contains the GUI, not the logic. You need to create a controller to implements
the behaviors of the FXML components.
22
5.3 Create ViewStoreController class
In the package [Link], create the ViewStoreController class.
Add all attributes and methods defined in the [Link] file to the Controller. You can copy the
Controller Skeleton from Scene Builder by select View > Show Sample Controller Skeleton.
Declare one attribute in the StoreManagerScreen class: Store store (because we need
information of the items in the store to display them) and and pass it to the constructor.
The GridPane we created in the section 5.1 is currently empty, we need to fill it with data of
media items in the store. In the initialize() method, we load the fxml file of each media
item to an FXML component (lines 35-40), set data for the item component (line 41) and add it
to the GridPane (line 48).
Explain initialize() method: The FXML controller can define an initialize() method,
which will be called once on an implementing controller when the contents of its associated
document have been completely loaded. In a few words: The constructor is called first, then any
@FXML annotated fields are populated, then initialize() is called.
23
5.4 Test View Store Screen
To test if our previouse code actually works, we will create a new package under the src pakcage
named: [Link], where program is
replaced by globalict or dsai.
24
6 Build Cart for AIMS Customer Application
6.1 Set up Cart Screen with Scene Builder
Similar to the View Store Screen, in package [Link], we will first create a
[Link] file with BorderPane being the root node. The Cart Screen has three distinct areas
(bounded in red borders) corresponding to TOP, CENTER and BOTTOM areas of BorderPane.
6.1.1 Set up the BorderPane:
- Layout:
▪ Pref Width: 1024
▪ Pref Height: 768
6.1.2 Set up the TOP area
We use the HBox layout for the TOP area to arrange components horizontally. The structure of
TOP area is shown as below:
25
Step 1. Drag a HBox into the BorderPane’s TOP area.
- Layout:
▪ Margin: 20 Left, 20 Right
▪ Pref Height: 100
Step 2. Add a Label to the HBox
- Properties:
▪ Text: CART
▪ Font: 50px
▪ Text Fill: #004cff
Step 3. Add a Region to the HBox
- Layout:
▪ Hgorw: ALWAYS
Step 4. Add a Button to the HBox
- Properties:
▪ Pref Width: 100
▪ Pref Height: 50
- Code:
▪ On Action: btnViewStorePressed
6.1.3 Setg up the CENTER area
For the CENTER area, we use the VBox layout to arrange components vertically. Inside the
Vbox, we use an HBox to arrange the top row of components horizontally. We also use a
TableView to display data in a tabular form. Below the TableView is another HBox containing
two buttons Play and Remove.
26
- Properties:
▪ Text: By ID
▪ Selected: ✔
▪ Toggle Group: filterCategory
Step 2.5. Add the second RadioButtons into the HBox
- Properties:
▪ Text: By Title
▪ Toggle Group: filterCategory
Step 3. Add a TableView into the VBox
- Set TableView’s fx:id property to tblMedia
- Add for TableColumns
▪ The Title column:
o Text: ID
o fx:id: colMediaId
▪ The Title column:
o Text: Title
o fx:id: colMediaTitle
▪ The Category column:
o Text: Category
o fx:id: colMediaCategory
▪ The Cost column:
o Text: Cost
o fx:id: colMediaCost
Step 4. Add another HBox below the TableView into the Vbox
Step 4.1. Set up the HBox
- Properties:
▪ Alignment: TOP_RIGHT
- Layout:
▪ Padding: 10 Top
▪ Spacing: 20
Step 4.2. Add button Play into the HBox
- Properties:
▪ Text: Play
- Layout:
▪ Pref Width: 60
- Code:
▪ fx:id: btnPlay
▪ On Action: btnPlayPressed
Step 4.3. Add button Remove into the HBox
- Properties:
▪ Text: Remove
- Layout:
▪ Pref Width: 60
- Code:
▪ fx:id: btnRemove
▪ On Action: btnRemovePressed
27
6.1.4 Setting up the BOTTOm area
Declare one attribute in the CartController class: Cart cart (because we need
information of the items in the cart to display them) and and pass it to the constructor.
28
Figure 39. Declaration of CartController class
In line 78, we set the cart’s list of items to the items of the TableView. Note that this will
initially cause an error, because we cannot set a regular List as the items of a TableView.
Instead, we have to use an ObservableList, so that any change in the data can be observed
and reflected by the TableView. Please open the source code of Cart and change the
itemsOrdered from List<Media> to ObservableList<Media>
After setting the items of the TableView, the data still isn’t showing up in the TableView
yet, because we still have to set up the way the columns can retrieve data. This is done by setting
the columns’ cellValueFactory.
In lines 69 – 76, we set the columns’ cellValueFactory using the class
PropertyValueFactory<S, T> (Read the Javadocs for more details). This class is a
29
callback that will take in a String <property> and look for the method
get<property>() in the Source S class. If a method matching this pattern exists, the
value returned from this method is returned to the TableCell.
You can now test the Cart Screen with some media in your cart, the results will look roughly like
this:
30
Figure 43. Modified initialize() method
Put some code at the end of the initialize() method to add a ChangeListener to the
TableView’s selectedItem property (lines 83 – 88 in Figure 43). Here, we create an
anonymous inner class for the ChangeListener. All ChangeListeners must implement
the changed() method. Whenever a selected item in the TableView is changed, the method
changed() is called. Here, we check to make sure the newValue is not null (the user didn’t
just unselect) and call the updateButtonBar() method (Figure 44)
31
6.5 Deleting a media
Next, we will implement the event handling for the “Remove” button. Please add a method name
to the onAction property of the button in Scene Builder. You can refer to the event-handling code
below:
Note that we don’t need to invoke an update for the TableView because it can already observe
the changes through the ObservableList and update its display.
6.6 Filter items in cart – FilteredList
This exercise is optional (full credit can still be given for this lab without doing this exercise),
but you can do it for extra credit.
We will implement a filter that is re-applied every time the user makes a change in the filter text
field. To do this, again, we need references to the text field where the user inputs the filter string,
and the two radio buttons (to determine what criteria are being used to filter).
Similar to the above, please add the fx:id property for the components in SceneBuilder and create
three corresponding attributes in the controller:
- The TextField: tfFilter
- The RadioButton “By ID”: radioBtnFilterId
- The RadioButton “By Title”: radioBtnFilterTitle
At the end of the initialize() method, put some code to add a ChangeListener to the
TextField’s text property (illustrated in Figure 29):
The following code is used to switch from Store Screen to Cart Screen when user click on the
button View Cart in Store Screen:
32
Figure 47. Source code switch from Store Screen to Cart Screen
This code is placed in ViewStoreController class created earlier. Make sure that you add
the On Action property for the View Cart button.
Note: You may need to modify the ViewStoreController and CartController classes earlier
● In ViewStoreController, add Cart cart attribute and modify its constructor to pass
both Store store and Cart cart to the constructor.
● In CartController, add Store store attribute and modify its constructor to pass both
Store store and Cart cart to the constructor.
33
9 Check all the previous source codes to catch/handle/delegate
runtime exceptions
Review all methods, classes in AimsProject, catch/handle or delegate all exceptions if necessary.
The exception delegation mechanism is especially helpful for constructors so that no object is
created if there is any violation of the requirement/constraints.
Hint: In Aims Project, we can apply exception handling to validate data constraints such as
non-negative price, to validate policies like the restriction of the number of orders, and to handle
unexpected interactions, e.g., users try to remove an author while the author is not listed.
For example, the following piece of code illustrates how to control the number of items in the
cart with exception.
34
● At this point, you should output an error message using [Link]()
method and the PlayerException should be raised.
- The example of codes and results for the play() of DigitalVideoDisc are illustrated in
the following figures.
- Save your changes and make the same with the play() method of Track.
35
Figure 50. Sample code for method play() of CompactDisc
- You should modify the above source code so that if any track in a CD can’t play, it throws a
PlayerException exception.
36
Figure 51. Swing dialog showing error
37