12.7. Additional Practice Exercises

Question 1

What is the purpose of extending javafx.application.Application when creating a JavaFX app?

Solution

Extending javafx.application.Application allows the class to inherit the JavaFX application life cycle methods, such as init(), start(Stage), and stop(). It enables the class to be recognized as a JavaFX application and run within the JavaFX runtime.

Question 2

Why must the start method be overridden in a JavaFX application subclass?

Solution

The start method is declared as abstract in the Application class. Overriding it is mandatory because it defines the main entry point for the JavaFX application where the primary stage (window) is set up and displayed.

Question 3

Examine the ExampleDriver.java main method in section 12.3. What does Application.launch(ExampleApp.class, args) do? Why do we pass the class type?

Solution

Application.launch starts the JavaFX application life cycle for the specified class. Passing the class type allows the JavaFX runtime to construct an instance of ExampleApp and invoke its life cycle methods (init(), start(Stage), stop()).

Question 4

Why is a try-catch block used around the Application.launch method in the driver class?

Solution

The try-catch block ensures that any exceptions propagated to the main method are caught and handled gracefully. It provides helpful debugging information, including stack traces, and informs the user of potential DISPLAY/X-forwarding issues.

Question 5

Summarize the steps of the JavaFX application life cycle in the order they occur.

Solution
  1. Construct an instance of the specified Application subclass by calling its constructor.

  2. Call the init() method (if overridden).

  3. Create a Stage object and call the start(Stage) method with it.

  4. Wait for the application to finish (either by calling Platform.exit() or closing the last window when implicitExit is true).

  5. Call the stop() method (if overridden).

Question 6

Write a minimal JavaFX application that prints “Hello, JavaFX!” to the console and opens an empty window. Identify where each life cycle method is called.

Solution
 import javafx.application.Application;
 import javafx.stage.Stage;

 public class HelloJavaFX extends Application {

     @Override
     public void init() {
         System.out.println("init() called");
     }

     @Override
     public void start(Stage primaryStage) {
         System.out.println("start() called");
         primaryStage.setTitle("Hello JavaFX Window");
         primaryStage.show();
         System.out.println("Hello, JavaFX!");
     }

     @Override
     public void stop() {
         System.out.println("stop() called");
     }
}
Question 7

Why is the start method considered the main entry point for a JavaFX application?

Solution

The start method is called after the init method has completed and the system is ready for the app to run. It is where the primary Stage is initialized and the main GUI setup occurs, making it the main entry point for interacting with the user interface.

Question 8

The start method receives a Stage object as its parameter. Why does JavaFX pass this stage instead of letting the app create it?

Solution

The primary Stage is constructed by the JavaFX runtime during the application life cycle. Passing it to the start method ensures that the app has a reference to the main window without needing to construct it, maintaining a controlled life cycle and avoiding conflicts with the JavaFX platform.

Question 9

In ExampleApp, the root of the scene graph is an HBox. What would happen if you replaced it with a VBox? How would it affect the layout?

Solution

Replacing HBox with VBox changes the layout direction from horizontal to vertical. Children nodes would now be stacked vertically instead of side-by-side.

Question 10

What is the role of an "EventHandler" in a JavaFX application? How does it relate to the events generated by nodes like a Button?

Solution

An "EventHandler" is responsible for responding to specific events generated by nodes (such as mouse clicks, key presses, or actions). When a node like a Button generates an ActionEvent, the registered handler executes its handle method to define what happens in response to that event.

Question 11

The text mentions that EventHandler<T> is a functional interface. What does this mean, and why does it allow us to use a lambda expression?

Solution

A functional interface has exactly one abstract method—in this case, handle(T event). Because of that, Java allows it to be implemented using a lambda expression instead of creating an anonymous inner class.

Question 12

If you create a Button object but do not add it to the scene graph using root.getChildren().add(button), what will happen when the program runs?

Solution

The button will not be visible in the application's GUI. In JavaFX, a node must be added to the scene graph to be displayed on the screen.

Question 13

In the code

EventHandler<ActionEvent> buttonHandler = event -> System.out.println("you clicked me!");

what does the lambda expression event -> ... represent?

Solution

The lambda expression represents the implementation of the handle method of the EventHandler<ActionEvent> interface. The parameter event refers to the ActionEvent object generated when the button is clicked.

Question 14

Why must we call button.setOnAction(buttonHandler) after defining the event handler object?

Solution

Because creating the handler only defines what should happen when the event occurs—it doesn’t attach it to any node. The setOnAction method registers the handler with the button so it can respond to user clicks.

Question 15

The method signature of setOnAction is public final void setOnAction(EventHandler<ActionEvent> value). What does the generic type <ActionEvent> indicate here?

Solution

It specifies that the handler is meant to handle ActionEvent objects, which are the events generated when the user interacts with a button (e.g., clicking it). It ensures type safety by allowing only handlers compatible with ActionEvent.

Question 16

After adding the button and running the program, you see it but nothing happens when clicked. What are two possible reasons for this?

Solution
  1. The event handler was not registered using button.setOnAction(buttonHandler).

  2. The handler code does not include a visible or logged action (e.g., it prints to a console that isn't visible).