2010-02-10 16 views
7

Intento seguir el patrón MVP (específicamente, visión pasiva) en una aplicación java swing ui.Vista del modelo Presentador y vistas compuestas

El diseño básico de la aplicación recuerda al control del asistente. La pantalla se divide en dos partes principales:

  • una vista activa.
  • una barra de navegación estática, con botones de navegación.

El usuario puede usar botones para cambiar la vista activa, pero la barra siempre se muestra.

Modelando este escenario, tengo un montón de descriptores diffirent, cada uno con su propio presentador, ver la interfaz y ver la implementación (usando JPanel). Luego tengo un presentador de Shell, visualizo Intefrace y veo la implementación, usando un JFrame. La idea es que el shell se cargue primero y siempre se muestre, mostrando la barra de navegación inferior y dejando un espacio para la vista activa. El presentador Shell permitirán ajustar la pantalla activa en ese momento, algo parecido a esto:

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) { 
     ??? 
    } 
} 

El problema está en el método SetActiveView: No estoy seguro de cómo configurar el ActiveView a la activePanel, cuando la interfaz de Vista es general y como tal, no sabe nada sobre JPanels. Obviamente, tampoco me gustaría que mis presentadores supieran sobre JPanels.

+0

¿Alguna vez descubrió cómo hacer esto? Ninguna de estas respuestas es particularmente buena. Acabo de publicar este hilo: http://stackoverflow.com/questions/17836421/how-dumb-can-mvp-views-really-be – durron597

Respuesta

1

Podría modificar la definición de Vista a:

interface View { 
    JComponent getContainer(); 
} 

Para que cada vista se puede conseguir fácilmente el contenido de vista? El shell no necesita saber qué implementación de JComponent se está devolviendo.

1

Su interfaz de Vista necesita proporcionar alguna forma de obtener algo visualizable en un JPanel:

interface View { 
    Component getComponent(); 
} 

Luego, en ShellFrame (suponiendo que el uso BorderLayout, como lo haría) se puede establecer el punto de vista de la siguiente manera:

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

El problema es que su JFrameesView, no cada subvista individual activa. La vista que está activa ahora es una tarea de renderizado y, por lo tanto, debe hacerse con el View, no con el Presenter. Imagine que desea cambiar una View diferente en lugar de tener una única subvista visible, todas eran visibles, pero la que estaba activa tenía un color de fondo diferente. El presentador simplemente controla cuál está activo, pero el View controla lo que se entiende por activo.

Así que su tarea no se puede hacer sin romper la encapsulación porque está tratando de hacer un trabajo que por su naturaleza rompe la encapsulación. Entonces haría algo como esto:

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; 
     } 
    } 
} 
Cuestiones relacionadas