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