# Com / Github / Blaxk3 / Ui

## Overview

The `com.github.blaxk3.ui` package appears to provide the Swing-based user interface for a currency converter application. It builds the main window, lets the user choose source and target currencies, accepts a numeric amount, and shows the converted result. The package also contains the input-validation and background-loading logic needed to keep the UI responsive while currency codes are fetched from the API.

## Key Classes and Interfaces

### `UI`

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

`UI` is the main window class and the center of this package. It extends `javax.swing.JFrame`, constructs the full screen layout, wires button actions, and exposes a few helper accessors so other code can read or update the visible controls.

#### Responsibilities

- Create and display the currency converter window.
- Hold references to the active text field, result label, and currency selectors.
- Trigger the conversion flow through `CurrencyRateAPI`.
- Provide convenience actions for swapping currencies and clearing the form.
- Attach numeric-only filtering to the amount field.
- Kick off asynchronous loading of currency codes into the combo boxes.

#### Important methods

- [UI.UI()](src/main/java/com/github/blaxk3/ui/UI.java:58) constructs the frame, sets the application icon and title, configures size and layout, and makes the window visible.
- [UI.panel()](src/main/java/com/github/blaxk3/ui/UI.java:70) assembles the two main horizontal sections of the interface.
- [UI.comboBox1()](src/main/java/com/github/blaxk3/ui/UI.java:95) and [UI.comboBox2()](src/main/java/com/github/blaxk3/ui/UI.java:103) create the source and target currency selectors and start background loading of currency codes.
- [UI.button()](src/main/java/com/github/blaxk3/ui/UI.java:111) creates the Convert, Swap, and Clear buttons and attaches their action listeners.
- [UI.textField()](src/main/java/com/github/blaxk3/ui/UI.java:149) creates the amount input field and installs a `DocumentFilter` that accepts only digits and a single decimal point.
- [UI.label()](src/main/java/com/github/blaxk3/ui/UI.java:158) creates the result display label.
- [UI.getComboBox1()](src/main/java/com/github/blaxk3/ui/UI.java:38), [UI.getComboBox2()](src/main/java/com/github/blaxk3/ui/UI.java:42), and [UI.getTextField()](src/main/java/com/github/blaxk3/ui/UI.java:46) expose the active widgets to the rest of the class.
- [UI.setTextField(String msg)](src/main/java/com/github/blaxk3/ui/UI.java:50) and [UI.setLabel(String textField)](src/main/java/com/github/blaxk3/ui/UI.java:54) update the visible text in the form.

#### How it fits into the package

`UI` depends on the nested helper classes in the same file and on `com.github.blaxk3.api.CurrencyRateAPI` for data retrieval and conversion. There are no child modules in this package, so `UI` is effectively the top-level entry point for this UI layer.

### `NumericFilter`

See [UI.insertString(FilterBypass fb, int offset, String string, AttributeSet attr)](src/main/java/com/github/blaxk3/ui/UI.java:169), [UI.replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)](src/main/java/com/github/blaxk3/ui/UI.java:182), and [UI.isValid(String text)](src/main/java/com/github/blaxk3/ui/UI.java:195).

`NumericFilter` is a `DocumentFilter` implementation that constrains the amount text field to numeric input. It is used by `UI.textField()` to prevent users from entering arbitrary characters into the amount box.

#### Responsibilities

- Intercept text insertion and replacement operations.
- Simulate the resulting document text before applying the edit.
- Allow only valid numeric strings.

#### Important methods

- [UI.insertString(FilterBypass fb, int offset, String string, AttributeSet attr)](src/main/java/com/github/blaxk3/ui/UI.java:169) builds the prospective text after insertion and delegates to `super.insertString(...)` only when the text passes validation.
- [UI.replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)](src/main/java/com/github/blaxk3/ui/UI.java:182) performs the same check for replacement edits.
- [UI.isValid(String text)](src/main/java/com/github/blaxk3/ui/UI.java:195) allows an empty string, digits, and a single decimal point. Any other character rejects the edit.

#### Notes

This filter is intentionally simple: it validates character content, but it does not appear to enforce numeric ranges, leading-zero rules, or decimal precision.

### `CurrencyCode`

See [UI.CurrencyCode(JComboBox < String > comboBox)](src/main/java/com/github/blaxk3/ui/UI.java:217), [UI.doInBackground()](src/main/java/com/github/blaxk3/ui/UI.java:221), and [UI.done()](src/main/java/com/github/blaxk3/ui/UI.java:227).

`CurrencyCode` is a `SwingWorker<String[], Void>` that loads available currency codes in the background and populates a combo box once the data arrives. It exists to keep the UI responsive while currency metadata is fetched from the API.

#### Responsibilities

- Run currency-code retrieval off the Event Dispatch Thread.
- Sort the returned codes before showing them to the user.
- Populate the combo box after the background work completes.
- Log retrieval failures instead of interrupting the UI flow.

#### Important methods

- [UI.CurrencyCode(JComboBox < String > comboBox)](src/main/java/com/github/blaxk3/ui/UI.java:217) stores the combo box that will receive the loaded codes.
- [UI.doInBackground()](src/main/java/com/github/blaxk3/ui/UI.java:221) calls `new CurrencyRateAPI().getCurrencyCode()` and returns the resulting `String[]`.
- [UI.done()](src/main/java/com/github/blaxk3/ui/UI.java:227) reads the worker result, sorts the codes, and adds each one to the combo box. If the worker fails, it logs an error with SLF4J.

#### Notes

The worker does not clear the combo box before adding items. If it were reused or triggered more than once, duplicate entries could accumulate.

## How It Works

The main user flow is:

1. `UI` creates the frame and calls `panel()` from its constructor.
2. `panel()` builds two stacked sections:
   - the top row contains the amount field and the source currency combo box
   - the bottom row contains the result label, the target currency combo box, and the action buttons
3. Both combo boxes are created empty and then populated asynchronously through `CurrencyCode` workers.
4. The amount field is created with `NumericFilter` attached so only numeric text can be entered.
5. When the user clicks **Convert**, the handler:
   - checks that the amount field is not empty and not just `.`
   - reads the selected source and target currencies
   - parses the entered amount as `double`
   - calls `CurrencyRateAPI.convert(...)`
   - formats the result with `DecimalFormat("#,###.###")`
   - writes the formatted result into the label
6. **Swap** exchanges the two selected currency codes.
7. **Clear** blanks both the amount field and the result label.

### Relationship diagram

```mermaid
flowchart TD
UIClass["UI"] --> NumericFilterClass["UI.NumericFilter"]
UIClass --> CurrencyCodeClass["UI.CurrencyCode"]
UIClass --> CurrencyRateAPIClass["CurrencyRateAPI"]
CurrencyCodeClass --> CurrencyRateAPIClass
UIClass --> ComboBox1["Source currency combo box"]
UIClass --> ComboBox2["Target currency combo box"]
UIClass --> AmountField["Amount text field"]
UIClass --> ResultLabel["Result label"]
```

## Data Model

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

- `JTextField` for the amount being converted
- two `JComboBox<String>` instances for source and destination currencies
- a `JLabel` for displaying the conversion result
- `String[]` currency codes returned by `CurrencyRateAPI.getCurrencyCode()`

The module also converts between textual and numeric representations during conversion:

- user input starts as a string in the text field
- it is parsed to `double`
- it is wrapped in `BigDecimal` before conversion
- the returned value is formatted back to a display string

## Dependencies and Integration

### Internal dependency

- `com.github.blaxk3.api.CurrencyRateAPI` — used for two purposes:
  - retrieving the list of currency codes for the combo boxes
  - converting one currency amount into another

### External libraries and APIs

The code relies on standard Swing and AWT classes for the interface itself, plus:

- SLF4J for logging
- `SwingWorker` for asynchronous background loading
- `DecimalFormat` for display formatting
- `BigDecimal` for numeric conversion input

### Integration points

`UI` is the main integration point between user interaction and the API layer. The package does not appear to expose business logic for other modules; instead, it wraps API calls in desktop UI behavior.

## Notes for Developers

- The constructor calls `setVisible(true)`, so instantiating `UI` immediately opens the window.
- `comboBox1()` and `comboBox2()` each start a new `CurrencyCode` worker. If you refactor the window creation flow, be aware that these workers are launched as side effects of component construction.
- The amount field filter allows only digits and a single decimal point. Negative values and formatted numbers with separators are not accepted.
- The Convert action does not show validation feedback beyond a modal error dialog when the amount is missing or invalid.
- The conversion handler catches `MalformedURLException` and `URISyntaxException` and rethrows them as unchecked `RuntimeException`s. That means API configuration or URL problems will fail hard rather than being shown as a user-facing message.
- `Swap` changes only the selected values, not the underlying code lists.
- `Clear` resets the text field and result label, but it does not change the selected currencies.
- `CurrencyCode.done()` sorts the returned codes before adding them to the combo box, so the visible list order is alphabetical.
- The nested classes are `public static`, which makes them reusable from tests or other UI code if needed, but their behavior is tightly coupled to this frame.

## Reference

- [UI](src/main/java/com/github/blaxk3/ui/UI.java:30)
- [UI.panel()](src/main/java/com/github/blaxk3/ui/UI.java:70)
- [UI.button()](src/main/java/com/github/blaxk3/ui/UI.java:111)
- [UI.textField()](src/main/java/com/github/blaxk3/ui/UI.java:149)
- [UI.NumericFilter](src/main/java/com/github/blaxk3/ui/UI.java:167)
- [UI.CurrencyCode](src/main/java/com/github/blaxk3/ui/UI.java:214)
