# नेविगेशन को किसी controller में केंद्रीकृत कैसे करें

> EventsProcessor स्टैक के push/pop को अपने controller में समाहित करें, ताकि नेविगेशन परीक्षण-योग्य और असंबद्ध हो।

Source: https://crossfly.dev/hi/docs/cookbook/nav/controller-de-navegacao — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# नेविगेशन को किसी controller में केंद्रीकृत कैसे करें

**उद्देश्य.** स्क्रीनों में `new X().show()` और `hide()` बिखेरना UI को नेविगेशन ग्राफ़ से जोड़ देता है। एक **controller** push/pop को केंद्रित करता है, logging/गार्ड के लिए एकल बिंदु देता है और "जड़ तक बंद करने" की अनुमति देता है। यह केवल `EventsProcessor` के वास्तविक स्टैक को समन्वित करता है।

## उपयोग की गई APIs
- `Window.show()` / `Window.hide()` — स्टैक पर push/pop (controller केवल इन्हें सौंपता है)।
- `EventsProcessor.topWindow()` — **स्थैतिक** मेथड जो शीर्ष की विंडो लौटाता है (`instance.windows.peek()`)।
- `EventsProcessor.instance.getLastWindow()` — **इंस्टेंस** मेथड; स्टैक का वास्तविक शीर्ष लौटाता है (या यदि खाली हो तो `null`)। तब उपयोग करें जब बिना अपवाद फेंके यह जाँचना हो कि कुछ स्टैक पर है या नहीं।

> `EventsProcessor` के स्रोत में पुष्टि किए गए नाम: `topWindow()` (स्थैतिक) और `getLastWindow()` (इंस्टेंस)। `topWindow()` `windows.peek()` करता है और यदि स्टैक खाली हो तो अपवाद फेंकता है; `getLastWindow()` उस स्थिति में `null` लौटाता है — रक्षात्मक जाँच के लिए इसे प्राथमिकता दें।

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

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

/** मुख्य निष्पादन योग्य स्क्रीन: स्क्रीन स्टैक/अनस्टैक करने के लिए Nav controller का उपयोग करती है। */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      add(new Label("Tela raiz"));
      add(new Button("Abrir detalhe").onAction(e -> Nav.push(new OutraTela())));  // controller के जरिए push
   }
}

/** स्टैक की गई स्क्रीन: controller (pop) के जरिए बंद होती है। */
class OutraTela extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      add(new Label("Detalhe"));
      add(new Button("Voltar").onAction(e -> Nav.pop()));  // controller के जरिए pop
   }
}

/** Controller: EventsProcessor के असली स्टैक के ऊपर एक पतला मुखौटा। */
final class Nav
{
   private Nav() {}

   /** push: स्टैक करता है और दिखाता है। */
   public static void push(Window w)
   {
      w.show();
   }

   /** pop: यदि कोई हो तो सबसे ऊपर की विंडो बंद करता है। */
   public static void pop()
   {
      Window top = EventsProcessor.instance.getLastWindow();  // null-safe
      if (top != null)
         top.hide();
   }

   /** वर्तमान में सबसे ऊपर की विंडो (null हो सकती है)। */
   public static Window current()
   {
      return EventsProcessor.instance.getLastWindow();
   }
}
```

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

## न्यूनतम अंश
```java
// स्रोत में सत्यापित: EventsProcessor.topWindow() (static) और instance.getLastWindow() (खाली होने पर null लौटाता है)
public final class Nav
{
   private Nav() {}

   /** push: स्टैक करता है और दिखाता है। */
   public static void push(Window w)
   {
      w.show();
   }

   /** pop: यदि कोई हो तो सबसे ऊपर की विंडो बंद करता है। */
   public static void pop()
   {
      Window top = EventsProcessor.instance.getLastWindow();  // null-safe
      if (top != null)
         top.hide();
   }

   /** केवल 1 विंडो (मूल) बचने तक pop दोहराता है। */
   public static void popToRoot()
   {
      Window top;
      // जब तक एक से अधिक विंडो स्टैक में हों, टॉप को हटाते रहें
      while ((top = EventsProcessor.instance.getLastWindow()) != null
             && top != EventsProcessor.topWindow()) { top.hide(); }
      // ("मूल पर लौटने" के लिए, प्रत्येक hide() एक को अनस्टैक करता है; रुकने की शर्त अपने ऐप के अनुसार समायोजित करें)
   }

   /** वर्तमान में सबसे ऊपर की विंडो (null हो सकती है)। */
   public static Window current()
   {
      return EventsProcessor.instance.getLastWindow();
   }
}

// स्क्रीन में उपयोग:
Nav.push(new DetalheTela());
// ...
Nav.pop();
```

सर्वोत्तम अभ्यास:

- स्टैक को दोबारा लागू **न** करें: `EventsProcessor` पहले से सत्य का स्रोत है। controller `show()`/`hide()` पर एक पतला मुखौटा है।
- नेविगेशन गार्ड (जैसे: "क्या असहेजे गए बदलाव हैं?") यहाँ स्वाभाविक होते हैं: `pop()` से पहले जाँचें और यदि जरूरी हो तो एक पुष्टिकरण `Alert` ट्रिगर करें।
- जब स्टैक खाली हो सकता हो तब `topWindow()` से सावधान रहें — यह `peek()` करता है और अपवाद फेंकता है। रक्षात्मक कोड के लिए `getLastWindow()` का उपयोग करें।

## और गहराई में जाएँ
- [विंडो स्टैक](/docs/ui/navigation/the-window-stack) · [स्क्रीनों के बीच नेविगेट करें](/docs/ui/navigation/navigate-between-screens)
- सहोदर रेसिपी: [किसी स्क्रीन को खोलें और बंद करें](/docs/cookbook/nav/abrir-tela)
