2010-02-10 2 views
7

Я пытаюсь выполнить шаблон MVP (в частности, пассивный) в приложении java swing ui.Model View Presenter and Composite Views

Основная конструкция приложения напоминает элемент управления мастером. Экран разделен на две основные части:

  • Активный просмотр.
  • статическая навигационная панель с кнопками навигации.

Пользователь может использовать кнопки для изменения активного вида, но панель всегда отображается.

Моделирование этого сценария. У меня есть куча diffirent screers, каждый со своим собственным презентатором, интерфейсом представления и реализацией представления (используя JPanel). Затем у меня есть презентатор Shell, просмотр intefrace и просмотр реализации с использованием JFrame. Идея состоит в том, что оболочка будет загружаться сначала и всегда отображаться, отображая нижнюю панель навигации и оставляя пространство для активного просмотра. Ведущая оболочка позволяют установить текущий активный экран, примерно так:

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

Проблема заключается в методе setActiveView: Я не уверен, как установить ActiveView к ActivePanel, когда View интерфейс вообще и поэтому ничего не знает о JPanels. Очевидно, я бы не хотел, чтобы мои докладчики знали о JPanels.

+0

Вы когда-нибудь выясняли, как это сделать? Ни один из этих ответов не является особенно хорошим. Я только что написал эту тему: http://stackoverflow.com/questions/17836421/how-dumb-can-mvp-views-really-be – durron597

ответ

1

Не могли бы вы изменить определение Вид на:

interface View { 
    JComponent getContainer(); 
} 

Так что каждый вид можно легко получить содержимое просмотра? Оболочке не нужно знать, какая реализация JComponent возвращается.

1

Ваш взгляд интерфейс должен предоставить какой-то способ, чтобы получить что-то отображаемую в JPanel:

interface View { 
    Component getComponent(); 
} 

Тогда в ShellFrame (предполагая, что вы используете BorderLayout, как я бы) вы можете установить вид следующим образом:

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

Проблема в том, что ваш JFrameявляетсяView, а не каждый отдельный активный под просмотр. Представление, которое активно сейчас, является заданием рендеринга, и поэтому должно выполняться View, а не Presenter. Представьте, что вы хотели поменять местами в другом View, чтобы вместо видимости только одного подвидения все они были видны, но тот, который был активен, имел другой цвет фона. Ведущий просто контролирует, какой из них активен, но View управляет тем, что подразумевается под активным.

Так что ваша задача не может быть выполнена без нарушения инкапсуляции, потому что вы пытаетесь выполнить задание, которое по своей природе нарушает инкапсуляцию. Поэтому я бы сделал что-то вроде этого:

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; 
     } 
    } 
} 
Смежные вопросы