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();
        }
    }
}
4
  • This looks like the beginning of a blog post not a question. Commented Aug 21, 2013 at 12:07
  • @bradgonesurfing, It seems so at a glance, but let me add it with samples. I really don't fully understand the MVC and communication between M, V and C. Commented Aug 21, 2013 at 12:14
  • This is a duplicate question to many. See stackoverflow.com/questions/129921/… Commented Aug 21, 2013 at 12:17
  • Also here stackoverflow.com/questions/2626803/… Commented Aug 21, 2013 at 12:18

1 Answer 1

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);
     }
}
Sign up to request clarification or add additional context in comments.

3 Comments

+1 for elaborating on the controller; I would argue that multiple views may listen to the same model, as outlined here.
@Dave Just, I've added my sample and I have some difficulties with controller connection to view (button listener).
@Dragon You are doing it a bit wrong, take a look at : http://r.je/mvc-in-php.html (PHP is irrelevant)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.