简体   繁体   English

使用Java中的Swing在GUI开发中正确实现MVC模式

[英]Correctly implementing the MVC pattern in GUI development using Swing in Java

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. 首先,我来自MVC的大背景,当我开始使用PHP时,我浏览了很多次,尝试用PHP完善我的MVC-Like设计。 A lot of people like answered with answers which helped me a lot. 很多人都喜欢回答了很多帮助我的答案。

But after starting GUI development in Swing, the answers about MVC in Swing are totally different. 但是在Swing中开始GUI开发之后,关于Swing中MVC的答案是完全不同的。 For instance, a model is also a view? 例如,模型也是一种观点? According to Oracle's Suggestions TextElementModel 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. 根据Oracle的建议, TextElementModel在这里没有任何逻辑业务,它所做的只是标记(设置颜色等)和设置数据,如设置文本等。 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. 当我使用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. 如您所见,我将带有ViewTest实例的名为“test”的视图添加到控制器,现在它将在框架中可见,并且可以接受输入。

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. 如果您需要更多信息,请告诉我们。

MVC pattern it is a common paradigm, so there is no differences between pragramming languages in general. MVC模式它是一种常见的范例,因此一般来说,语法编排语言之间没有区别。 However the implementation and some terminologies sometimes look different. 然而,实现和一些术语有时看起来不同。 In Java Swing it is often to see two following approaches: Java Swing中 ,通常会看到以下两种方法:

1. Classic MVC 1.经典MVC

Controller - Listens user interface actions, performs corresponding Model updates. Controller - 侦听用户界面操作,执行相应的模型更新。 Can listen actions from different Views . 可以从不同的 视图中侦听操作。

Model - Represents the state and the domain logic, methods to modify the state. Model - 表示状态和域逻辑,修改状态的方法。 Notifies listeners about the model updates ( several Views can listen the updates). 通知侦听器有关模型更新的信息( 多个视图可以监听更新)。 Model is 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. 视图 - 负责用户界面,UI元素布局,还可以监听模型更新并在需要时更新图形界面。 Has some knowledge about the model, in example shown below it knows how to process list of "items". 有一些关于模型的知识,在下面的例子中它知道如何处理“项目”列表。

Design of some simple "To Do" app can look like: 一些简单的“待办事项”应用程序的设计可能如下所示:

在此输入图像描述

2. MVP (Model View Presenter) 2. MVP(模型视图演示者)

Controller acts as a Mediator between the View and the Model . 控制器充当视图模型之间的中介 View become very thin and knows nothing about the Model and interact with Controller only. 视图变得非常薄,对模型一无所知,只与Controller交互。 Controller listens both View and Model and perform corresponding actions. Controller侦听ViewModel并执行相应的操作。

在此输入图像描述

Swing itself adds some confusion because it uses MVC pattern for its UI components. Swing本身增加了一些混乱,因为它使用MVC模式作为其UI组件。 Each UI control has a Model and View. 每个UI控件都有一个模型和视图。 It makes easier to design new UI components, however in a "big picture" of the whole Application design - UI controls stay on the View layer. 设计新的UI组件变得更加容易,但是在整个应用程序设计的“大图”中 - UI控件保留在View层上。

Maybe I am misunderstanding, and everything should be done differently in different languages? 也许我是误会,一切都应该用不同的语言做不同的事情?

There is no misunderstanding; 没有误解; the pattern is merely applied differently. 模式仅以不同方式应用。

As noted in a comment by @ordous and this this answer by @udalmik, a Swing application may have multiple implementations of the MVC pattern. 正如@ordous的评论和@udalmik的这个答案所指出的,Swing应用程序可能有多个MVC模式的实现。 As noted here and here , "not every interaction needs to pass through your application's controller." 如此此处所述 ,“并非每个交互都需要通过应用程序的控制器。” In contrast, a web application may well "have a 1:1 relation between views and controllers." 相比之下, 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可分离模型体系结构 “将每个组件的视图和控制器部分折叠成单个UI(用户界面)对象。” Swing controllers are scattered among the descendants of JComponent , typically in the component's UI delegate . Swing控制器分散在JComponent的后代中,通常位于组件的UI委托中 As a concrete example, BasicButtonUI contains a BasicButtonListener that handles user mouse interaction. 作为一个具体的例子, BasicButtonUI包含一个处理用户鼠标交互的BasicButtonListener

Almost used the answer in 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. 这可能令人困惑,因为简单的Swing程序可能根本没有明确的控制器。 As suggested in this outline , the controller has direct access to any relevant view and model ; 如本概要所述, 控制器可以直接访问任何相关的视图模型 ; it may also listen to user interaction with the view. 它还可以监听用户与视图的交互。 The example was 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. 例如, 此处引用的模拟具有一个ControlPanel视图组件,用于更新应用程序的视图和模型。 The DisplayPanel listens directly for a ComponentEvent that requires a model update. DisplayPanel直接侦听需要模型更新的ComponentEvent Etc. 等等。

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详细阐述了这一点,并引用了相关答案中的其他例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM