I will be implementing MVC model in my program but before that, I have done a simple program based on my understanding of the MVC model.

I have three pages:

  • The user will enter a value in page one and click the next button.
  • The value will be printed in page two and a picture will be displayed.
  • page three is the end of the page.

Two questions I would like to ask:

  • Is my MVC implementation correct?
  • There are repeated swing components such as JPanel topPanel, JPanel centerPanel, JPanel bottomPanel in PageOne.java, PageTwo.java and PageThree.java and JButton nextButton, JButton cancelButton in PageOne.java, PageTwo.java. Is it ok to repeat component like this for every class? or is there a better way to initialize the component once and use for different classes?

View

PageOne.java

package View;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

@SuppressWarnings("serial")
public class PageOne extends JPanel{

    private JPanel topPanel;
    private JPanel centerPanel;
    private JPanel bottomPanel;
    private JLabel pageOneLabel;
    private JLabel valueLabel;
    private JTextField textField;
    private JButton nextButton;
    private JButton cancelButton;

    public PageOne() {
        setLayout(new BorderLayout());

        pageOneLabel = new JLabel("Page One");
        valueLabel = new JLabel("Enter a value");
        textField = new JTextField(15);
        nextButton = new JButton("Next");
        cancelButton = new JButton("Cancel");

        topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        centerPanel = new JPanel(new FlowLayout());
        bottomPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));

        topPanel.setBackground(Color.WHITE);
        topPanel.add(pageOneLabel);

        centerPanel.add(valueLabel);
        centerPanel.add(textField);

        bottomPanel.add(nextButton);
        bottomPanel.add(cancelButton);

        add(topPanel, BorderLayout.NORTH);
        add(centerPanel, BorderLayout.CENTER);
        add(bottomPanel, BorderLayout.SOUTH);
    }

    public void nextButtonListener(ActionListener listener) {
        nextButton.addActionListener(listener);
    }

    public void cancelButtonListener(ActionListener listener) {
        cancelButton.addActionListener(listener);
    }

    public String textFieldValue() {
        return textField.getText();
    }
}

PageTwo.java

package View;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

import Model.PageTwoModel;

@SuppressWarnings("serial")
public class PageTwo extends JPanel{

    private JPanel topPanel;
    private JPanel centerPanel;
    private JPanel bottomPanel;
    private JLabel pageTwoLabel;
    private JLabel valueLabel;
    private JLabel pic;
    private JButton nextButton;
    private JButton cancelButton;

    public PageTwo(PageTwoModel pageTwoModel) {
        setLayout(new BorderLayout());

        pageTwoLabel = new JLabel("Page Two");
        pic = new JLabel((new ImageIcon(pageTwoModel.getImage())));
        valueLabel = new JLabel();
        nextButton = new JButton("Next");
        cancelButton = new JButton("Cancel");

        topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        centerPanel = new JPanel(new FlowLayout());
        bottomPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));

        topPanel.setBackground(Color.WHITE);
        topPanel.add(pageTwoLabel);

        centerPanel.add(pic);
        centerPanel.add(valueLabel);

        bottomPanel.add(nextButton);
        bottomPanel.add(cancelButton);

        add(topPanel, BorderLayout.NORTH);
        add(centerPanel, BorderLayout.CENTER);
        add(bottomPanel, BorderLayout.SOUTH);
    }

    public void nextButtonListener(ActionListener listener) {
        nextButton.addActionListener(listener);
    }

    public void cancelButtonListener(ActionListener listener) {
        cancelButton.addActionListener(listener);
    }

    public void setLabelValue(String s) {
        valueLabel.setText(s);
    }
}

PageThree.java

package View;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class PageThree extends JPanel{

    private JPanel topPanel;
    private JPanel centerPanel;
    private JPanel bottomPanel;
    private JLabel pageThreeLabel;
    private JLabel valueLabel;
    private JButton closeButton;

    public PageThree() {
        setLayout(new BorderLayout());

        pageThreeLabel = new JLabel("Page Three");
        valueLabel = new JLabel("End of Page");
        closeButton = new JButton("Close");

        topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        centerPanel = new JPanel(new FlowLayout());
        bottomPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));

        topPanel.setBackground(Color.WHITE);
        topPanel.add(pageThreeLabel);

        centerPanel.add(valueLabel);

        bottomPanel.add(closeButton);

        add(topPanel, BorderLayout.NORTH);
        add(centerPanel, BorderLayout.CENTER);
        add(bottomPanel, BorderLayout.SOUTH);
    }
}

Model

PageOneModel.java

package Model;

public class PageOneModel {
    private String value = " ";

    public PageOneModel() {

    }

    public String getString() {
        return value;
    }

    public void setString(String value) {
        this.value = value;
    }
}

PageTwoModel.java

package Model;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class PageTwoModel {
    private BufferedImage pic = null;

    public PageTwoModel() {

    }

    public BufferedImage getImage() {
        try {
            pic = ImageIO.read(new File("email.png"));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return pic;

    }   
}

Controller

package Controller;

import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

import Model.PageOneModel;
import View.PageOne;
import View.PageThree;
import View.PageTwo;

@SuppressWarnings("serial")
public class Controller extends JFrame {

    private CardLayout pages;
    private JPanel pagePanel;
    private PageOne pageOne;
    private PageTwo pageTwo;
    private PageThree pageThree;
    private PageOneModel pageOneModel;

    public Controller(PageOne pageOne, PageTwo pageTwo,PageThree pageThree,PageOneModel pageOneModel) {
        pages = new CardLayout();
        pagePanel= new JPanel();
        pagePanel.setLayout(pages);

        this.pageOne = pageOne;
        this.pageTwo = pageTwo;
        this.pageThree = pageThree;
        this.pageOneModel = pageOneModel;

        pagePanel.add(this.pageOne,"1");
        pagePanel.add(this.pageTwo,"2");
        pagePanel.add(this.pageThree,"3");
        pages.show(pagePanel,"1");

        this.pageOne.nextButtonListener(new GoToPageTwo());
        this.pageTwo.nextButtonListener(new GoToPageThree());

        add(pagePanel);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        pack();
        setSize(510,390);
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);
    }

    class GoToPageTwo implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            pageOneModel.setString(pageOne.textFieldValue());
            pages.show(pagePanel,"2");
            pageTwo.setLabelValue(pageOneModel.getString());

        }
    }

    class GoToPageThree implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            pages.show(pagePanel,"3");          
        }
    }
}

Main

package Main;

import Controller.Controller;
import Model.PageOneModel;
import Model.PageTwoModel;
import View.PageOne;
import View.PageThree;
import View.PageTwo;

public class Main {

    private PageOneModel pageOneModel;
    private PageTwoModel pageTwoModel;
    private PageOne pageOne;
    private PageTwo pageTwo;
    private PageThree pageThree;

    public Main() {

        pageOneModel = new PageOneModel();
        pageTwoModel = new PageTwoModel();
        pageOne = new PageOne();
        pageTwo = new PageTwo(pageTwoModel);
        pageThree = new PageThree();
        new Controller(pageOne,pageTwo,pageThree,pageOneModel);
    }

    public static void main(String[] args) {

        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
                new Main();
            }
        });
    }
}

There is one major mistake I see in your design (only had a quick glance)

public class Controller extends JFrame {

A Controller should contain nothing but business logic (that what you might call the 'back-end' (or what is directly contacting the back-end)) of the application.

You're not supposed to have UI components in a Controller. This class seems more like a part of your View.

This might help you improve your knowledge of the matter.

There's nothing wrong with repeating things like Cancel buttons. They all have their own place/size in ther own forms. If they all do exactly the same thing then it would be OK for them to share a single actionListener.

This article has been dead for over six months. Start a new discussion instead.