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

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

## 1. Role

### UI.button()

This method builds the three action buttons that drive the currency conversion screen: **Convert**, **Swap**, and **Clear**. It does not perform business calculations itself; instead, it wires user-facing controls to the supporting conversion API and to local UI state updates. The method follows a lightweight **factory + event delegation** pattern: it creates the buttons, applies consistent sizing, and attaches action listeners that delegate work to the API and UI helper methods.

From a business perspective, the method supports the core user journey of the application. **Convert** validates that an amount has been entered, then requests a currency conversion using the currently selected source and target currencies and renders the formatted result. **Swap** exchanges the selected currencies so the user can quickly reverse the conversion direction. **Clear** resets both the amount input and the result display so the screen can be reused for another conversion. The method therefore acts as the interaction hub for the conversion panel and is called when the UI is assembled.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START["button()"]
    INIT["Create JButton array: Convert, Swap, Clear"]
    SIZE["Set preferred size for each button"]
    API["Instantiate CurrencyRateAPI"]
    CONVERT_HANDLER["Attach Convert action listener"]
    CONVERT_CHECK{ "getTextField().getText() is not empty AND not '.'" }
    CONVERT_OK["Call rate.convert(sourceCurrency, targetCurrency, amount)"]
    FORMAT["Format converted value with DecimalFormat '#,###.###'"]
    SET_LABEL["setLabel(formatted result)"]
    CONVERT_ERROR["Show message dialog: Please enter the amount you need"]
    CONVERT_EX["Catch MalformedURLException or URISyntaxException and throw RuntimeException"]
    SWAP_HANDLER["Attach Swap action listener"]
    SWAP_SAVE["Read selected source currency into boxItem"]
    SWAP_SET1["Set source combo box to target selection"]
    SWAP_SET2["Set target combo box to saved source selection"]
    CLEAR_HANDLER["Attach Clear action listener"]
    CLEAR_TEXT["setTextField(\"\")"]
    CLEAR_LABEL["setLabel(\"\")"]
    RETURN["Return Component[]"]

    START --> INIT
    INIT --> SIZE
    SIZE --> API
    API --> CONVERT_HANDLER
    CONVERT_HANDLER --> CONVERT_CHECK
    CONVERT_CHECK -- "Yes" --> CONVERT_OK
    CONVERT_CHECK -- "No" --> CONVERT_ERROR
    CONVERT_OK --> FORMAT
    FORMAT --> SET_LABEL
    CONVERT_OK --> CONVERT_EX
    CONVERT_ERROR --> CONVERT_EX
    SET_LABEL --> SWAP_HANDLER
    CONVERT_EX --> SWAP_HANDLER
    SWAP_HANDLER --> SWAP_SAVE
    SWAP_SAVE --> SWAP_SET1
    SWAP_SET1 --> SWAP_SET2
    SWAP_SET2 --> CLEAR_HANDLER
    CLEAR_HANDLER --> CLEAR_TEXT
    CLEAR_TEXT --> CLEAR_LABEL
    CLEAR_LABEL --> RETURN
```

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| - | (none) | - | This method takes no parameters. It relies on the UI object's internal state, especially the amount text field, the source currency combo box, and the target currency combo box. |

**Instance fields / external state read by the method:** `textField`, `getTextField()`, `getComboBox1()`, `getComboBox2()`, and the `CurrencyRateAPI` service instance created inside the method. The event handlers also read and update the live Swing component state when buttons are clicked.

## 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 field to validate input before conversion. |
| R | `UI.getComboBox1` | UI | - | Reads the selected source currency for conversion or swapping. |
| R | `UI.getComboBox2` | UI | - | Reads the selected target currency for conversion or swapping. |
| R | `CurrencyRateAPI.convert` | CurrencyRateAPI | - | Requests the converted exchange value for the selected currency pair and amount. |
| U | `UI.setLabel` | UI | - | Updates the result label with the formatted converted amount. |
| U | `UI.setTextField` | UI | - | Clears the amount input when the user presses Clear. |
| U | `UI.setLabel` | UI | - | Clears the displayed conversion result when the user presses Clear. |
| U | `UI.getComboBox1` | UI | - | Updates the source selection during the Swap action via `setSelectedItem`. |
| U | `UI.getComboBox2` | UI | - | Updates the target selection during the Swap action via `setSelectedItem`. |
| - | `javax.swing.JOptionPane.showMessageDialog` | - | - | Displays an error prompt when the amount field is empty or invalid. |
| - | `new DecimalFormat("#,###.###")` | - | - | Formats the converted numeric result for user display. |

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

The only direct caller found in the source is `UI` itself, where the method is invoked while building the screen component tree (`panelFramePanel2.add(button()[0])`, `panelFramePanel2.add(button()[1])`, `panelFramePanel2.add(button()[2])`). The method is therefore an internal UI factory routine rather than a reusable service endpoint.

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Screen/UI assembly | `UI` layout construction -> `button()` -> Swing listeners -> `CurrencyRateAPI.convert` | `convert [R] -` |
| 2 | Screen/UI assembly | `UI` layout construction -> `button()` -> Swing listeners -> `setLabel` | `setLabel [U] -` |
| 3 | Screen/UI assembly | `UI` layout construction -> `button()` -> Swing listeners -> `setTextField` | `setTextField [U] -` |
| 4 | Screen/UI assembly | `UI` layout construction -> `button()` -> Swing listeners -> `getComboBox1` / `getComboBox2` | `getComboBox1 [R] -`, `getComboBox2 [R] -` |

## 6. Per-Branch Detail Blocks

**Block 1** — `SET` and initialization (L111-L118)

> Creates the three action buttons and standardizes their size so the conversion panel has a consistent user interface.

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

**Block 2** — `EXEC` Convert action listener registration (L120-L131)

> Registers the business action that validates the amount and performs the conversion request.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `button[0].addActionListener(convert -> {` |
| 2 | EXEC | `try {` |
| 3 | CALL | `getTextField().getText()` |
| 4 | CALL | `getTextField().getText().isEmpty()` |
| 5 | CALL | `getTextField().getText().equals(".")` |
| 6 | IF | `if (!getTextField().getText().isEmpty() && !getTextField().getText().equals("."))` |
| 7 | CALL | `getComboBox1().getSelectedItem()` |
| 8 | CALL | `getComboBox2().getSelectedItem()` |
| 9 | CALL | `rate.convert(...)` |
| 10 | SET | `new DecimalFormat("#,###.###")` |
| 11 | EXEC | `setLabel(...)` |
| 12 | ELSE | `javax.swing.JOptionPane.showMessageDialog(null, "Please enter the amount you need", "Error", javax.swing.JOptionPane.ERROR_MESSAGE);` |
| 13 | CATCH | `catch (MalformedURLException | URISyntaxException ex)` |
| 14 | RETURN | `throw new RuntimeException(ex);` |

**Block 2.1** — `IF` valid amount entered (L122)

> Guards the conversion request so the API is only called when the user has entered a meaningful amount.

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

**Block 2.2** — `ELSE` invalid amount entered (L124)

> Blocks conversion and informs the user that an amount is required.

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

**Block 2.3** — `CATCH` conversion API URL/URI failure (L125-L127)

> Converts checked network/address exceptions into an unchecked failure so the UI event thread fails fast.

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

**Block 3** — `EXEC` Swap action listener registration (L133-L137)

> Registers the exchange-direction reversal behavior for 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 3.1** — `SET` preserve current source currency (L134)

> Saves the current source selection so it can be restored to the target field after the swap.

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

**Block 3.2** — `EXEC` update currency selections (L135-L136)

> Swaps the user’s currency pair without changing any other screen state.

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

**Block 4** — `EXEC` Clear action listener registration (L139-L142)

> Registers the reset behavior that clears both input and output fields.

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

**Block 4.1** — `EXEC` clear amount input (L140)

> Removes the amount so the user can begin a fresh conversion.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `setTextField("");` |

**Block 4.2** — `EXEC` clear conversion result (L141)

> Removes the previously displayed output so the screen returns to a neutral state.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `setLabel("");` |

**Block 5** — `RETURN` component array (L144)

> Returns the configured buttons so the caller can place them into the UI container.

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

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `button()` | Method | Factory method that creates the conversion screen's three primary action buttons. |
| `Convert` | UI action | Triggers currency conversion for the entered amount and selected currency pair. |
| `Swap` | UI action | Reverses the source and target currency selections. |
| `Clear` | UI action | Resets the amount input and the displayed result. |
| `CurrencyRateAPI` | Service | Currency conversion integration used to calculate the exchange result. |
| `convert` | Operation | API call that returns the converted amount for a source currency, target currency, and numeric value. |
| `textField` | Field | Amount input box where the user enters the value to convert. |
| `getComboBox1()` | UI accessor | Returns the source currency selector. |
| `getComboBox2()` | UI accessor | Returns the target currency selector. |
| `setLabel()` | UI mutator | Updates the displayed conversion result or clears it. |
| `setTextField()` | UI mutator | Updates the amount input value or clears it. |
| `DecimalFormat` | Technical term | Java formatter used to display the converted amount with thousands separators and up to three decimals. |
| `MalformedURLException` | Exception | Checked exception indicating the API endpoint or URL is invalid. |
| `URISyntaxException` | Exception | Checked exception indicating the request URI could not be parsed. |
| `JOptionPane` | Swing component | Modal dialog used to show validation errors to the user. |
| `JButton` | Swing component | Clickable button used to start UI actions. |
| `Component[]` | Technical type | Array of Swing UI components returned to the screen builder. |
| `FTTH` | Business term | Fiber To The Home; not used by this method, but commonly denotes a fiber broadband service in telecom domains. |
| `CRUD` | Acronym | Create, Read, Update, Delete; used here to classify method interactions. |
| `UI` | Layer term | Presentation-layer class that assembles and manages interactive screen elements. |
| `Source currency` | Business term | The currency the user is converting from. |
| `Target currency` | Business term | The currency the user is converting to. |
| `Amount` | Business term | The numeric value entered by the user for conversion. |
