在 Java 中使用 Swing 在 GUI 开发中正确实现 MVC 模式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25502552/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Correctly implementing the MVC pattern in GUI development using Swing in Java
提问by Artemkller545
Firstly, I come from a big PHP background with MVC, when I started with PHP, I browsed a lot of times, to try my best and perfect my MVC-Like design in PHP. A lot of people like answered with answers which helped me a lot.
首先,我来自MVC的大PHP背景,当我开始使用PHP时,我浏览了很多次,尽我所能并在PHP中完善我的MVC-Like设计。很多人都喜欢回答对我有很大帮助的答案。
But after starting GUI development in Swing, the answers about MVC in Swing are totally different. For instance, a model is also a view? According to Oracle's SuggestionsTextElementModel
doesn't have any logical business here, all it does is markup (set color etc) and setting data such as set text and so on. When I developed in PHP, there is no such thing as AbstractModel
because I always got told that a model is not a class, or more, it's a whole layer that processes logical business.
但是在Swing开始GUI开发之后,关于MVC在Swing中的答案就完全不同了。例如,模型也是视图?根据Oracle 的 SuggestionsTextElementModel
在这里没有任何逻辑业务,它所做的只是标记(设置颜色等)和设置数据,例如设置文本等。当我用 PHP 开发时,没有这样的事情,AbstractModel
因为我总是被告知模型不是一个类,或者更多,它是处理逻辑业务的整个层。
In PHP I used Services, Data Mappers and Domain Objects, suggested from this amazing answer which helped me in PHP a lot: How should a model be structured in MVC?
在 PHP 中,我使用了服务、数据映射器和域对象,这是从这个惊人的答案中提出的,这对我在 PHP 中帮助很大:如何在 MVC 中构建模型?
My attempt
我的尝试
After reading again, I thought to give it a go and do a similar thing in Java:
再次阅读后,我想试一试并在Java中做一个类似的事情:
I have the ControllerContainer
which creates all controllers:
我有ControllerContainer
创建所有控制器的:
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));
}
}
As you see, I add the view named "test" with instance of ViewTest
to the controller, now it will be visible in the frame, and can take input.
如您所见,我将名为“test”的视图添加ViewTest
到控制器中,现在它将在框架中可见,并且可以接受输入。
My Controller
class, which should be abstract, but I didn't make it abstract yet:
我的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);
}
}
And an test controller:
还有一个测试控制器:
public class Atest extends Controller {
public Atest(JFrame frame) {
super(frame);
}
public void hit() {
((ViewTest) super.getView("test")).changeColorBlue();
}
}
And my TestView
:
而我的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);
}
}
The problem
问题
As you see, my view creates a new button, and adds a mouse listener to it. the listener will have access to the controller to pass input. The controller gets the input and changes the view.
如您所见,我的视图创建了一个新按钮,并向其添加了一个鼠标侦听器。侦听器将有权访问控制器以传递输入。控制器获取输入并更改视图。
Basically the controller instantly forced to update the view, without any serious logical business because it's not needed in my case.
基本上控制器立即强制更新视图,没有任何严重的逻辑业务,因为在我的情况下不需要它。
According to the link I have posted above, answered by tere?ko, how can I use his idea & suggestions with Java Swing correctly?
根据我在上面发布的链接,由 tere?ko 回答,我如何正确地将他的想法和建议用于 Java Swing?
I am really confused, after the PHP background.
在PHP背景之后,我真的很困惑。
Maybe I am misunderstanding and everything should be done differently in different languages? But I thought that patterns should always be implemented the same way.
也许我误解了,一切都应该用不同的语言来做?但我认为模式应该始终以相同的方式实现。
If you need more information, let me know.
如果您需要更多信息,请告诉我。
回答by udalmik
MVCpattern it is a common paradigm, so there is no differences between pragramming languages in general. However the implementation and some terminologies sometimes look different. In Java Swingit is often to see two following approaches:
MVC模式是一种通用范式,因此一般的编程语言之间没有区别。然而,实现和一些术语有时看起来不同。在Java Swing 中,经常会看到以下两种方法:
1. Classic MVC
1. 经典MVC
Controller- Listens user interface actions, performs corresponding Modelupdates. Can listen actions from differentViews.
控制器- 监听用户界面操作,执行相应的模型更新。可以监听来自不同视图的动作。
Model- Represents the state and the domain logic, methods to modify the state. Notifies listeners about the model updates (several Viewscan listen the updates). Modelis independent and knows nothing about the listeners and their logic.
模型- 表示状态和域逻辑,修改状态的方法。通知监听器模型更新(多个视图可以监听更新)。模型是独立的,对听众及其逻辑一无所知。
View- Responsible for user interface, UI elements layout, also listens Model updates and update the graphic inteface if required. Has some knowledge about the model, in example shown below it knows how to process list of "items".
View- 负责用户界面、UI 元素布局,还监听模型更新并在需要时更新图形界面。对模型有一些了解,在下面显示的示例中,它知道如何处理“项目”列表。
Design of some simple "To Do" app can look like:
一些简单的“待办事项”应用程序的设计可能如下所示:
2. MVP (Model View Presenter)
2. MVP(模型视图展示器)
Controlleracts as a Mediatorbetween the Viewand the Model. Viewbecome very thin and knows nothing about the Modeland interact with Controlleronly. Controllerlistens both Viewand Modeland perform corresponding actions.
Controller充当View和Model之间的中介者。视图变得非常瘦,对模型一无所知,只与控制器交互。Controller 同时监听View和Model并执行相应的操作。
Swingitself adds some confusion because it uses MVC pattern for its UI components. Each UI control has a Model and View. It makes easier to design new UI components, however in a "big picture" of the whole Application design - UI controls stay on the Viewlayer.
Swing本身增加了一些混乱,因为它的 UI 组件使用 MVC 模式。每个 UI 控件都有一个模型和视图。它更容易设计新的 UI 组件,但是在整个应用程序设计的“大图”中 - UI 控件保留在视图层。
回答by trashgod
Maybe I am misunderstanding, and everything should be done differently in different languages?
可能是我理解错了,用不同的语言做每件事都应该不同?
There is no misunderstanding; the patternis merely applied differently.
没有误会;该模式只是应用不同。
As noted in a commentby @ordous and this this answerby @udalmik, a Swing application may have multiple implementations of the MVCpattern. As noted hereand here, "not everyinteraction needs to pass through your application's controller." In contrast, a web applicationmay well "have a 1:1 relation between views and controllers."
正如@ordous的评论和@udalmik 的这个答案所指出的,Swing 应用程序可能有多个MVC模式的实现。正如此处和此处所述,“并非每个交互都需要通过应用程序的控制器。” 相比之下,Web 应用程序很可能“在视图和控制器之间具有 1:1 的关系”。
The Swing separable model architecture, cited here, "collapses the view and controller parts of each component into a single UI (user-interface) object." Swing controllers are scattered among the descendants of JComponent
, typically in the component's UI delegate. As a concrete example, BasicButtonUI
contains a BasicButtonListener
that handles user mouse interaction.
此处引用的 Swing 可分离模型体系结构“将每个组件的视图和控制器部分折叠成单个 UI(用户界面)对象。” Swing 控制器分散在 的后代中,通常在组件的UI 委托中。作为一个具体的例子,包含一个处理用户鼠标交互的。JComponent
BasicButtonUI
BasicButtonListener
Almost used the answerin the link, but the fact that his controller extends
JPanel
ruined it, totally confused me there.
几乎使用了链接中的答案,但他的控制器扩展的事实
JPanel
毁了它,让我完全困惑。
This can be confusing, as a simple Swing program may have no explicit controller at all. As suggested in this outline, the controllerhas direct access to any relevant viewand model; it may also listen to user interaction with the view. The examplewas intended to illustrate the simplest such interaction. It is mere coincidence that the effect is evoked by user interaction with a view component. The simulation cited here, for example, has a ControlPanel
of view components that update the application's view and model. The DisplayPanel
listens directly for a ComponentEvent
that requires a model update. Etc.
这可能会令人困惑,因为一个简单的 Swing 程序可能根本没有显式控制器。正如本大纲中所建议的,控制器可以直接访问任何相关的视图和模型;它还可以监听用户与视图的交互。该示例旨在说明最简单的此类交互。这种效果是由用户与视图组件的交互引起的,这只是巧合。例如,此处引用的模拟具有ControlPanel
更新应用程序视图和模型的视图组件。在DisplayPanel
直接的监听ComponentEvent
,需要一个模型更新。等等。
Your application's controller is then free to focus on the application's needs.
然后您的应用程序的控制器可以自由地专注于应用程序的需求。
@Marco13 elaborates on this and cites additional examples in this related answer.
@Marco13 对此进行了详细说明,并在此相关答案中引用了其他示例。