2010-02-10 15 views
7

Sto provando a seguire il pattern MVP (specificamente Passive-View) in un'applicazione java swing ui.Modello View Presenter e Composite Views

Il design di base dell'applicazione ricorda un controllo della procedura guidata. Lo schermo è diviso in due parti principali:

  • una vista attiva.
  • una barra di navigazione statica, con pulsanti di navigazione.

L'utente può utilizzare i pulsanti per modificare la vista attiva, ma la barra viene sempre visualizzata.

Modellando questo scenario, ho una serie di diffrent screers, ognuno con il proprio presenter, l'interfaccia di visualizzazione e l'implementazione di visualizzazione (usando JPanel). Poi ho un relatore Shell, vista intefrace e vista implementazione, usando un JFrame. L'idea è che la shell verrà caricata prima e sempre visualizzata, mostrando la barra di navigazione in basso e lasciando uno spazio per la vista attiva. Il presentatore Shell consentiranno l'impostazione della schermata attiva corrente, un po 'come questo:

interface View { 
} 

class Presenter { 
    View view; 

    public Presenter(View view) { 
     this.view = view; 
    } 

    public View getView() { 
     return view; 
    } 

} 

interface ShellView extends View { 
    void setActiveView(View activeView); 
} 

class ShellPresenter extends Presenter { 
    private ShellView shellView; 

    public void setActivePresenter(Presenter activePresenter) { 
     shellView.setActiveView(activePresenter.getView()); 
    } 
} 

class ShellFrame implements ShellView { 
    private JFrame frame; 
    private JPanel activePanel; 
    private JPanel navigationBar; 

    public ShellFrame() { 
     Container c = frame.getContentPane(); 
     c.add(activePanel); 
     c.add(navigationBar); 
    } 

    public setActiveView(View activeView) { 
     ??? 
    } 
} 

Il problema è nel metodo SetActiveView: Non sono sicuro di come impostare l'ActiveView alla activePanel, quando l'interfaccia View è generale e come tale non sa nulla di JPanels. Ovviamente non vorrei che anche i miei relatori fossero a conoscenza di JPanels.

+0

Hai mai capito come fare? Nessuna di queste risposte è particolarmente buona. Ho appena postato questa discussione: http://stackoverflow.com/questions/17836421/how-dumb-can-mvp-views-really-be – durron597

risposta

1

Potrebbe modificare la definizione di View a:

interface View { 
    JComponent getContainer(); 
} 

In modo che ogni vista può facilmente ottenere il contenuto View? La shell non deve sapere quale implementazione di JComponent viene restituita.

1

L'interfaccia View deve fornire un modo per ottenere qualcosa visualizzabile in un JPanel:

interface View { 
    Component getComponent(); 
} 

Poi nel ShellFrame (a patto di utilizzare BorderLayout, come avrei fatto) è possibile impostare la visualizzazione nel modo seguente:

public setActiveView(View activeView) { 
    activePanel.add(activeView.getComponent(), BorderLayout.CENTER);  
} 
1

Il problema è che il JFrameè il View, non ogni singola sotto-vista attiva. La vista che è attiva in questo momento è un lavoro di rendering, e quindi dovrebbe essere fatto dallo View, non dallo Presenter. Immagina di voler scambiare in un diverso View che invece di avere solo una vista secondaria visibile, erano tutti visibili, ma quello che era attivo aveva un diverso colore di sfondo. Il relatore controlla solo quale è attivo, ma il View controlla cosa si intende per attivo.

Così il tuo compito non può essere svolto senza interrompere l'incapsulamento perché stai cercando di fare un lavoro che, per sua stessa natura, rompe l'incapsulamento. Quindi vorrei fare qualcosa del genere:

class PresenterManager { 
    private Presenter activePresenter; 
    private List<Presenter> allPresenters; 

    IView view; 

    PresenterManager(IView view) { 
     this.view = view; 
     view.subscribe(this); 
    } 

    void addPresenter(Presenter p) { 
     allPresenters.add(p); 
    } 

    void setView(int index) { 
     view.setView(index); 
     activePresenter = allPresenters.get(index); 
    } 
} 

class SwingView implements IView { 
    List<SubView> allViews; 
    SubView activeView; 
    int lastIndex; 

    public void setView(int index) { 
     if(index != lastIndex) { 
      activeView.setVisible(false); 
      activeView = allViews.get(index); 
      lastIndex = index; 
     } 
    } 
} 
Problemi correlati