# Com / Github / Blaxk3 / Ui

## Overview

The `com.github.blaxk3.ui` package contains the Swing user interface for a currency converter application. It appears to be responsible for rendering the main window, collecting the amount and currencies from the user, and coordinating currency conversion requests through `com.github.blaxk3.api.CurrencyRateAPI`.

This module is small but central to the application experience: it owns the visible controls, validates numeric input, loads currency codes asynchronously, and handles the main user actions of convert, swap, and clear.

## 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 both the top-level window and the builder for its own contents. The constructor initializes the frame, sets the icon/title/layout, creates the panel hierarchy, and makes the window visible immediately.

The class also stores references to the primary interactive widgets so event handlers can share state:

- `label` shows the conversion result.
- `textField` accepts the amount to convert.
- `comboBox1` and `comboBox2` hold source and target currencies.

Important methods:

- `getComboBox1()` / `getComboBox2()` / `getTextField()` expose the live Swing components so listeners can read or update them.
- `setTextField(String msg)` and `setLabel(String textField)` are convenience mutators used by button handlers.
- `panel()` assembles the window contents into two horizontal sections.
- `comboBox1()` and `comboBox2()` create the currency selectors and populate them asynchronously.
- `button()` creates the Convert, Swap, and Clear buttons and wires their actions.
- `textField()` creates the numeric input field and attaches validation.
- `label()` creates the output display area.

This class depends directly on `CurrencyRateAPI` for currency metadata and conversions, but it does not manage persistence or business rules beyond user interaction and formatting.

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

`NumericFilter` is a nested `DocumentFilter` that constrains what the user can type into the amount field. Its purpose is to keep the text field limited to numeric input with at most one decimal point, so the UI can safely parse it as a `double` later.

Key methods:

- `insertString(...)` intercepts text insertion and only allows it if the resulting value is valid.
- `replace(...)` applies the same validation when existing characters are replaced.
- `isValid(String text)` performs the actual character-by-character check.

The filter allows an empty string, digits, and a single `.` character. Any other character is rejected before it reaches the document.

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

`CurrencyCode` is a nested `SwingWorker<String[], Void>` that loads currency codes in the background and populates a `JComboBox`. This avoids blocking the UI thread while the application fetches currency metadata from `CurrencyRateAPI`.

Key methods:

- Constructor: stores the target combo box to populate later.
- `doInBackground()` calls `new CurrencyRateAPI().getCurrencyCode()` and returns the result.
- `done()` retrieves the loaded codes, sorts them, and adds them to the combo box.

If loading fails, `done()` logs the error with SLF4J rather than interrupting the UI flow.

## How It Works

### Startup and layout construction

When `new UI()` runs, the frame is configured immediately:

1. The window icon is loaded from `/icon/image/icon.png`.
2. `panel()` builds the content hierarchy.
3. The title is set to `Currency Converter`.
4. The frame is sized to `500 x 500`, made non-resizable, centered, and shown.

The panel structure is simple:

- The root panel uses a vertical `BoxLayout`.
- The top subpanel contains the amount field and the first currency selector.
- The bottom subpanel contains the output label, second currency selector, and the action buttons.

### Loading currency codes

Both combo boxes are created in `comboBox1()` and `comboBox2()`. Each method instantiates an empty `JComboBox`, sets its preferred size, and then starts a `CurrencyCode` worker.

That worker calls `CurrencyRateAPI.getCurrencyCode()` off the EDT, then sorts and inserts the returned codes into the combo box in `done()`. This pattern keeps the UI responsive while the code list loads.

### Converting an amount

The Convert button handler performs the core flow:

1. Read the amount from the text field.
2. Reject empty input or a solitary `.` and show an error dialog.
3. Read the selected source and target currencies from the combo boxes.
4. Call `CurrencyRateAPI.convert(...)` with the currencies and a `BigDecimal` amount.
5. Parse the returned value as `double` and format it with `DecimalFormat("#,###.###")`.
6. Update the result label with the formatted value.

The conversion call can throw `MalformedURLException` or `URISyntaxException`, which are wrapped in a `RuntimeException` if they occur.

### Swapping and clearing

The other buttons are purely UI convenience actions:

- Swap exchanges the selected items between the two combo boxes.
- Clear empties the amount field and clears the result label.

## Mermaid relationship diagram

```mermaid
flowchart TD
UIClass["UI"] --> PanelMethod["panel()"]
UIClass --> ComboBoxOne["comboBox1()"]
UIClass --> ComboBoxTwo["comboBox2()"]
UIClass --> ButtonMethod["button()"]
UIClass --> TextFieldMethod["textField()"]
UIClass --> LabelMethod["label()"]
UIClass --> NumericFilterClass["NumericFilter"]
UIClass --> CurrencyCodeClass["CurrencyCode"]
CurrencyCodeClass --> CurrencyRateAPIClass["CurrencyRateAPI"]
ButtonMethod --> CurrencyRateAPIClass
```

## Data Model

This package does not define domain entities or DTOs. Its main data structures are Swing components and simple value types used for conversion:

- `String` for currency codes and label text
- `BigDecimal` for the requested amount passed to the API
- `String[]` for the asynchronously loaded currency code list

The UI keeps direct references to the components rather than using a separate view model.

## Dependencies and Integration

### Internal dependency

- [com.github.blaxk3.api](src/main/java/com/github/blaxk3/api/CurrencyRateAPI.java) — provides currency codes and conversion results

### External libraries and frameworks

- Swing/AWT for the desktop UI
- SLF4J for logging
- `javax.swing.SwingWorker` for background loading
- `DocumentFilter` for input validation

### Integration pattern

The package is tightly coupled to `CurrencyRateAPI`:

- `CurrencyCode` uses it to fetch the list of valid currencies.
- The Convert button uses it to perform exchange-rate conversion.

That makes `UI` the presentation layer and `CurrencyRateAPI` the service layer from the perspective of this module.

## Notes for Developers

- `UI` constructs and shows the frame in its constructor. Creating an instance has visible side effects immediately.
- The combo boxes are populated asynchronously, so they may be empty briefly after startup.
- `NumericFilter` allows only digits and a single decimal point. Negative values, thousand separators, and scientific notation are not supported.
- The Convert handler assumes the API returns a numeric string that can be parsed as `double`.
- `button()` returns an array of buttons, and `panel()` relies on fixed array positions. If you add buttons, update both the array order and the panel assembly.
- Errors from currency loading are logged, but the UI does not surface a user-visible failure state for that path.
- The package currently contains one top-level class with two nested helper classes, so most behavior is concentrated in a single file: [src/main/java/com/github/blaxk3/ui/UI.java](src/main/java/com/github/blaxk3/ui/UI.java).
