Project Architecture Overview

The Jukebox project follows a clean Model-View-Controller (MVC) pattern, which is a common architectural pattern in software development. This pattern separates the application into three interconnected components:

MVC Pattern:
  • Model: Manages data, logic, and rules of the application
  • View: Handles the display and user interface
  • Controller: Acts as an intermediary between Model and View, handling user input

Architecture Diagram

┌─────────────────────────────────────────────────────────────────┐
│                        JUKEBOX APPLICATION                                │
├─────────────────────────────────────────────────────────────────┤
│                                                                     │
│  ┌─────────────────┐    ┌─────────────────┐    ┌─────────────┐ │
│  │      MODEL       │    │     CONTROLLER   │    │     VIEW    │ │
│  │  (Data Classes)  │◄──►│ (Controller Classes)│◄──►│  (FXML Files)│ │
│  └─────────────────┘    └─────────────────┘    └─────────────┘ │
│           │                        │                        │            │
│           ▼                        ▼                        ▼            │
│  ┌─────────────────┐    ┌─────────────────┐    ┌─────────────┐ │
│  │  Database.java   │    │ ApplicationWindow│    │ application-│ │
│  │  Album.java      │    │ Controller.java  │    │ window.fxml │ │
│  │  Song.java       │    │ AdminPanelController│   │             │ │
│  │  User.java       │    │ ChooseAlbumController│ └─────────────┘ │
│  │  Genre.java      │    │ PlayAlbumController│                    │
│  └─────────────────┘    │ HomeScreenController│                    │
│                          └─────────────────┘                    │
│                                                                     │
└─────────────────────────────────────────────────────────────────┘

Component Breakdown

1. Model Layer

The Model layer contains the data classes that represent the application's information. These are pure Java classes with no dependencies on JavaFX.

Key Model Concept:

The Database class is a singleton-like object that holds all application data. It's created once in Jukebox.main() and stored in a static field for access throughout the application. This makes it easy to share data between different parts of the program.

2. View Layer

The View layer consists of FXML files that define the user interface declaratively (using XML). Each FXML file corresponds to a screen or component in the application.

FXML Benefits:
  • Separates UI design from logic
  • Declarative syntax is easier to read and maintain
  • Can be designed visually with tools like Scene Builder
  • Automatically connects to controller classes

3. Controller Layer

The Controller layer contains Java classes that handle user interactions, manage the view lifecycle, and coordinate with the Model.

Controller Communication:

In the Jukebox project, controllers communicate through static fields in the Jukebox class. Each controller has a static reference that can be accessed from anywhere:

// In Jukebox.java
public static ApplicationWindowController applicationWindowController;
public static ChooseAlbumController chooseAlbumController;
public static PlayAlbumController playAlbumController;
public static HomeScreenController homeScreenController;
public static AdminPanelController adminPanelController;
public static Database database;
public static Album selectedAlbum;

Application Flow

Here's how the application starts and flows between views:

  • Application Startup

    1. Jukebox.main() is called when you run the program
    2. It creates a new Database instance and calls loadData() to load saved data from database.json
    3. It calls launch(args) which starts the JavaFX runtime
  • JavaFX Initialization

    1. JavaFX calls Jukebox.start(Stage stage)
    2. start() creates the main view by calling ApplicationWindowController.createViewInstance()
    3. A Scene is created with the view as the root node
    4. The scene is set on the primary stage and the window is shown
  • View Initialization

    1. ApplicationWindowController.createViewInstance() loads application-window.fxml
    2. The initialize() method is called automatically
    3. All child views (Home, Choose Album, Play Album, Admin) are created and cached
    4. The home view is displayed as the initial screen
  • View Navigation

    When a user clicks a button to navigate:

    1. An event handler in the current controller is called (e.g., onHomeButtonClicked)
    2. If coming from Admin Panel, data is auto-saved via database.saveData()
    3. The ApplicationWindowController clears the container and adds the new view
    4. For Play Album view, the controller is re-initialized to load current album data
  • Navigation Flow Diagram

                       ┌─────────────────┐
                       │   HOME SCREEN   │
                       └────────┬────────┘
                                │
              ┌─────────────────┼─────────────────┐
              ▼                 ▼                 ▼
    ┌─────────────────┐ ┌─────────────┐ ┌─────────────┐
    │ PLAY MODE        │ │ ADMIN MODE  │ │ (other views)│
    │ (Choose Album)   │ │ (Admin Panel)│ │              │
    └────────┬────────┘ └────────┬────┘ └─────────────┘
             │                  │
             ▼                  ▼
    ┌─────────────────┐ ┌─────────────┐
    │ PLAY ALBUM      │ │ (saves data  │
    │ (Song list)     │ │  on exit)    │
    └─────────────────┘ └─────────────┘
             │                  │
             └────────┬─────────┘
                      ▼
               ┌──────────────┐
               │ HOME SCREEN   │
               │ (via GO HOME) │
               └──────────────┘
    Single Window Architecture:

    The Jukebox uses a single window with a container-based view switching system. Instead of creating multiple windows, different views are added and removed from the same container (VBox with fx:id="container"). This provides a more consistent user experience and is easier to manage.

    Data Flow

    Understanding how data moves through the application is crucial:

  • Data Loading

    1. When the application starts, Database.loadData() reads from database.json
    2. Gson deserializes the JSON into a Database object
    3. The Database object is stored in Jukebox.database for global access
  • Data Display

    1. Controllers access data from Jukebox.database
    2. For example, AdminPanelController.initialize() creates an ObservableList from Jukebox.database.albums
    3. The ListView automatically displays the contents of the ObservableList
  • Data Modification

    1. When a user adds, edits, or deletes items, the changes are made directly to the objects in Jukebox.database
    2. For ObservableLists, changes automatically update the UI
    3. For non-Observable collections, refresh() is called to update the display
  • Data Saving

    1. Data is saved in several scenarios:
    2. Manual Save: Clicking "Save All" in Admin Panel calls database.saveData()
    3. Auto-Save on Navigation: When leaving Admin Panel, ApplicationWindowController automatically saves
    4. Database.saveData() uses Gson to serialize the entire Database object to JSON
  • Key Architectural Decisions

    Why Static References?

    In a small to medium-sized application like Jukebox, static references provide a simple way for controllers to communicate. Benefits:

    • Easy to access from anywhere
    • No complex dependency injection framework needed
    • Simple to understand for beginners

    Trade-off: This approach can make testing more difficult and isn't ideal for very large applications. For production applications, consider using dependency injection or event buses.

    Why FXML?

    FXML provides several advantages:

    • Separation of UI design from business logic
    • Can be edited with visual tools (Scene Builder)
    • Easier to maintain and modify UI without touching code
    • Supports CSS styling
    Why Single Window?

    Using a single window with view switching:

    • Provides consistent user experience
    • Easier to manage state and navigation
    • Better performance (views are cached and reused)
    • Simpler window management
    Why Gson?

    Gson was chosen for persistence because:

    • Simple API - easy for beginners to understand
    • No configuration needed - just add the JAR file
    • Automatically handles complex object graphs
    • Human-readable JSON output

    Summary

    The Jukebox project demonstrates a well-structured JavaFX application using:

    Understanding this architecture will help you as you explore the individual cookbook sections, as each section builds on these foundational concepts.