首先,我来自一个MVC的PHP背景,当我开始PHP的时候,我浏览了很多次,尽我所能完善我在PHP的MVC设计。很多人喜欢回答这个问题,这对我帮助很大。
但是在Swing开始GUI开发之后,关于Swing中MVC的答案完全不同。例如,模型也是一个视图?根据Oracle的建议TextElementModel
这里没有任何逻辑业务,它所做的只是标记(设置颜色等)和设置数据,如设置文本等。当我在PHP开发时,没有AbstractModel
这样的东西,因为我总是被告知模型不是一个类,或者更多,它是处理逻辑业务的整个层。
在PHP中,我使用了服务、数据映射器和领域对象,从这个对我PHP有很大帮助的惊人答案中提出:模型应该如何在MVC中构建?
再次阅读后,我想试一试,在Java做类似的事情:
我有ControlllerContainer
它创建所有控制器:
public class ControllerContainer {
private JFrame frame;
public ControllerContainer(JFrame rune) {
this.frame = frame;
}
public void initControllers() {
Atest test = new Atest(frame);
test.registerView("test", new ViewTest(test));
}
}
如您所见,我将名为“test”的视图与ViewTest
的实例添加到控制器中,现在它将在框架中可见,并且可以接受输入。
我的Controller
类,它应该是抽象的,但我还没有让它抽象:
public class Controller {
private JFrame frame;
private Map<String, Component> views = new HashMap<String, Component>();
public Controller(JFrame frame) {
this.frame = frame;
}
protected void registerView(String title, Component c) {
this.views.put(title, c);
this.frame.add(c);
}
protected void deregisterView(String title) {
this.frame.remove(this.views.get(title));
this.views.remove(title);
}
protected Component getView(String title) {
return this.views.get(title);
}
}
和测试控制器:
public class Atest extends Controller {
public Atest(JFrame frame) {
super(frame);
}
public void hit() {
((ViewTest) super.getView("test")).changeColorBlue();
}
}
和我的TestView
:
public class ViewTest extends JPanel {
private final Atest controller;
public ViewTest(Atest c) {
this.controller = c;
setBackground(Color.RED);
setLocation(0,0);
setSize(300, 300);
setLayout(null);
JButton b = new JButton("hello");
b.setSize(150, 150);
b.setLocation(0,0);
b.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent arg0) {
controller.hit();
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
});
add(b);
}
public void changeColorBlue() {
setBackground(Color.BLUE);
}
}
如您所见,我的视图创建了一个新按钮,并向其添加了一个鼠标侦听器。侦听器将有权访问控制器以传递输入。控制器获取输入并更改视图。
基本上,控制器立即强制更新视图,没有任何严肃的逻辑业务,因为在我的情况下不需要它。
根据我在上面发布的链接,由tereško回答,我如何使用他的想法
我真的很困惑,PHP背景之后。
也许我误解了,所有的事情都应该在不同的语言中以不同的方式完成?但是我认为模式应该总是以相同的方式实现。
如果您需要更多信息,请告诉我。
MVC模式是一种常见的范式,因此一般来说,使用语法语言之间没有区别。然而,实现和一些术语有时看起来不同。在JavaSwing中,通常会看到以下两种方法:
1.经典MVC
控制器-监听用户交互界面操作,执行相应的模型更新。可以监听不同视图的操作。
模型-表示状态和域逻辑,修改状态的方法。通知侦听器模型更新(多个视图可以监听更新)。模型是独立的,对侦听器及其逻辑一无所知。
视图-负责用户交互界面,UI元素布局,还监听模型更新,并在需要时更新图形界面。对模型有一些了解,例如下面所示,它知道如何处理“项目”列表。
一些简单的“待办事项”应用程序的设计可能如下所示:
2.MVP(模型视图演示器)
控制器充当视图和模型之间的中介。视图变得非常薄,对模型一无所知,只与控制器交互。控制器同时监听视图和模型并执行相应的操作。
Swing本身增加了一些混乱,因为它为其UI组件使用MVC模式。每个UI控件都有一个模型和视图。设计新的UI组件更加容易,但是在整个应用程序设计的“大图”中——UI控件停留在视图层。
也许我是误解,所有的事情都应该用不同的语言来做?
没有误解;这种模式只是应用不同。
正如@ordous的评论和@udalmik的这个回答所指出的,Swing应用程序可能有多个MVC模式的实现。正如这里和这里所指出的,“不是每个交互都需要通过应用程序的控制器。”相比之下,Web应用程序很可能“在视图和控制器之间具有1:1的关系”。
这里引用的Swing可分离模型架构“将每个组件的视图和控制器部分折叠成一个UI(用户界面)对象。”Swing控制器分散在JComponent
的后代中,通常位于组件的UI委托中。作为一个具体的例子,BasicButtonUI
包含一个处理用户鼠标交互的BasicButtonListener
。
几乎使用了链接中的答案,但事实上他的控制器扩展JPanel
毁了它,完全让我困惑。
这可能会令人困惑,因为一个简单的Swing程序可能根本没有显式控制器。正如本大纲中建议的那样,控制器可以直接访问任何相关的视图和模型;它也可以监听用户与视图的交互。该示例旨在说明最简单的此类交互。用户与视图组件的交互唤起效果只是巧合。例如,这里引用的模拟具有更新应用程序视图和模型的视图组件的ControlPanel
。DisplayPanel
直接监听需要模型更新的ComponentEvent
。等等。
然后,您的应用程序的控制器可以自由地专注于应用程序的需求。
@Marco13对此进行了详细阐述,并在相关回答中引用了其他例子。