8

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.

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 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. 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.

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?

My attempt

After reading again, I thought to give it a go and do a similar thing in Java:

I have the ControllerContainer which creates all controllers:

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.

My Controller class, which should be abstract, but I didn't make it abstract yet:

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:

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?

I am really confused, after the PHP background.

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.

Community
  • 1
  • 1
Artemkller545
  • 979
  • 3
  • 21
  • 55
  • http://www.journaldev.com/1739/observer-design-pattern-in-java-example-tutorial i know it's not exactly mvc but it's mostly used for that. pretty good tutorial – Stefan Sprenger Aug 26 '14 at 09:50
  • 1
    I believe your confusion comes from you thinking that a model is singular (i.e. an application has just one complex model that models everything). In Swing (and in many other frameworks) components in the view have their own little models and controls. A table has it's own model in the sense that it holds the data, retrieves it and does all operations with it, while the table just shows it. As such, in the context of the table itself, it *is* MVC. Even though the table "model" is useless outside the table and wouldn't even be considered one. – Ordous Aug 26 '14 at 10:33
  • 1
    There's some good links on Swing MVC [here](http://stackoverflow.com/q/3066590/261156). – Catalina Island Aug 26 '14 at 10:52
  • @CatalinaIsland Almost used the answer in the link, but the fact that his controller extends JPanel ruined it, totally confused me there. – Artemkller545 Aug 26 '14 at 16:51
  • I see what you mean; there's a not much required in a Swing `Controller` class, since the view components already handle most user interaction. There's another nice example [here](http://stackoverflow.com/a/22032787/261156). – Catalina Island Aug 28 '14 at 11:54
  • I doubt that there will be **THE ONE** canonical answer, because MVC is not a really strict pattern (as I already wrote here http://stackoverflow.com/a/23416515/3182664 together with some more general explanations - maybe it answers some of your questions regarding Swing). I'm not familiar with PHP, but it seems like the approach there is rather different from MVC in Swing (at least, what I *consider* to mean MVC in Swing). I agree that there are many so-called "MVC examples" that are horribly confusing. One that I found insightful is linked in the answer that I mentioned above... – Marco13 Aug 28 '14 at 20:09
  • ... I think part of the confusion stems from the fact that Swing uses MVC at "multiple layers". trashgod and udalmik already mentioned this in their answers, but as an example: A `JTable` contains a `TableModel`. The `JTable` is a listener for the `TableModel`, and this is one incarnation of MVC. However, for *you* and your application, you may consider the `JTable` as the *view* (that shows data of *your* domain model). Apart from that, I can hardly say more than what was already said in all the other questions and answers about MVC here on stackoverflow. It seems to be an endless story. – Marco13 Aug 28 '14 at 20:13
  • @Marco13: I added a link to your very helpful answer below; IIUC, the PHP approach is similar to that used in other web application framework designs. – trashgod Aug 29 '14 at 17:37

2 Answers2

20

MVC pattern 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 Swing it is often to see two following approaches:

1. Classic MVC

Controller - Listens user interface actions, performs corresponding Model updates. Can listen actions from different Views.

Model - Represents the state and the domain logic, methods to modify the state. 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. 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:

enter image description here

2. MVP (Model View Presenter)

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 listens both View and Model and perform corresponding actions.

enter image description here

Swing itself 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 View layer.

udalmik
  • 7,838
  • 26
  • 40
  • 2
    See also these examples of [1. MVC](http://stackoverflow.com/a/3072979/230513) and [2. MVP](http://stackoverflow.com/a/22032787/230513). – trashgod Aug 28 '14 at 19:32
  • So if I create an MVC program where the Model is a video library that converts AVI to MP4 and I put a view on it and it works great. Later I want to distribute the converter library so someone wants to create their own video converter software, but too bad, because that library depends on the view! So that's why the first pattern is horrendously bad, in a way that requires a special talent to design it that bad. – Chris Vilches Aug 28 '17 at 09:12
  • 2
    Sorry, didn't get this. MVC doesn't prevent you to build software as a set of reusable components and using different implementation of them. – udalmik Aug 30 '17 at 05:56
10

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. 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."

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.

Almost used the answer in the link, but the fact that his controller extends JPanel ruined it, totally confused me there.

This can be confusing, as a simple Swing program may have no explicit controller at all. 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. The DisplayPanel listens directly for a ComponentEvent that requires a model update. 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.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045