Bober02 Bober02 - 1 month ago 10
Java Question

Correct Model-View-Controller pattern in Java Swing

I recently started working with Swing applications in Java, using mostly JTables at the moment. Coming from the world of .NET WPF background, which was tremendously architectured using MVVM design pattern, I am struggling a little bit with Swing. The reason being, with JTables it seems there are many ways you can implement the Model-View-Controller pattern (at least what I feel after looking at available classes). As a result, I wanted to share a few possible general approaches that cmae through my mind and which I saw so far, as well as gather your comments on this issue, which possibly can apply to other controls/applications:


  1. JTable <--> TableModel: In this approach we only have in a sense a View and a Model.
    TableModel has useful methods for updates, such as setValueAt, in which you can put the handling code of any UI updates and, which in turn, can raise events on Model updates. I guess this is the default implementation of DefaultTableModel. So model handles updates made directly on cells (data).
    View (JTable) would register any further handlers in the code behind of a class that would serve as a View. The code could look like this:

    class View extends JPanel {

    public View(TableModel model) {
    super(new BorderLayout(1, 0));
    JTable table = new JTable(model) {

    //override anything you need here - renderers etc.

    };

    //add any listeners here
    }
    //Listeners that would perform actions on events, and possibly call model to update


    What I like about this is that we only have two places to put code into, and there is a natural connection between a JTable and TableModel provided in the implementation, namely setValueAt method.
    What I hate about this though is, in my opinion, a complete disregard to the MVC pattern, which in case of MVVM structured your code brilliantly

  2. JTable --> Controller <--> TableModel : Add another layer to perform the logic
    We would now have a central controller that would instantiate (or receive injected in constructor) view and model. Furthermore, it would register any listeners on the view, and whenever this would happen, we would call some update method on the Model. Perhaps yet another approach would be to forward events from the view's registered handlers to the controller, but that would require view to know about the controller...
    I guess the firing of the event back to view would remain on the model, when we call update method, unless we would simply call tableChanged method on the table. This however ruins the whole neatness of event mechanism, which is given for free in TableModel implementation...
    Further things which must be taken into account here is that we need to look out for converting from view index to model index every time we handle the event from the View (possibly other considerations which I cannot think of at the moment)

  3. JTable <--> TableModel --> BusinessModel: We use the TableModel as the coordinator and keep our business knowledge elsewhere
    So far I assumed that the TableModel contains the raw business data, in the form of List for instance. Now we could potentially use setValueAt method + register handlers on the TableModel which would subsequently modify the underlying BusinessModel, encapsulating the List.
    My only fear is that TableModel should really be a model and not the controller.



These are my views on the matter. I very much look forward to your replies and comments.

Answer

The Swing MVC model, as I understand it does not strictly separate the View from the model, that is there is some communication between the two to avoid unnecessarily going through the controller. As i use it, the JTable is the view, the TableModel is the model, and your listeners act as controllers for the things that need more control than just 'show what's in the model'.