# Picker (आधार वर्ग)

> सभी pickers का आधार — getAnswer() + show(onAnswer) पैटर्न।

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

# Picker (आधार वर्ग)

`Picker` CrossFly की सभी चयन विंडो (तारीख, समय, फ़ाइल, फ़ोटो, रंग, बारकोड, निर्देशांक) का साझा आधार है। हर picker खुलता है, उपयोगकर्ता को इंटरैक्ट करने देता है और, **पुष्टि** करने पर, स्वयं बंद हो जाता है और परिणाम को असिंक्रोनस रूप से, callback के माध्यम से, उस कोड को सौंप देता है जिसने उसे खोला था।

इस पृष्ठ के पैटर्न को समझना **सभी** pickers को एक साथ समझना है।

> 🟡 · **पैकेज:** `dev.crossfly.ui.picker` · **विस्तार करता है:** `Window` · **ट्रांज़िशन:** डिफ़ॉल्ट रूप से `FADE`

## केंद्रीय पैटर्न: `getAnswer()` + `show(onAnswer)`

- **`Picker.getAnswer()`** चयनित मान उत्पन्न करता है (प्रत्येक उपवर्ग ठोस प्रकार लौटाने के लिए इसे ओवरराइड करता है: `String`, `Integer`, `LatLon`…)। आधार में, यह `null` लौटाता है।
- **`Window.show(RunnableWith<Object> onAnswer)`** इस मान का उपभोग **तब करता है जब विंडो बंद होती है**।

दोनों के बीच की कड़ी `Window.hide()` में है:

```java
public void hide() {
   ...
   Object answer = this instanceof Picker ? ((Picker) this).getAnswer() : null;
   if (onAnswer != null && answer != null)
      onAnswer.run(answer);
   ...
}
```

व्यावहारिक परिणाम (सभी कोड में पुष्ट):

- **`onAnswer` callback केवल `hide()` में और केवल तभी ट्रिगर होता है जब `getAnswer() != null`।** **रद्द** करने पर, उपवर्ग `getAnswer()` को `null` लौटाने के लिए बनाते हैं — तो `onAnswer` **नहीं** कहा जाता। जिसे रद्दीकरण पर प्रतिक्रिया देनी हो, उसे `onHide()`/`onRemove()` ओवरराइड करना चाहिए या उपवर्ग का विशिष्ट callback उपयोग करना चाहिए।
- `show(onAnswer)` **थ्रेड-सुरक्षित** है: यदि paint thread के बाहर कहा जाए, तो इसे पुनर्निर्धारित किया जाता है और पूरा होने तक ब्लॉक करता है।
- सौंपा गया मान `Object` है; उपभोक्ता picker के ठोस प्रकार में **cast** करता है।

> यह [`Alert`](/docs/ui/widgets/alert)/[`ActionSheet`](/docs/ui/widgets/actionsheet) से भिन्न है, जो `Window` का विस्तार करते हैं पर `Picker` का **नहीं** — उनमें `show(onAnswer)` ट्रिगर नहीं होता और उत्तर बटन callbacks से आता है।

## पूरा उदाहरण (कॉपी करें, पेस्ट करें और चलाएँ)
```java
package com.exemplo;

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

/** चलाने योग्य मुख्य स्क्रीन। launcher (classname) की ओर संकेत करें और चलाएँ: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      Button abrir = new Button("Abrir picker");
      abrir.onAction(c ->
      {
         // Picker का कोई भी subclass वही show(onAnswer) पैटर्न अपनाता है
         DatePicker dp = new DatePicker();
         dp.show(answer ->
         {
            // 'answer' वह Object है जो getAnswer() लौटाता है; यहाँ तभी पहुँचता है जब != null
            String data = (String) answer;
            Hint.show("Selecionado: " + data, 2000);
         });
      });
      add(LAY_AUTO, abrir);
   }
}
```

> नीचे के अंश **केवल मूल भाग** दिखाते हैं (जो `onShow()` के अंदर जाता है)। चलाने के लिए, उन्हें ऊपर दिए `MainWindow` कंकाल में रखें।

## बुनियादी उपयोग (किसी भी picker का सामान्य रूप)
```java
DatePicker dp = new DatePicker();
dp.show(answer ->
{
   // 'answer' वह Object है जो getAnswer() लौटाता है; यहाँ तभी पहुँचता है जब != null
   String data = (String) answer;
   Debug.log("Selecionado: " + data);
});
```

## सार्वजनिक विधियाँ
| विधि | रिटर्न | विवरण |
|---|---|---|
| `getAnswer()` | `Object` | picker का परिणाम, या रद्द होने पर `null`। प्रत्येक उपवर्ग द्वारा ओवरराइड। |
| `show(RunnableWith<Object> onAnswer)` | `void` | picker खोलता है; बंद होने पर callback के माध्यम से मान सौंपता है (`Window` से विरासत में)। |

## उपवर्ग द्वारा लौटाए गए प्रकार
| Picker | `getAnswer()` लौटाता है |
|---|---|
| [`DatePicker`](/docs/ui/widgets/datepicker) | `String` (`LocaleFormats.dateFormat`/`dateSeparator` के अनुसार तारीख) |
| [`TimePicker`](/docs/ui/widgets/timepicker) | `String` (`HH:MM`, 24h) |
| [`FilePicker`](/docs/ui/widgets/filepicker) | — (खाली कंकाल; आधार से `null` विरासत में) |
| [`PhotoPicker`](/docs/ui/widgets/photopicker) | `String` (पथ **या** `"ERROR: ..."`) |
| [`ColorPicker`](/docs/ui/widgets/colorpicker) | `Integer` (alpha रहित RGB) |
| [`BarcodePicker`](/docs/ui/widgets/barcodepicker) | `String` (पढ़ा गया payload) |
| [`LocationPicker`](/docs/ui/widgets/locationpicker) | `LatLon` |

## अच्छे अभ्यास
- हमेशा ऊपर दी तालिका के ठोस प्रकार में `Object` का **cast** करें।
- रद्दीकरण पर प्रतिक्रिया देने के लिए, `onAnswer` पर भरोसा न करें — विशिष्ट callback (`onSelect`/`onCapture`) उपयोग करें या `onHide()` ओवरराइड करें।
- हार्डवेयर pickers (`PhotoPicker`, `BarcodePicker`, `LocationPicker`) बंद होने पर संसाधन मुक्त करते हैं; `hide()` के बाद उसी इंस्टेंस का पुनः उपयोग न करें।

## सामान्य गलतियाँ
- **रद्दीकरण पर `onAnswer` की अपेक्षा करना** — यह ट्रिगर नहीं होता, क्योंकि `getAnswer()` `null` लौटाता है।
- **cast भूलना** — callback को `Object` मिलता है।

## यह भी देखें
- क्षेत्र गाइड: [`ui/`](/docs/ui) · रेसिपी: [`cookbook/`](/docs/cookbook)
- उपवर्ग: [`DatePicker`](/docs/ui/widgets/datepicker) · [`TimePicker`](/docs/ui/widgets/timepicker) · [`FilePicker`](/docs/ui/widgets/filepicker) · [`PhotoPicker`](/docs/ui/widgets/photopicker) · [`ColorPicker`](/docs/ui/widgets/colorpicker) · [`BarcodePicker`](/docs/ui/widgets/barcodepicker) · [`LocationPicker`](/docs/ui/widgets/locationpicker)
