[英]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.