# Java: Presentation-Model Structure

Previous - Big Blob, Next - MVC

The single most important structure in a program is to separate the user interface from the model (business logic, domain, ...). This provides a huge improvement in simplicity, altho at first it may not appear so. Program enhancements and maintenance are much simpler with this structure.

A further separation can be found in the next example which separates the View (displaying information) from the Controller (processing user interactions) -- the MVC pattern. However, for most applications, you will probably get most of the benefit without some of the complications by simply sticking to the Presentation-Model organization that is shown here.

## Main class

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
    // structure/presentation-model/CalcV3.java
    //   Calculator with separation of presentation and model.
    // Fred Swartz -- December 2004

    // Program Organization: Separate View+Controller and Model

    import javax.swing.*;

    public class CalcV3 {
        public static void main(String[] args) {
            JFrame presentation = new CalcViewController();
            presentation.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            presentation.setTitle("Simple Calc - Presentation-Model");
            presentation.setVisible(true);
        }
    }

## The Presentation (GUI, View+Controller, ...)

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
    // structure/presentation-model/CalcViewController.java
    // Fred Swartz - December 2004

    // GUI Organization - GUI independent of model.
    //
    //     GUI subclasses JFrame and builds it in the constructor.
    //
    //     The GUI creates a calculator model object, but knows nothing
    //     about the internal implementation of the calculator.

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class CalcViewController extends JFrame {
        //... Constants
        private static final String INITIAL_VALUE = "1";

        //... The Model.
        private CalcModel  m_logic;

        //... Components
        private JTextField m_userInputTf = new JTextField(5);
        private JTextField m_totalTf     = new JTextField(20);
        private JButton    m_multiplyBtn = new JButton("Multiply");
        private JButton    m_clearBtn    = new JButton("Clear");

        /** Constructor */
        CalcViewController() {
            //... Set up the logic
            m_logic = new CalcModel();
            m_logic.setValue(INITIAL_VALUE);

            //... Initialize components
            m_totalTf.setText(m_logic.getValue());
            m_totalTf.setEditable(false);

            //... Layout the components.
            JPanel content = new JPanel();
            content.setLayout(new FlowLayout());
            content.add(new JLabel("Input"));
            content.add(m_userInputTf);
            content.add(m_multiplyBtn);
            content.add(new JLabel("Total"));
            content.add(m_totalTf);
            content.add(m_clearBtn);

            //... finalize layout
            this.setContentPane(content);
            this.pack();

            //... Set button listeners.
            m_multiplyBtn.addActionListener(new MultiplyListener());
            m_clearBtn.addActionListener(new ClearListener());
        }//end constructor

        ////////////////////////////////////////// inner class MultiplyListener
        /** When a mulitplication is requested.
         *  1. Get the user input number.
         *  2. Call the model to mulitply by this number.
         *  3. Get the result from the Model.
         *  4. Set the Total textfield to this result.
         * If there was an error, display it in a JOptionPane.
         */
        class MultiplyListener implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                String userInput = "";
                try {
                    userInput = m_userInputTf.getText();
                    m_logic.multiplyBy(userInput);
                    m_totalTf.setText(m_logic.getValue());
                } catch (NumberFormatException nfex) {
                    JOptionPane.showMessageDialog(CalcViewController.this,
                                          "Bad input: '" + userInput + "'");
                }
            }
        }//end inner class MultiplyListener

        //////////////////////////////////////////// inner class ClearListener
        /**  1. Reset model.
         *   2. Put model's value into Total textfield.
         */
        class ClearListener implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                m_logic.reset();
                m_totalTf.setText(m_logic.getValue());
            }
        }// end inner class ClearListener

    }

## The Model (Logic, ...)

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
    // structure/presentation-model/CalcModel.java
    // Fred Swartz - December 2004
    // Model
    //     This model is completely independent of the user interface.
    //     It could as easily be used by a command line or web interface.

    import java.math.BigInteger;

    public class CalcModel {
        //... Constants
        private static final String INITIAL_VALUE = "0";

        //... Member variable defining state of calculator.
        private BigInteger m_total;  // The total current value state.

        //========================================================== constructor
        /** Constructor */
        CalcModel() {
            reset();
        }

        //================================================================ reset
        /** Reset to initial value. */
        public void reset() {
            m_total = new BigInteger(INITIAL_VALUE);
        }

        //=========================================================== multiplyBy
        /** Multiply current total by a number.
        *@param operand Number (as string) to multiply total by.
        */
        public void multiplyBy(String operand) {
            m_total = m_total.multiply(new BigInteger(operand));
        }

        //============================================================= setValue
        /** Set the total value.
        *@param value New value that should be used for the calculator total.
        */
        public void setValue(String value) {
            m_total = new BigInteger(value);
        }

        //============================================================= getValue
        /** Return current calculator total. */
        public String getValue() {
            return m_total.toString();
        }
    }