13.3. Additional Practice ExercisesΒΆ

Section 13.1
  1. Look at the scene graph diagram provided in section 13.1.

    1. Identify the parent node of the Button.

    2. Explain what would happen visually if the ImageView were removed from the VBox.

    Solution
    1. The parent node of the Button is the HBox.

    2. If the ImageView were removed, only the HBox containing the TextField and Button would remain in the VBox. The app would still run, but no image would be displayed.

  2. Explain what it means to extend a JavaFX class to create a custom component. Give one real-world example of a custom UI component you might create.

    Solution

    Extending a JavaFX class means creating your own class that inherits functionality from an existing control (e.g., HBox, Button, Pane) and customizing behavior or appearance. Example: A SearchBar component that includes a TextField and a search Button bundled together with built-in event handling.

  3. Suppose clicking the Button does not update the ImageView. Suggest two debugging strategies.

    Solution
    • Print debug messages to check if the event handler is triggered.

    • Verify the image URL or file path is valid and supported (check for exceptions).

    • Optionally add logging to ensure the ImageView reference is assigned properly.

  4. The user provides a URL in the TextField, but the program crashes when an unsupported file type is entered.

    1. What exception might be thrown?

    2. How would you handle this gracefully?

    Solution
    1. Likely a IllegalArgumentException or a runtime loading error from new Image(url).

    2. Use a try-catch block and provide user feedback through JavaFX, such as a Label or an Alert dialog.

  5. Propose one improvement to the GUI that would help users. Explain why it improves usability.

    Solution

    Answers may vary:

    • Add prompt text in the TextField so users know to enter an image URL.

    • Display error messages if loading fails.

    • Add a default image to avoid a blank screen on launch.

Section 13.2

Based on section 13.2, answer the following review questions.

  1. Refer to the original and refactored scene graphs shown in the text.

    1. In the refactored scene graph (where the two lower VBox sub-graphs were replaced), what is the parent node of the two ImageLoader components?

    2. In the original scene graph, what node type is the root of the repeating sub-graph that we want to encapsulate inside ImageLoader?

    Solution
    1. The parent node of the two ImageLoader components is the root HBox (the top-level HBox that contains the two ImageLoader instances).

    2. The root of the repeating sub-graph is a VBox (it contains an HBox and an ImageView as children).

  2. Explain, in two or three sentences, why creating an ImageLoader custom component is preferable.

    Solution

    Creating an ImageLoader reduces redundancy and centralizes behavior and layout. It makes the code easier to maintain, promotes reuse, and hides implementation details so the top-level ImageApp stays small and focused on composition rather than construction.

  3. List which instance variables should be moved into the ImageLoader class (name the node types), and state what to do with the static constants originally in ImageApp (visibility and placement).

    Solution

    Instance variables to move into ImageLoader: HBox urlLayer, TextField urlField, Button loadButton, and ImageView imgView (or similarly named variables representing those nodes). Static constants from ImageApp (e.g., default image URL, preferred sizes) should be copied into ImageLoader (or placed in a shared package-level class) and made protected static if other classes in the same package need access. This keeps constants accessible while reducing coupling.

  4. Section 13.2 suggests moving the loadImage method from ImageApp into ImageLoader. Describe two things you must remember to do after moving the method so that clicking the Button still works.

    Solution
    1. Set the button's event handler inside ImageLoader (for example, loadButton.setOnAction(e -> loadImage());) so the handler references the ImageLoader's fields (urlField, imgView).

    2. Ensure loadImage is either an instance method of ImageLoader (not static) and that it uses the instance variables urlField.getText() and imgView directly. Also handle exceptions locally (e.g., try-catch) to provide user feedback.