# TimePicker

> Hour and minute selection via analog clock or grid.

Source: https://crossfly.dev/docs/ui/widgets/timepicker — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# TimePicker

`TimePicker` selects **hour and minute** via two analog clocks (hours on the left, minutes on the right) with draggable hands, or via a **numeric grid** (list mode). It is confirmed through three buttons: morning (AM), afternoon (PM), and current time. It follows the picker pattern (see [`Picker`](/docs/ui/widgets/picker)).

> 🟡 · **Package:** `dev.crossfly.ui.picker` · **Extends:** `Picker` · **Style:** `TimePickerStyle`

## When to use
- Collect a time (`HH:MM`).

## When NOT to use
- Collect a date → use [`DatePicker`](/docs/ui/widgets/datepicker).

## Appearance
Large display at the top (`hh:mm`), a clock/grid toggle button, the clock area (or numeric grid), and a row of `Morning` / `Afternoon` / `Current` buttons. It sizes itself to ~85% of `Screen.minSize`.

## Complete example (copy, paste, and run)
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.picker.*;

/** Runnable main screen. Point the launcher (classname) and run: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Button abrir = new Button("Escolher hora");
      abrir.onAction(c ->
      {
         TimePicker tp = new TimePicker().setTime(8, 30);
         tp.show(answer -> Hint.show("Hora: " + (String) answer, 2000)); // "08:30"
      });
      add(LAY_AUTO, abrir);
   }
}
```

> The snippets below show **only the core** (what goes inside `onShow()`). To run them, place them in the `MainWindow` skeleton above.

## Basic usage
```java
TimePicker tp = new TimePicker();
tp.show(answer -> campoHora.setText((String) answer)); // "08:30"
```

## Constructors
| Constructor | Description |
|---|---|
| `TimePicker()` | No parameters; starts at the current time. |

## Properties and customization
| Method | Type | What it does |
|---|---|---|
| `setTime(int hour, int minute)` | 0-23 / 0-59 (clamp) | Presets the time. **Call before `show()`.** |
| `timeStyle(TimePickerStyle)` | style | Custom style. |
| `getHour()` / `getMinute()` | `int` | Hour (0-23) / minute. |
| `getTimeText()` | `String` | `HH:MM` (24h) with `LocaleFormats.timeSeparator`. |

## Callbacks and events
| Callback | When it fires |
|---|---|
| `onSelect(Action)` | on confirm (receives the `TimePicker`). |
| `show(onAnswer)` | on close, delivers the `HH:MM` `String`. |

`getAnswer()` always returns **24h** `HH:MM`. The labels and separator respect `LocaleFormats.is24Hour`/`timeSeparator`.

## States
- Clock mode (`listMode=false`) or numeric grid (`listMode=true`), switched by the toggle.
- `hide()` is overridden to **stop the timer** for "current time" before closing.

### Preset and react to selection
```java
TimePicker tp = new TimePicker().setTime(8, 30);
tp.onSelect(p -> Debug.log("Escolhido: " + ((TimePicker) p).getTimeText()));
tp.show(answer -> campoHora.setText((String) answer)); // "08:30"
```

## Best practices
- Call `setTime` **before** `show()` — the angles are read in `onShow`.
- The result is always 24h; convert to 12h in the app display if needed.

## Common mistakes
- **`setTime` after `show()`** — it does not reflect in the already-built UI.
- **Assuming 12h format in `answer`** — it is always 24h `HH:MM`.

## See also
- Area guide: [`ui/`](/docs/ui) · Recipes: [`cookbook/`](/docs/cookbook)
- Pattern base: [`Picker`](/docs/ui/widgets/picker)
- Related components: [`DatePicker`](/docs/ui/widgets/datepicker)
