1

The answer on this question Swing: how to get container bind to JRadioButton? made me think of MVC in a simple app design. I describe the general idea of an app and my thoughts on MVC pattern for this case.

Small app description:

This app lets user to add simple records that consist of name and description. After pressing "add" button, they are added to the panel as two labels and radio button to let edit the record. User can save his list in a profile (serialize to xml, properties or somewhere else).

My thoughts on how to apply MVC here:

Model

  • Record with name and description fields

  • Profile with serialization mechanism

View

  • Panel that contains multiple panels (records list) - one for each record (radio button + 2 labels for name and description data)

Controller

  • 2 text boxes with labels and a button to add record

  • button to edit a record

At the moment there's no code samples (I'll provide them a little bit later). I don't want to hurry, I want to understand whether I go in a right MVC direction or something should be changed before implementation.

Updated

Code sample

*MainClass*:
public class RecordsControl extends JFrame {
    private RecordsModel model;
    private RecordsController controller;
    private RecordsControlView view;

    public RecordsControl() {
        super("Records Control");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        initMVC();
        getContentPane().add(view);

        pack();
        setMinimumSize(new Dimension(250, 500));
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
    }

    private void initMVC() {
        model = new RecordsModel();
        view = new RecordsControlView(controller);
        controller = new RecordsController(model, view);
    }
}

*Model*:
public class RecordsModel {
    //Record class has only two fields String::name and String::description
    private List<Record> RecordsList;

    public RecordsModel() {
        RecordsList = new ArrayList<Record>();
    }

    public void addRecord(String name, String description) {
        RecordsList.add(new Record(name, description));
    }

    public List<Record> getRecordsList() {
        return RecordsList;
    }
}

*View*:
public class RecordsControlView extends JPanel {
    private final RecordsController controller;

    private JLabel nameLabel;
    private JLabel descrLabel;
    private JTextField nameField;
    private JTextField descrField;
    private JButton addButton;
    private JButton editButton;
    private JButton deleteButton;
    private JPanel recordsListPanel;

    public RecordsControlView(RecordsController controller) {
        super();
        this.controller = controller;
        achievNameLabel = new JLabel("Name: ");
        achievDescrLabel = new JLabel("Description: ");
        achievNameField = new JTextField(15);
        achievDescrField = new JTextField(15);
        addButton = new JButton("Add");

        initGUI();
        initListeners();
    }

    private void initListeners() {
        addButton.addActionListener(controller);
    }

    private void initGUI() {
        //Main Panel
        this.setLayout(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints();

        //name panel
        //...BoxLayout label + panel

        //description panel
        //...BoxLayout label + panel

        //Records list Panel
        //...Vertical BoxLayout

        //Add widgets to GridBagLayout
        //Name panel
        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.insets = new Insets(5, 5, 2, 2);
        add(namePanel, constraints);

        //Description Panel
        constraints.gridx = 0;
        constraints.gridy = 1;
        constraints.insets = new Insets(0, 5, 5, 2);
        add(descrPanel, constraints);

        //Add button
        constraints.gridx = 1;
        constraints.gridy = 0;
        constraints.gridheight = 2;
        constraints.gridwidth = 1;
        constraints.insets = new Insets(5, 0, 5, 5);
        constraints.fill = GridBagConstraints.VERTICAL;
        add(addButton, constraints);

        //Records List panel
        constraints.gridx = 0;
        constraints.gridy = 2;
        constraints.gridwidth = GridBagConstraints.REMAINDER;
        constraints.gridheight = GridBagConstraints.REMAINDER;
        constraints.fill = GridBagConstraints.BOTH;
        constraints.insets = new Insets(0, 5, 5, 5);
        add(recordsListPanel, constraints);
    }

    public JButton getAddButton() {
        return addButton;
    }

    public void addRecord(JPanel record) {
        recordsListPanel.add(record);
    }
}

public class RecordsView extends JPanel {
    private static ButtonGroup radioButtons = new ButtonGroup();

    private JRadioButton radioButton;
    private JLabel name;
    private JLabel description;

    public RecordsView() {
        super();
        radioButton = new JRadioButton();
        name = new JLabel();
        description = new JLabel();

        initGUI();
    }

    private void initGUI() {
        radioButtons.add(radioButton);

        setLayout(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints();

        constraints.gridx = 0;
        constraints.gridy = 0;
        add(radioButton, constraints);

        constraints.gridx = 1;
        constraints.gridy = 0;
        constraints.weightx = 1.0;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        add(name, constraints);

        constraints.gridx = 1;
        constraints.gridy = 1;
        constraints.weightx = 1.0;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        add(description, constraints);
}

*Controller*:
public class RecordsController implements ActionListener{
    private final RecordsModel model;
    private final RecordsControlView view;

    public RecordsController(RecordsModel model, RecordsControlView view) {
        this.model = model;
        this.view = view;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == view.getAddButton()) {
            RecordsView record = new RecordsView();
            view.add(record);
            view.updateUI();
        }
    }
}
Community
  • 1
  • 1
Dragon
  • 2,431
  • 11
  • 42
  • 68

1 Answers1

2

First of all, let's start by saying what actually MVC is:

Model

It's an abstraction layer that contain a lot of classes to deal with application logic. And since then its an abstracted concern, that means, the are no strict rules of a Model definition until its scoped in business logic

View

A view should read data from a Model directly and prepare an output. For each model there should be singular view.

Controller

Also known as Editor, its responsible for changing state of a Model, that means it should only be responsible for defining/re-defining common variables you are dealing with.

If your application satisfies something like this,

- A controller writes to either a Model or a View and does nothing else

- A view contains only display logic

- A model consist of application core classes

Then you are on the right track - you are applying MVC correctly.

An example of basic implementation,

class ModelLayer
{
    public void ModelLayer()
    {
        this.age = 1;
    }

    public int getAgeFromDb()
    {
        return this.age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }
}

class View
{
     public void View(ModelLayer modelLayer)
     {
          this.modelLayer = modelLayer;
     }
     
     public string render()
     {
         return this.modelLayer.getAgeFromDb();
     }
}

class Controller
{
     public void Controller(ModelLayer modelLayer)
     {
          this.modelLayer = modelLayer;
     }
     
     public void onSaveBtnClick()
     {
          this.modelLayer.setAge(2);
     }
}
Community
  • 1
  • 1
Yang
  • 8,580
  • 8
  • 33
  • 58
  • +1 for elaborating on the controller; I would argue that multiple views may listen to the same model, as outlined [here](http://stackoverflow.com/a/2687871/230513). – trashgod Aug 21 '13 at 19:39
  • @Dave Just, I've added my sample and I have some difficulties with controller connection to view (button listener). – Dragon Aug 22 '13 at 12:07
  • @Dragon You are doing it a bit wrong, take a look at : `http://r.je/mvc-in-php.html` (PHP is irrelevant) – Yang Aug 23 '13 at 01:27