2

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.

Bober02
  • 15,034
  • 31
  • 92
  • 178

2 Answers2

2

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

James
  • 2,483
  • 2
  • 24
  • 31
  • I saw this approach as well, I just wanted to see whether anyone was conforming to any other suggestion I made – Bober02 Aug 03 '12 at 11:38
  • 1
    The pattern used by Swing combines the view and controller into one object. So it is not the case that the Swing is avoiding "necessarily going through the controller" or that your "listeners act as controllers". Instead the controller is built-in to the view. Read: http://www.oracle.com/technetwork/java/architecture-142923.html – Jason Dec 12 '12 at 22:53
  • I've found that trying to shoe-horn JTable into a strict MVC paradigm has led to very confusing code. Most recently was an overlap of TableModelEvent handlers that caused an infinite loop. My "controller" and my CustomJTable class were handling the TableModelEvents by mistake. I am now changing my app to CustomJTable extends JTable class which will handle TableModelEvents. My "controller" will then handle events from other portions of the app that affect either the TableModel, TableView or both. Thanks for the great initial question Bober02 and the Oracle reference Jason. – bitsdanceforme Mar 25 '13 at 16:41
2

Just to clarify, the Swing separable model architecture couples the model and view loosely using the observer pattern, as shown here. Typically EventListenerList is used internally, but other implementations are mentioned here. The UI delegate controls user interaction with the view. This allows the component to work correctly, as perceived by the user, on disparate platforms.

So the model registers with the view component via a specific Listener interface?

No, each model maintains an EventListenerList internally; each corresponding view adds itself as a listener via the model's addXxxListener() method. Most components also use PropertyChangeLister for bound properties.

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