# (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 constructs and configures the three primary action buttons used by the currency conversion screen: Convert, Swap, and Clear. Its business role is to provide the user-facing command layer for the screen, translating button clicks into screen actions rather than performing domain persistence or back-end state management. The method implements a simple routing/dispatch pattern by attaching separate action listeners to each button, so each UI action has a dedicated behavior path.

The Convert branch validates that the entered amount is present and not just a lone decimal point before requesting a currency conversion from `CurrencyRateAPI`. If the input is valid, the method reads the selected source and target currencies from the combo boxes, sends the amount to the conversion service, formats the returned value, and displays it in the result label. If the input is invalid, it shows a user error dialog asking for the amount.

The Swap branch exchanges the selected values of the two currency combo boxes, which is a usability shortcut for reversing conversion direction. The Clear branch resets both the input amount field and the output label, allowing the user to start a new conversion flow. Overall, this method is a shared presentation utility for the UI screen and acts as the central button factory and event-binding point for the conversion workflow.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["button()"])
    CREATE["Create JButton array with Convert, Swap, Clear"]
    LOOP["For each button set preferred size to 200x35"]
    RATE["Instantiate CurrencyRateAPI"]
    CONVERT_HANDLER["Attach action listener to Convert button"]
    CONVERT_CHECK{"Text field has amount and is not a lone dot"}
    SHOW_ERROR["Show error dialog asking for amount"]
    CALL_CONVERT["Call rate.convert(fromCurrency, toCurrency, amount)"]
    FORMAT["Format converted rate and set label"]
    SWAP_HANDLER["Attach action listener to Swap button"]
    SWAP_SET["Read selected currency from first combo box"]
    SWAP_EXEC1["Set first combo box to second combo box selection"]
    SWAP_EXEC2["Set second combo box to saved first selection"]
    CLEAR_HANDLER["Attach action listener to Clear button"]
    CLEAR_EXEC1["Clear text field"]
    CLEAR_EXEC2["Clear label"]
    RETURN_NODE(["Return Component array"])

    START --> CREATE --> LOOP --> RATE --> CONVERT_HANDLER --> CONVERT_CHECK
    CONVERT_CHECK -->|yes| CALL_CONVERT --> FORMAT --> SWAP_HANDLER
    CONVERT_CHECK -->|no| SHOW_ERROR --> SWAP_HANDLER
    SWAP_HANDLER --> SWAP_SET --> SWAP_EXEC1 --> SWAP_EXEC2 --> CLEAR_HANDLER --> CLEAR_EXEC1 --> CLEAR_EXEC2 --> RETURN_NODE
```

## 3. Parameter Analysis

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

**External state read by this method:** `textField`, `comboBox1`, `comboBox2`, and the helper methods `getTextField()`, `getComboBox1()`, `getComboBox2()`, `setLabel()`, `setTextField()`. The method also creates and uses a local `CurrencyRateAPI` instance.

## 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` |

Analyze all method calls within this method and classify each as a CRUD operation.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `UI.getTextField` | UI | - | Reads the current amount input field before validation and conversion |
| R | `UI.getComboBox1` | UI | - | Reads the source currency selection for conversion and swapping |
| R | `UI.getComboBox2` | UI | - | Reads the target currency selection for conversion and swapping |
| - | `CurrencyRateAPI.convert` | CurrencyRateAPI | - | Requests the converted exchange rate from the rate API |
| U | `UI.setLabel` | UI | - | Updates the result label with the converted amount |
| U | `UI.setTextField` | UI | - | Clears the amount field during reset |
| U | `UI.getComboBox1().setSelectedItem` | UI | - | Updates the source currency selection during swap |
| U | `UI.getComboBox2().setSelectedItem` | UI | - | Updates the target currency selection during swap |

## 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]

This method is called only from the same `UI` class, where the returned buttons are added to the screen panel. The method itself then delegates to the exchange-rate service and to UI field helpers.

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Utility: `UI` | `UI.button` -> `panelFramePanel2.add(button()[0])` / `button()[1]` / `button()[2]` | `CurrencyRateAPI.convert [R] -` ; `UI.getTextField [R] -` ; `UI.getComboBox1 [R] -` ; `UI.getComboBox2 [R] -` ; `UI.setLabel [U] -` ; `UI.setTextField [U] -` |

## 6. Per-Branch Detail Blocks

**Block 1** — [SET] initial button array creation and sizing loop (L111)

> Builds the three visible actions for the currency converter screen and applies a consistent button size.

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

**Block 2** — [SET] create exchange-rate service and bind Convert action (L117)

> Prepares the service dependency used when the user requests a conversion.

| # | Type | Code |
|---|------|------|
| 1 | SET | `CurrencyRateAPI rate = new CurrencyRateAPI();` |
| 2 | EXEC | `button[0].addActionListener(convert -> { ... });` |

**Block 2.1** — [IF] `!getTextField().getText().isEmpty() && !getTextField().getText().equals(".")` (L119)

> Validates that the user entered a usable numeric amount before calling the exchange-rate service.

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

**Block 2.1.1** — [THEN] valid amount path (L120)

| # | Type | Code |
|---|------|------|
| 1 | CALL | `getComboBox1().getSelectedItem()` |
| 2 | CALL | `getComboBox2().getSelectedItem()` |
| 3 | EXEC | `textField.getText()` is parsed to `Double` and converted to `BigDecimal` |
| 4 | CALL | `rate.convert(...)` |
| 5 | EXEC | `new DecimalFormat("#,###.###").format(...)` |
| 6 | CALL | `setLabel(...)` |

**Block 2.1.2** — [ELSE] invalid amount path (L122)

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

**Block 2.2** — [CATCH] `MalformedURLException | URISyntaxException` (L124)

> Converts checked service-level errors into a runtime failure for the UI layer.

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

**Block 3** — [SET] bind Swap action and exchange selected currencies (L128)

> Reverses the conversion direction by swapping the two selected currency codes.

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

**Block 3.1** — [SET] preserve first combo selection (L129)

| # | Type | Code |
|---|------|------|
| 1 | SET | `String boxItem = Objects.requireNonNull(getComboBox1().getSelectedItem()).toString();` |

**Block 3.2** — [EXEC] apply swapped selections (L130-L131)

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `getComboBox1().setSelectedItem(getComboBox2().getSelectedItem());` |
| 2 | EXEC | `getComboBox2().setSelectedItem(boxItem);` |

**Block 4** — [SET] bind Clear action and reset UI state (L133)

> Clears the amount input and the displayed conversion result.

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

**Block 4.1** — [EXEC] clear input and output (L134-L135)

| # | Type | Code |
|---|------|------|
| 1 | CALL | `setTextField("");` |
| 2 | CALL | `setLabel("");` |

**Block 5** — [RETURN] return the configured component array (L137)

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

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `UI` | Class | User-interface helper for the currency conversion screen |
| `button` | Method | Factory method that creates and wires the screen action buttons |
| `Convert` | Business term | User action that requests an exchange-rate conversion |
| `Swap` | Business term | User action that reverses source and target currencies |
| `Clear` | Business term | User action that resets the input and output fields |
| `CurrencyRateAPI` | Service | Exchange-rate service used to calculate the converted amount |
| `getTextField` | Method | Reads the current amount input control |
| `setTextField` | Method | Updates or clears the amount input control |
| `getComboBox1` | Method | Reads the first currency selector, treated here as the source currency |
| `getComboBox2` | Method | Reads the second currency selector, treated here as the target currency |
| `setLabel` | Method | Updates the output label with the converted value or clears it |
| `textField` | Field | Amount entry field where the user types the value to convert |
| `comboBox1` | Field | First currency selection control |
| `comboBox2` | Field | Second currency selection control |
| `DecimalFormat` | Technical term | Formatter that presents the converted value with thousands separators and up to three decimals |
| `BigDecimal` | Technical term | Precise numeric type used to pass the amount into the conversion service |
| `MalformedURLException` | Technical term | Checked exception indicating an invalid URL used by the rate service |
| `URISyntaxException` | Technical term | Checked exception indicating an invalid URI used by the rate service |
| `JOptionPane` | Technical term | Swing dialog utility used to display validation errors to the user |
| `RuntimeException` | Technical term | Unchecked exception used to surface service failures to the UI layer |
