# (DD01) Business Logic — UI.button() [37 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `com.github.blaxk3.ui.UI` |
| Layer | Utility |
| Module | `ui` (Package: `com.github.blaxk3.ui`) |

## 1. Role

### UI.button()

This method builds the three primary action controls for the currency conversion screen: **Convert**, **Swap**, and **Clear**. It acts as a UI factory and event wiring method, returning a `Component[]` that the parent screen can place directly into the panel layout. The method applies a common presentation rule to every button, ensuring consistent sizing before any business interaction occurs.

From a business perspective, the method supports the end-user currency exchange workflow. The **Convert** action validates that an amount has been entered, reads the selected source and target currencies, and delegates to the currency conversion API to compute the result. The **Swap** action exchanges the selected currencies between the two selectors so users can quickly reverse the conversion direction. The **Clear** action resets the amount input and the result label, providing a clean slate for the next transaction.

The method implements a simple **routing/dispatch pattern** through action listeners: each button is mapped to one user intent, and each intent triggers a different UI or service behavior. It is not a domain service itself; instead, it is a presentation-layer coordinator that connects screen actions to the underlying conversion service and shared UI state.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["button()"])
    CREATE_BUTTONS["Create JButton array with Convert, Swap, Clear"]
    SET_SIZE["For each button, set preferred size to 200 x 35"]
    NEW_RATE["Instantiate CurrencyRateAPI"]
    ADD_CONVERT["Attach Convert action listener"]
    CHECK_INPUT{"Text field not empty and not dot"}
    CALL_GETTEXT["Call getTextField().getText() twice"]
    CALL_RATE["Call rate.convert(from, to, amount)"]
    CALL_GETCOMBOS["Call getComboBox1() and getComboBox2()"]
    FORMAT["Format converted amount with DecimalFormat #,###.###"]
    SET_LABEL["setLabel(formatted amount)"]
    SHOW_ERROR["Show JOptionPane error message"]
    HANDLE_EXCEPTION["Wrap MalformedURLException and URISyntaxException in RuntimeException"]
    ADD_SWAP["Attach Swap action listener"]
    GET_BOXITEM["Read selected item from ComboBox1"]
    SWAP_VALUES["Swap selected items between ComboBox1 and ComboBox2"]
    ADD_CLEAR["Attach Clear action listener"]
    CLEAR_VALUES["setTextField and setLabel to empty strings"]
    RETURN_NODE(["Return button array"])

    START --> CREATE_BUTTONS
    CREATE_BUTTONS --> SET_SIZE
    SET_SIZE --> NEW_RATE
    NEW_RATE --> ADD_CONVERT
    ADD_CONVERT --> CHECK_INPUT
    CHECK_INPUT -- "true" --> CALL_GETTEXT
    CALL_GETTEXT --> CALL_GETCOMBOS
    CALL_GETCOMBOS --> CALL_RATE
    CALL_RATE --> FORMAT
    FORMAT --> SET_LABEL
    CHECK_INPUT -- "false" --> SHOW_ERROR
    SET_LABEL --> HANDLE_EXCEPTION
    SHOW_ERROR --> HANDLE_EXCEPTION
    HANDLE_EXCEPTION --> ADD_SWAP
    ADD_SWAP --> GET_BOXITEM
    GET_BOXITEM --> SWAP_VALUES
    SWAP_VALUES --> ADD_CLEAR
    ADD_CLEAR --> CLEAR_VALUES
    CLEAR_VALUES --> RETURN_NODE
```

**CRITICAL — Constant Resolution:**

No application-specific constants are referenced in this method. The method uses only literal UI labels, numeric dimensions, and standard library classes.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|----------------------|
| - | (none) | - | - |

External state read by this method:
- `textField` via `getTextField()` and direct `textField.getText()` usage
- Source currency selection via `getComboBox1()`
- Target currency selection via `getComboBox2()`
- Result display target via `setLabel(...)`
- Input reset target via `setTextField(...)`
- Standard output dialog through `javax.swing.JOptionPane`
- External exchange-rate provider via `CurrencyRateAPI.convert(...)`

## 4. CRUD Operations / Called Services

### Pre-computed evidence from code analysis graph:

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| - | `CurrencyRateAPI.convert` | CurrencyRateAPI | - | Calls `convert` in `CurrencyRateAPI` |
| R | `UI.getComboBox1` | UI | - | Calls `getComboBox1` in `UI` |
| R | `UI.getComboBox2` | UI | - | Calls `getComboBox2` in `UI` |
| R | `UI.getTextField` | UI | - | Calls `getTextField` in `UI` |
| - | `UI.setLabel` | UI | - | Calls `setLabel` in `UI` |
| - | `UI.setTextField` | UI | - | Calls `setTextField` in `UI` |

The method is presentation-heavy and does not directly perform database CRUD. Its business operations are delegated to UI state mutators and the currency conversion service.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `UI.getTextField` | UI | - | Reads the current amount input to decide whether conversion can proceed |
| R | `UI.getComboBox1` | UI | - | Reads the source currency selection |
| R | `UI.getComboBox2` | UI | - | Reads the target currency selection |
| - | `CurrencyRateAPI.convert` | CurrencyRateAPI | External currency rate service | Requests the conversion result for the selected currency pair and amount |
| U | `UI.setLabel` | UI | - | Updates the output label with the formatted converted amount |
| U | `UI.setTextField` | UI | - | Clears the amount entry field |
| U | `UI.getComboBox1().setSelectedItem` | UI | - | Swaps the source currency selection |
| U | `UI.getComboBox2().setSelectedItem` | UI | - | Swaps the target currency selection |
| - | `javax.swing.JOptionPane.showMessageDialog` | Swing | - | Displays a validation error message to the user |

## 5. Dependency Trace

### Pre-computed evidence from code analysis graph:

No screen/batch entry points found within 8 hops. Direct callers found: 1 methods.
Terminal operations from this method: `setLabel` [-], `setTextField` [-], `getComboBox2` [R], `getComboBox2` [R], `getComboBox1` [R], `getComboBox1` [R], `setLabel` [-], `convert` [-], `getComboBox2` [R], `getComboBox1` [R], `getTextField` [R], `getTextField` [R]

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Screen/UI rendering path | `UI` constructor / panel assembly -> `button()` | `getTextField [R]`, `getComboBox1 [R]`, `getComboBox2 [R]`, `CurrencyRateAPI.convert [-]`, `setLabel [U]`, `setTextField [U]` |

The method is internally invoked by the `UI` screen assembly path when adding the three buttons to the panel. Its downstream impact is limited to UI state changes and a single external conversion call; no database-backed terminal operation is reached from this method.

## 6. Per-Branch Detail Blocks

**Block 1** — Sequential setup `(L111-L118)`

> Builds the button collection and applies consistent sizing.

| # | Type | Code |
|---|------|------|
| 1 | SET | `JButton[] button = new JButton[] { new JButton("Convert"), new JButton("Swap"), new JButton("Clear") };` |
| 2 | FOR | `for (JButton buttons: button)` |
| 3 | EXEC | `buttons.setPreferredSize(new Dimension(200, 35));` |

**Block 2** — Instantiate converter dependency `(L120)`

> Creates the rate service used by the Convert action.

| # | Type | Code |
|---|------|------|
| 1 | SET | `CurrencyRateAPI rate = new CurrencyRateAPI();` |

**Block 3** — Convert action listener registration `(L121-L131)`

> Handles amount validation and currency conversion execution.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `button[0].addActionListener(convert -> { ... });` |
| 2 | TRY | `try { ... }` |
| 3 | IF | `if (!getTextField().getText().isEmpty() && !getTextField().getText().equals("."))` |

**Block 3.1** — Valid amount branch `(L123-L126)`

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `getTextField().getText()` |
| 2 | EXEC | `getComboBox1().getSelectedItem()` |
| 3 | EXEC | `getComboBox2().getSelectedItem()` |
| 4 | CALL | `rate.convert(Objects.requireNonNull(getComboBox1().getSelectedItem()).toString(), Objects.requireNonNull(getComboBox2().getSelectedItem()).toString(), BigDecimal.valueOf(Double.parseDouble(textField.getText())))` |
| 5 | EXEC | `new DecimalFormat("#,###.###").format((Number) Double.parseDouble(...))` |
| 6 | CALL | `setLabel(...)` |

**Block 3.2** — Invalid amount branch `(L126-L128)`

| # | Type | Code |
|---|------|------|
| 1 | CALL | `javax.swing.JOptionPane.showMessageDialog(null, "Please enter the amount you need", "Error", javax.swing.JOptionPane.ERROR_MESSAGE);` |

**Block 3.3** — Exception branch `(L129-L130)`

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `throw new RuntimeException(ex);` |

**Block 4** — Swap action listener registration `(L133-L136)`

> Exchanges the source and target currency selections.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `button[1].addActionListener(swap -> { ... });` |
| 2 | SET | `String boxItem = Objects.requireNonNull(getComboBox1().getSelectedItem()).toString();` |
| 3 | EXEC | `getComboBox1().setSelectedItem(getComboBox2().getSelectedItem());` |
| 4 | EXEC | `getComboBox2().setSelectedItem(boxItem);` |

**Block 5** — Clear action listener registration `(L138-L141)`

> Clears the input and output display for a new conversion.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `button[2].addActionListener(clear -> { ... });` |
| 2 | CALL | `setTextField("");` |
| 3 | CALL | `setLabel("");` |

**Block 6** — Return button array `(L143)`

> Returns the completed action button set to the caller.

| # | Type | Code |
|---|------|------|
| 1 | RETURN | `return button;` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `button` | Variable | Array of UI action buttons used to drive the conversion workflow |
| `Convert` | UI action | Triggers currency conversion using the selected source and target currencies |
| `Swap` | UI action | Reverses the direction of the currency pair selection |
| `Clear` | UI action | Resets the amount entry and conversion result display |
| `textField` | Field | Amount input field where the user types the value to convert |
| `comboBox1` | Field / Control | Source currency selector |
| `comboBox2` | Field / Control | Target currency selector |
| `CurrencyRateAPI` | Service | External conversion service wrapper that returns converted currency values |
| `convert` | Method | Performs the rate lookup and amount conversion |
| `DecimalFormat` | Technical term | Formats the converted amount with thousands separators and up to three decimal places |
| `MalformedURLException` | Exception | Indicates the conversion request URL was built incorrectly |
| `URISyntaxException` | Exception | Indicates the conversion request URI could not be parsed |
| `JOptionPane` | Swing component | Displays a modal validation error to the user |
| `amount` | Business term | Numeric value entered by the user for conversion |
| `source currency` | Business term | Currency that the amount is currently expressed in |
| `target currency` | Business term | Currency that the amount should be converted into |
| `swap` | Business term | User operation that reverses the source and target currencies |
| `clear` | Business term | User operation that resets the form for a new transaction |
| `UI` | Class | Presentation-layer screen helper that constructs and wires the interactive controls |
| `Component[]` | Technical term | Swing component array returned to the parent panel for rendering |
| `Dimension` | Technical term | Swing sizing object used to standardize button dimensions |
