# (DD01) Module: com.github.blaxk3.ui — Detailed Design [132 LOC]

## Module Overview

The `com.github.blaxk3.ui` module provides the Swing-based user interface for a currency conversion application. It is responsible for rendering the main window, collecting user input, fetching currency codes asynchronously, and enforcing numeric input constraints in the amount field.

The module is centered around two classes:

- `UI`, which builds the frame and all visible widgets, wires button actions, and triggers remote currency conversion requests.
- `NumericFilter`, which protects the amount input field from invalid characters and malformed decimal values.

Together, these classes form the presentation layer for the application and delegate rate lookup work to `com.github.blaxk3.api.CurrencyRateAPI`.

---

## Class: UI

### Class Summary

| Field | Value |
|-------|-------|
| FQN | `com.github.blaxk3.ui.UI` |
| Layer | Presentation / Swing UI |
| Methods | 6 |

`UI` is the main application window. It constructs the frame, arranges the input and output panels, populates currency dropdowns asynchronously, and attaches action listeners for converting, swapping, and clearing values.

### Method: UI()

#### 1. Role

This constructor initializes the application window and makes it visible immediately. It configures the icon, title, size, layout, close behavior, and placement, then adds the main panel returned by `panel()`.

#### 2. Processing Pattern

```mermaid
flowchart LR
A["UI constructor"] --> B["Set window icon"]
B --> C["Build main panel"]
C --> D["Configure frame properties"]
D --> E["Show window"]
```

#### 3. Parameter Analysis

| Parameter | Type | Purpose | Validation |
|-----------|------|---------|------------|
| None | - | Creates a fully configured application window | Uses `Objects.requireNonNull` for the icon resource |

#### 4. CRUD Operations / Called Services

| Service / Dependency | Operation | Purpose |
|----------------------|-----------|---------|
| Swing `JFrame` | C / U | Creates and configures the top-level window |
| Classpath resource `/icon/image/icon.png` | R | Loads the window icon |
| `panel()` | C | Builds and adds the UI content |

#### 5. Dependency Trace

| Caller | Entry Point | Notes |
|--------|-------------|-------|
| Application bootstrap | `new UI()` | This is the visible entry point for the desktop app |

#### 6. Per-Branch Detail Blocks

- Main path
  - Resolves the icon resource from the classpath.
  - Adds the constructed panel.
  - Applies fixed window properties and shows the frame.

---

### Method: panel()

#### 1. Role

This method assembles the full screen layout. It creates two stacked sub-panels: one for entering the source amount and source currency, and another for displaying the result, selecting the target currency, and exposing the action buttons.

#### 2. Processing Pattern

```mermaid
flowchart LR
A["panel"] --> B["Create root panel"]
B --> C["Create input row"]
C --> D["Add text field"]
D --> E["Add source currency combo box"]
E --> F["Create output row"]
F --> G["Add label"]
G --> H["Add target currency combo box"]
H --> I["Add action buttons"]
I --> J["Return frame panel"]
```

#### 3. Parameter Analysis

| Parameter | Type | Purpose | Validation |
|-----------|------|---------|------------|
| None | - | Builds the complete UI container | None |

#### 4. CRUD Operations / Called Services

| Service / Dependency | Operation | Purpose |
|----------------------|-----------|---------|
| `textField()` | C | Creates the numeric input field |
| `comboBox1()` | C | Creates the source currency selector |
| `label()` | C | Creates the output label |
| `comboBox2()` | C | Creates the target currency selector |
| `button()` | C | Creates the three action buttons |
| Swing `JPanel` / `BoxLayout` / `FlowLayout` | C / U | Builds the visual layout |

#### 5. Dependency Trace

| Caller | Entry Point | Notes |
|--------|-------------|-------|
| `UI()` | Constructor | The constructor inserts the panel into the frame |

#### 6. Per-Branch Detail Blocks

- Root panel branch
  - Creates the vertical container for the full form.
- Input row branch
  - Places the amount field and source currency combo box.
- Output row branch
  - Places the result label, target currency combo box, and buttons.

---

### Method: comboBox1()

#### 1. Role

This method creates the first currency dropdown used as the source currency selector. It also starts the background `CurrencyCode` worker so the list is filled asynchronously from the external rate service.

#### 2. Processing Pattern

```mermaid
flowchart LR
A["comboBox1"] --> B["Create JComboBox"]
B --> C["Set preferred size"]
C --> D["Start CurrencyCode worker"]
D --> E["Return combo box"]
```

#### 3. Parameter Analysis

| Parameter | Type | Purpose | Validation |
|-----------|------|---------|------------|
| None | - | Creates the source currency dropdown | None |

#### 4. CRUD Operations / Called Services

| Service / Dependency | Operation | Purpose |
|----------------------|-----------|---------|
| Swing `JComboBox` | C / U | Builds the dropdown widget |
| `CurrencyCode` worker | C | Loads currency codes in the background |
| `CurrencyRateAPI` indirectly | R | Currency codes are fetched by the worker |

#### 5. Dependency Trace

| Caller | Entry Point | Notes |
|--------|-------------|-------|
| `panel()` | UI construction | Adds the source currency selector to the first row |

#### 6. Per-Branch Detail Blocks

- Creation branch
  - Instantiates an empty combo box.
  - Sets its size so it fits the layout.
- Background-load branch
  - Starts asynchronous population of codes.

---

### Method: comboBox2()

#### 1. Role

This method creates the second currency dropdown used as the target currency selector. Like `comboBox1()`, it starts the background loader so the available currencies are populated without blocking the UI thread.

#### 2. Processing Pattern

```mermaid
flowchart LR
A["comboBox2"] --> B["Create JComboBox"]
B --> C["Set preferred size"]
C --> D["Start CurrencyCode worker"]
D --> E["Return combo box"]
```

#### 3. Parameter Analysis

| Parameter | Type | Purpose | Validation |
|-----------|------|---------|------------|
| None | - | Creates the target currency dropdown | None |

#### 4. CRUD Operations / Called Services

| Service / Dependency | Operation | Purpose |
|----------------------|-----------|---------|
| Swing `JComboBox` | C / U | Builds the dropdown widget |
| `CurrencyCode` worker | C | Loads currency codes in the background |
| `CurrencyRateAPI` indirectly | R | Currency codes are fetched by the worker |

#### 5. Dependency Trace

| Caller | Entry Point | Notes |
|--------|-------------|-------|
| `panel()` | UI construction | Adds the target currency selector to the second row |

#### 6. Per-Branch Detail Blocks

- Creation branch
  - Instantiates an empty combo box.
  - Sets its size so it fits the layout.
- Background-load branch
  - Starts asynchronous population of codes.

---

### Method: button()

#### 1. Role

This method creates and wires the three primary actions in the UI: convert, swap, and clear. The convert action validates the amount field, calls the exchange-rate service, and writes the formatted result into the label. The swap and clear actions update the current selections and reset the form state.

#### 2. Processing Pattern

```mermaid
flowchart LR
A["button"] --> B["Create buttons"]
B --> C["Set button sizes"]
C --> D["Attach convert action"]
C --> E["Attach swap action"]
C --> F["Attach clear action"]
D --> G["Validate amount"]
G --> H["Call CurrencyRateAPI.convert"]
H --> I["Format and display result"]
E --> J["Swap selected currencies"]
F --> K["Clear fields"]
```

#### 3. Parameter Analysis

| Parameter | Type | Purpose | Validation |
|-----------|------|---------|------------|
| None | - | Creates the action buttons and listeners | Checks that the amount is not empty or just `.` before conversion |

#### 4. CRUD Operations / Called Services

| Service / Dependency | Operation | Purpose |
|----------------------|-----------|---------|
| `CurrencyRateAPI.convert()` | R | Converts the entered amount between selected currencies |
| Swing `JOptionPane` | C | Displays validation error messages |
| Source `JComboBox` | R / U | Reads and updates the selected currency |
| Target `JComboBox` | R / U | Reads and updates the selected currency |
| Output `JLabel` | U | Displays the converted amount |
| Amount `JTextField` | R / U | Reads user input and clears it |

#### 5. Dependency Trace

| Caller | Entry Point | Notes |
|--------|-------------|-------|
| `panel()` | UI construction | Inserts the button array into the output row |
| User clicks button | Action listener | Each button listener is the runtime entry point |

#### 6. Per-Branch Detail Blocks

- Convert branch
  - Reads the current amount.
  - Rejects empty values and a lone decimal point.
  - Calls the external API service with selected currency codes.
  - Formats and displays the response.
  - Exception path
    - Wraps URL and URI failures in a runtime exception.
- Swap branch
  - Stores the source selection.
  - Exchanges the selected items between the two combo boxes.
- Clear branch
  - Clears the amount field.
  - Clears the result label.

---

### Method: textField()

#### 1. Role

This method creates the amount input field used by the converter. It applies a large font, fixed size, and a numeric document filter so only valid decimal input can be typed or pasted.

#### 2. Processing Pattern

```mermaid
flowchart LR
A["textField"] --> B["Create JTextField"]
B --> C["Set font and size"]
C --> D["Install NumericFilter"]
D --> E["Return text field"]
```

#### 3. Parameter Analysis

| Parameter | Type | Purpose | Validation |
|-----------|------|---------|------------|
| None | - | Creates the amount input field | Input is constrained by `NumericFilter` |

#### 4. CRUD Operations / Called Services

| Service / Dependency | Operation | Purpose |
|----------------------|-----------|---------|
| Swing `JTextField` | C / U | Creates the text input widget |
| `NumericFilter` | C | Enforces numeric-only entry |

#### 5. Dependency Trace

| Caller | Entry Point | Notes |
|--------|-------------|-------|
| `panel()` | UI construction | Adds the field to the source row |

#### 6. Per-Branch Detail Blocks

- Creation branch
  - Creates the field and applies styling.
  - Attaches the document filter to the plain document.

---

### Method: label()

#### 1. Role

This method creates the result label used to display the converted amount. It uses the same typographic treatment as the input field and styles the label as a white output panel for readability.

#### 2. Processing Pattern

```mermaid
flowchart LR
A["label"] --> B["Create JLabel"]
B --> C["Set font and size"]
C --> D["Enable opaque background"]
D --> E["Set background color"]
E --> F["Return label"]
```

#### 3. Parameter Analysis

| Parameter | Type | Purpose | Validation |
|-----------|------|---------|------------|
| None | - | Creates the output display area | None |

#### 4. CRUD Operations / Called Services

| Service / Dependency | Operation | Purpose |
|----------------------|-----------|---------|
| Swing `JLabel` | C / U | Creates the result display widget |
| AWT `Color` | C | Applies the white background |

#### 5. Dependency Trace

| Caller | Entry Point | Notes |
|--------|-------------|-------|
| `panel()` | UI construction | Adds the output label to the second row |

#### 6. Per-Branch Detail Blocks

- Creation branch
  - Builds the label and applies typography.
  - Makes the background visible and white.

---

## Class: NumericFilter

### Class Summary

| Field | Value |
|-------|-------|
| FQN | `com.github.blaxk3.ui.UI.NumericFilter` |
| Layer | Presentation / Input validation |
| Methods | 3 |

`NumericFilter` is a nested `DocumentFilter` implementation used by the amount text field. It validates edited text before it is committed, allowing only digits and at most one decimal point.

### Method: isValid(String text)

#### 1. Role

This method checks whether a candidate text value is acceptable for the amount field. It allows empty input, digits, and a single decimal point, and it rejects any other character.

#### 3. Parameter Analysis

| Parameter | Type | Purpose | Validation |
|-----------|------|---------|------------|
| `text` | `String` | Candidate document content | Must contain only digits and at most one `.` |

#### 4. CRUD Operations / Called Services

| Service / Dependency | Operation | Purpose |
|----------------------|-----------|---------|
| None | - | Pure validation logic |

#### 5. Dependency Trace

| Caller | Entry Point | Notes |
|--------|-------------|-------|
| `insertString()` | Internal call | Validates prospective content after insertion |
| `replace()` | Internal call | Validates prospective content after replacement |

#### 6. Per-Branch Detail Blocks

- Empty string branch
  - Returns `true` to allow clearing the field.
- Character scan branch
  - Accepts digits.
  - Allows a single decimal point.
  - Rejects any other symbol or a second decimal point.

### Method: insertString(FilterBypass fb, int offset, String string, AttributeSet attr)

#### 1. Role

This override validates text before an insert operation is committed to the document. It reconstructs the would-be document content, checks it with `isValid()`, and only then allows the insertion to proceed.

#### 2. Processing Pattern

```mermaid
flowchart LR
A["insertString"] --> B["Build proposed text"]
B --> C["isValid"]
C -->|true| D["super.insertString"]
C -->|false| E["Reject change"]
```

#### 3. Parameter Analysis

| Parameter | Type | Purpose | Validation |
|-----------|------|---------|------------|
| `fb` | `FilterBypass` | Access to the target document | Assumed non-null by Swing |
| `offset` | `int` | Insert position | Used to compute the prospective content |
| `string` | `String` | Text to insert | Must keep the full document valid |
| `attr` | `AttributeSet` | Character attributes | Passed through to Swing |

#### 4. CRUD Operations / Called Services

| Service / Dependency | Operation | Purpose |
|----------------------|-----------|---------|
| `Document` | R | Reads current document content |
| `DocumentFilter.super.insertString()` | C / U | Commits a valid insert |
| `isValid()` | R | Validates the resulting text |

#### 5. Dependency Trace

| Caller | Entry Point | Notes |
|--------|-------------|-------|
| Swing text editing | Document pipeline | Triggered when the user types or pastes into the field |

#### 6. Per-Branch Detail Blocks

- Valid branch
  - Calls the superclass implementation to apply the edit.
- Invalid branch
  - Does nothing, leaving the document unchanged.

### Method: replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)

#### 1. Role

This override validates text before a replacement operation is committed to the document. It rebuilds the resulting document content after substitution and permits the change only when the entire result matches the numeric rules.

#### 2. Processing Pattern

```mermaid
flowchart LR
A["replace"] --> B["Build proposed text"]
B --> C["isValid"]
C -->|true| D["super.replace"]
C -->|false| E["Reject change"]
```

#### 3. Parameter Analysis

| Parameter | Type | Purpose | Validation |
|-----------|------|---------|------------|
| `fb` | `FilterBypass` | Access to the target document | Assumed non-null by Swing |
| `offset` | `int` | Replacement start index | Used to compute the prospective content |
| `length` | `int` | Number of characters to remove | Used to compute the prospective content |
| `text` | `String` | Replacement text | Must keep the full document valid |
| `attrs` | `AttributeSet` | Character attributes | Passed through to Swing |

#### 4. CRUD Operations / Called Services

| Service / Dependency | Operation | Purpose |
|----------------------|-----------|---------|
| `Document` | R | Reads current document content |
| `DocumentFilter.super.replace()` | C / U | Commits a valid replacement |
| `isValid()` | R | Validates the resulting text |

#### 5. Dependency Trace

| Caller | Entry Point | Notes |
|--------|-------------|-------|
| Swing text editing | Document pipeline | Triggered when existing text is replaced in the field |

#### 6. Per-Branch Detail Blocks

- Valid branch
  - Calls the superclass implementation to apply the replacement.
- Invalid branch
  - Ignores the edit and preserves the existing text.
