# आपका पहला ऐप (मार्गदर्शित, आद्योपांत)

> एक वास्तविक टास्क सूची — लेआउट, इनपुट, स्टेट, नेविगेशन और SQLite में परसिस्टेंस।

Source: https://crossfly.dev/hi/docs/get-started/your-first-app — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# आपका पहला ऐप: टास्क सूची

चलिए एक ऐसा ऐप बनाते हैं जो **खुलता है, जोड़ता है, नेविगेट करता है और सहेजता है** — चरण-दर-चरण, हर
हिस्से को आवश्यकता के क्रम में प्रस्तुत करते हुए।

## संपूर्ण उदाहरण (कॉपी करें, पेस्ट करें और चलाएँ)
आवश्यक चीज़ों का एक सुव्यवस्थित और स्वयं-निहित संस्करण: एक `TextField` + `Button` जो एक वर्चुअल सूची में
आइटम जोड़ता है। इसे एक `MainWindow` क्लास में पेस्ट करें और `gradlew :lwjgl3:run` से चलाएँ।
```java
package com.exemplo;

import java.util.ArrayList;
import java.util.List;

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

public class MainWindow extends Window
{
   private final List<String> tarefas = new ArrayList<>();
   private TextField campo;
   private VirtualListView lista;

   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      // इनपुट पंक्ति: field (चौड़ाई सोखता है) + button (प्राकृतिक आकार)
      Component entrada = new Component();
      entrada.setLayout(new HorizontalLayout());
      campo = new TextField().caption("Nova tarefa");
      Button add = new Button("Adicionar");
      entrada.add(LAY_FILL, campo);
      entrada.add(LAY_AUTO, add);
      add(LAY_AUTO, entrada);

      // वर्चुअल सूची: प्रत्येक cell की ऊंचाई फ़ॉन्ट की 3x होती है
      lista = new VirtualListView(Relative.ofFont(3f), new DataAdapter()
      {
         @Override public int getCount() { return tarefas.size(); }
         @Override public Component createView() { return new Label(""); }
         @Override public void bindView(Component view, int index)   // पहले view, फिर index
         {
            ((Label) view).setText(tarefas.get(index));   // सीधा cast
         }
      });
      add(LAY_FILL, lista);

      add.onAction(c -> adicionar());
   }

   private void adicionar()
   {
      String texto = campo.getText().trim();
      if (texto.isEmpty())
      {
         Hint.show("Digite uma tarefa", 1500);   // हमेशा 2 args
         return;
      }
      tarefas.add(texto);
      campo.clearText();
      lista.notifyDataChanged();   // सूची को फिर से मापता और रीपेंट करता है
   }
}
```

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

## 1. स्क्रीन का ढाँचा (VerticalLayout)
```java
public class TarefasScreen extends Window {
   private final List<Tarefa> tarefas = new ArrayList<>();   // स्थिति Window के fields में
   private Component listaBox;
   private TextField campo;

   @Override public void onShow() throws Exception {
      super.onShow();
      setLayout(new VerticalLayout());

      // इनपुट पंक्ति (field + button)
      Component entrada = new Component();
      entrada.setLayout(new HorizontalLayout());
      campo = new TextField().caption("Nova tarefa");
      Button add = new Button("Adicionar");
      entrada.add(LAY_FILL, campo);       // field चौड़ाई सोखता है
      entrada.add(LAY_AUTO, add);         // button सामग्री के आकार का
      add(LAY_AUTO, entrada);

      // सूची क्षेत्र, जो शेष ऊंचाई सोखता है
      listaBox = new Component();
      listaBox.setLayout(new VerticalLayout());
      add(LAY_FILL, listaBox);

      add.onAction(c -> adicionar());
      carregar();                          // डेटाबेस से भरता है
   }
}
```

## 2. जोड़ना और UI में प्रतिबिंबित करना (बिना रिएक्टिव बाइंडिंग)
```java
private void adicionar() {
   String texto = campo.getText().trim();
   if (texto.isEmpty()) return;
   Tarefa t = new Tarefa(texto);
   tarefas.add(t);
   salvar(t);              // persist करता है (चरण 4)
   campo.clearText();
   renderizarLista();      // आप UI को मैनुअली अपडेट करते हैं
}

private void renderizarLista() {
   listaBox.removeAll();
   for (Tarefa t : tarefas) {
      Button item = new Button(t.titulo);
      item.onAction(c -> new DetalheScreen(t).show());   // नेविगेशन (चरण 3)
      listaBox.add(LAY_AUTO, item);
   }
   listaBox.setValidLayout(false);   // layout को फिर से मापता है
   Component.repaint();              // नया frame मांगता है
}
```

## 3. push/pop नेविगेशन
```java
public class DetalheScreen extends Window {
   private final Tarefa tarefa;
   public DetalheScreen(Tarefa t) { this.tarefa = t; }   // कंस्ट्रक्टर से डेटा
   @Override public void onShow() throws Exception {
      super.onShow();
      setLayout(new VerticalLayout());
      add(LAY_AUTO, new Label(tarefa.titulo));
      Button voltar = new Button("Voltar");
      voltar.onAction(c -> hide());     // pop
      add(LAY_AUTO, voltar);
   }
}
```

## 4. SQLite में परसिस्टेंस (paint thread के बाहर)
```java
private void carregar() {
   new Thread(() -> {
      List<Tarefa> carregadas = new ArrayList<>();
      try (SqliteDb db = SqliteDb.open("tarefas.db")) {
         db.exec("CREATE TABLE IF NOT EXISTS tarefa(id INTEGER PRIMARY KEY, titulo TEXT)");
         try (SqliteCursor c = db.query("SELECT id, titulo FROM tarefa ORDER BY id")) {
            while (c.next())                                   // getter 0-based
               carregadas.add(new Tarefa(c.getInt(0), c.getString(1)));
         }
      } catch (Exception e) { Debug.handle(e); }
      Component.onUI(() -> {                                   // paint thread पर वापस
         tarefas.clear(); tarefas.addAll(carregadas);
         renderizarLista();
      });
   }).start();
}

private void salvar(Tarefa t) {
   new Thread(() -> {
      try (SqliteDb db = SqliteDb.open("tarefas.db")) {
         db.execute("INSERT INTO tarefa(titulo) VALUES(?)", t.titulo);   // bind 1-based
      } catch (Exception e) { Debug.handle(e); }
   }).start();
}
```
> **SQLite के दो सुनहरे नियम:** पैरामीटर bind **1-आधारित** है, कर्सर के getters
> **0-आधारित** हैं; और डेटाबेस paint thread के **बाहर** चलता है, जिसका परिणाम
> `Component.onUI(...)` के जरिए वापस आता है।

## आपने क्या बनाया
एक ऐप जो **खुलता है, जोड़ता है, नेविगेट करता है और सहेजता है** — और आपने वे स्तंभ पहले ही देख लिए हैं जिन्हें
[`learn/` कोर्स](/docs/learn) गहराई से समझाता है।

## अगले कदम
→ [प्रोजेक्ट की शारीरिक-रचना](/docs/get-started/project-structure)

## यह भी देखें
- [Layouts](/docs/ui/layouts) · [Navegação](/docs/ui/navigation) · [SQLite](/docs/data-and-services/storage-sqlite)
