簡體   English   中英

模型視圖演示者和復合視圖

[英]Model View Presenter and Composite Views

我試圖在java swing ui應用程序中遵循MVP(特別是Passive-View)模式。

應用程序的基本設計提醒向導控件。 屏幕分為兩個主要部分:

  • 積極的觀點。
  • 一個靜態導航欄,帶有導航按鈕。

用戶可以使用按鈕更改活動視圖,但始終顯示該欄。

在這個場景建模中,我有一堆不同的screers,每個都有自己的演示者,視圖界面和視圖實現(使用JPanel)。 然后我有一個Shell演示者,使用JFrame查看intefrace和視圖實現。 這個想法是shell將首先加載並始終顯示,顯示底部導航欄並為活動視圖留出空間。 shell演示者將允許設置當前活動屏幕,有點像這樣:

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。

問題是您的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;
        }
    }
}

你能否修改View的定義為:

interface View {
    JComponent getContainer();
}

這樣每個視圖都可以輕松獲取視圖內容? shell不需要知道返回JComponent的實現。

您的View界面需要提供一些方法來獲取JPanel中可顯示的內容:

interface View {
    Component getComponent();
}

然后在ShellFrame中(假設您使用BorderLayout,就像我一樣),您可以按以下方式設置視圖:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM