# Com / Github / Blaxk3 / Ui

## Overview

This package appears to provide the Swing-based user interface for a currency converter application. The central `UI` frame builds the visible window, wires user actions to conversion behavior, and asynchronously loads supported currency codes into the dropdowns from the API layer.

The module is small but important: it is the boundary where user input, UI validation, and currency-rate integration meet. It also contains two nested helper classes that keep the UI responsive and constrain what users can type.

## Key Classes and Interfaces

### [`UI`](src/main/java/com/github/blaxk3/ui/UI.java:30)

`UI` is the main application window. It extends `javax.swing.JFrame`, so it is responsible for creating the window, laying out controls, and handling the button actions that drive conversion.

#### Responsibilities

- Builds the converter screen with two combo boxes, a text field, a result label, and three action buttons.
- Launches background work to populate both combo boxes with currency codes.
- Calls the API layer to perform conversions when the user clicks **Convert**.
- Provides simple accessors and mutators so other code can read or update the form state.

#### Key methods

- [`getComboBox1()`](src/main/java/com/github/blaxk3/ui/UI.java:38) and [`getComboBox2()`](src/main/java/com/github/blaxk3/ui/UI.java:42) return the source and target currency selectors.
- [`getTextField()`](src/main/java/com/github/blaxk3/ui/UI.java:46) returns the amount input field.
- [`setTextField(String msg)`](src/main/java/com/github/blaxk3/ui/UI.java:50) updates the amount field text.
- [`setLabel(String textField)`](src/main/java/com/github/blaxk3/ui/UI.java:54) updates the output label shown to the user.
- [`UI()`](src/main/java/com/github/blaxk3/ui/UI.java:58) constructs and displays the window.
- [`panel()`](src/main/java/com/github/blaxk3/ui/UI.java:70) assembles the two horizontal rows that make up the layout.
- [`comboBox1()`](src/main/java/com/github/blaxk3/ui/UI.java:95) and [`comboBox2()`](src/main/java/com/github/blaxk3/ui/UI.java:103) create and initialize the currency selectors.
- [`button()`](src/main/java/com/github/blaxk3/ui/UI.java:111) creates the action buttons and attaches their listeners.
- [`textField()`](src/main/java/com/github/blaxk3/ui/UI.java:149) creates the numeric input field and installs input validation.
- [`label()`](src/main/java/com/github/blaxk3/ui/UI.java:158) creates the result display label.

#### Design role

`UI` is not just a view class. It also acts as the event wiring layer between the screen and the API. The conversion logic is intentionally simple and lives directly in the button listener rather than in a separate controller layer.

#### Important behavior

The constructor configures the frame with:

- a custom icon loaded from `/icon/image/icon.png`,
- a fixed title, size, and layout,
- a non-resizable window centered on screen,
- `EXIT_ON_CLOSE` so the app terminates when the window closes.

The constructor also immediately adds the built panel and calls `setVisible(true)`, so instantiating `UI` is enough to show the application.

### [`UI.NumericFilter`](src/main/java/com/github/blaxk3/ui/UI.java:167)

`NumericFilter` is a `DocumentFilter` used to constrain the amount field to numeric input. It allows digits and a single decimal point, which matches the converter’s use of `Double.parseDouble(...)` later in the conversion flow.

#### Responsibilities

- Prevents invalid characters from being inserted into the amount text field.
- Preserves empty input, which allows the user to clear the field.
- Supports typing and replacement operations, not just direct insertion.

#### Key methods

- [`insertString(FilterBypass fb, int offset, String string, AttributeSet attr)`](src/main/java/com/github/blaxk3/ui/UI.java:169) simulates the insertion and only applies it if the resulting text is valid.
- [`replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)`](src/main/java/com/github/blaxk3/ui/UI.java:182) applies the same validation for edits that replace existing text.
- [`isValid(String text)`](src/main/java/com/github/blaxk3/ui/UI.java:195) checks that the current text is empty or contains only digits plus at most one decimal point.

#### Design role

This class keeps malformed numeric input from reaching the conversion logic. That reduces the need for more defensive parsing later and makes the text field behave like a constrained numeric input control.

### [`UI.CurrencyCode`](src/main/java/com/github/blaxk3/ui/UI.java:214)

`CurrencyCode` is a `SwingWorker<String[], Void>` that loads currency codes in the background and populates a combo box when the data arrives.

#### Responsibilities

- Fetches currency codes off the Event Dispatch Thread so the UI remains responsive.
- Sorts the returned codes before adding them to the combo box.
- Logs failures rather than crashing the UI thread.

#### Key methods

- [`CurrencyCode(JComboBox<String> comboBox)`](src/main/java/com/github/blaxk3/ui/UI.java:217) stores the target combo box to populate later.
- [`doInBackground()`](src/main/java/com/github/blaxk3/ui/UI.java:221) calls `new CurrencyRateAPI().getCurrencyCode()` and returns the code array.
- [`done()`](src/main/java/com/github/blaxk3/ui/UI.java:227) reads the result with `get()`, sorts it, and adds each code to the combo box.

#### Design role

This class isolates background loading from UI construction. The constructor in `UI.comboBox1()` and `UI.comboBox2()` starts the worker immediately, so the dropdowns can render first and populate shortly afterward.

## How It Works

### Typical startup flow

1. A caller creates a new [`UI`](src/main/java/com/github/blaxk3/ui/UI.java:30) instance.
2. The constructor sets window metadata and calls [`panel()`](src/main/java/com/github/blaxk3/ui/UI.java:70).
3. `panel()` builds two rows:
   - the top row contains the amount field and the source currency combo box,
   - the bottom row contains the result label, the target combo box, and the three buttons.
4. [`comboBox1()`](src/main/java/com/github/blaxk3/ui/UI.java:95) and [`comboBox2()`](src/main/java/com/github/blaxk3/ui/UI.java:103) each create a combo box and start a [`CurrencyCode`](src/main/java/com/github/blaxk3/ui/UI.java:214) worker to populate it asynchronously.
5. [`textField()`](src/main/java/com/github/blaxk3/ui/UI.java:149) installs [`NumericFilter`](src/main/java/com/github/blaxk3/ui/UI.java:167), so only valid amounts can be entered.
6. The frame becomes visible and the user can interact with the controls.

### Conversion flow

When the user clicks **Convert** in [`button()`](src/main/java/com/github/blaxk3/ui/UI.java:111):

1. The listener checks that the amount field is not empty and is not just a decimal point.
2. It reads the selected source and target currency codes from the two combo boxes.
3. It parses the amount from the text field as a `double`, wraps it in `BigDecimal`, and passes it to `CurrencyRateAPI.convert(...)`.
4. The returned value is formatted with `DecimalFormat("#,###.###")`.
5. The formatted string is written to the result label with [`setLabel(String textField)`](src/main/java/com/github/blaxk3/ui/UI.java:54).
6. If the user did not enter a usable amount, a Swing error dialog is shown instead.

### Swap and clear behavior

The other buttons are simple UI conveniences:

- **Swap** exchanges the selected items between the two combo boxes by temporarily storing the first selection and assigning the second to the first.
- **Clear** resets both the amount field and the result label to empty strings.

## Data Model

This package does not define domain entities or DTOs of its own. The main data handled here is UI state:

- selected currency codes in `JComboBox<String>` controls,
- the amount text entered in `JTextField`,
- the converted result rendered in `JLabel`.

The only non-UI data returned directly in this package is the `String[]` currency-code array produced by [`CurrencyCode.doInBackground()`](src/main/java/com/github/blaxk3/ui/UI.java:221). That array is passed into the combo box population step and then discarded.

## Dependencies and Integration

### Package dependency

- [`com.github.blaxk3.api`](src/main/java/com/github/blaxk3/ui/UI.java:3) — used through [`CurrencyRateAPI`](src/main/java/com/github/blaxk3/api/CurrencyRateAPI.java:1), which supplies currency codes and performs conversions.

### External libraries and APIs

- Swing and AWT for the desktop UI (`JFrame`, `JPanel`, `JComboBox`, `JTextField`, `JLabel`, `JButton`, layout and color classes).
- `SwingWorker` for background loading.
- `DocumentFilter` for input validation.
- SLF4J for error logging.
- `DecimalFormat` and `BigDecimal` for result formatting and numeric precision handling.

### Mermaid relationship diagram

```mermaid
flowchart TD
UIClass["UI"] --> Panel["panel()"]
UIClass["UI"] --> ComboBox1["comboBox1()"]
UIClass["UI"] --> ComboBox2["comboBox2()"]
UIClass["UI"] --> Button["button()"]
UIClass["UI"] --> TextField["textField()"]
UIClass["UI"] --> Label["label()"]
Button["button()"] --> NumericFilter["NumericFilter"]
Button["button()"] --> CurrencyRateAPI["CurrencyRateAPI"]
ComboBox1["comboBox1()"] --> CurrencyCode["CurrencyCode"]
ComboBox2["comboBox2()"] --> CurrencyCode["CurrencyCode"]
CurrencyCode["CurrencyCode"] --> CurrencyRateAPI["CurrencyRateAPI"]
```

## Notes for Developers

- The constructor calls `setVisible(true)` immediately, so creating the frame has side effects. If you need to test or extend the UI, be aware that instantiation opens the window.
- Both combo boxes are populated asynchronously. Code that depends on their contents should expect an initial empty state.
- `NumericFilter` allows only a single decimal point and digits. It does not allow negative values or locale-specific decimal separators.
- The conversion listener relies on `Double.parseDouble(...)` and `BigDecimal.valueOf(...)`, so formatting and numeric behavior are tied to Java’s default decimal syntax.
- The result label is updated from the button listener and the clear action only. There is no separate model layer tracking the current conversion result.
- `CurrencyCode.done()` sorts the code list before adding items. If order matters differently in the future, that is the place to adjust it.
- Errors in loading currency codes are logged, but the UI does not currently surface a user-facing failure state for that background step.

## Summary

`com.github.blaxk3.ui` contains the desktop entry point for the currency converter experience. It builds the form, validates amount input, loads supported currencies in the background, and delegates conversion work to `CurrencyRateAPI`.
