2010-02-10 97 views
7

我試圖在java swing ui應用程序中關注MVP(特別是被動視圖)模式。模型視圖演示者和複合視圖

該應用程序的基本設計提醒了一個嚮導控制。屏幕分爲兩個主要部分:

  • 積極的看法。
  • 一個靜態導航欄,帶導航按鈕。

用戶可以使用按鈕來更改活動視圖,但總是顯示欄。我有一堆不同的事業,每個人都有自己的演示者,視圖界面和視圖實現(使用JPanel)。然後我有一個Shell演示者,使用JFrame查看intefrace和視圖實現。這個想法是,外殼將首先加載並始終顯示,顯示底部導航欄併爲活動視圖留出空間。外殼主持人將允許設置當前激活畫面,有點像這樣:

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方法:我不知道如何將活動視圖設置爲activePanel,當View接口是通用的因此他們對JPanels一無所知。顯然,我不希望我的演示者也知道JPanels。

+0

你有沒有想過如何做到這一點?這些答案都不是特別好。我只是發佈這個線程:http://stackoverflow.com/questions/17836421/how-dumb-can-mvp-views-really-be – durron597 2013-07-24 14:13:49

回答

1

你能修改視圖的定義:

interface View { 
    JComponent getContainer(); 
} 

讓每個視圖可以輕鬆獲得瀏覽內容? shell不需要知道返回JComponent的實現。

1

您的視圖界面需要提供一些方法,以獲得一個JPanel東西顯示:

interface View { 
    Component getComponent(); 
} 

然後在ShellFrame(假設你使用BorderLayout的,我會),您可以通過以下方式設置視圖:

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

問題是你的JFrameView,而不是每個單獨的活動子視圖。目前處於活動狀態的視圖是渲染作業,因此應該由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; 
     } 
    } 
} 
相關問題