Simple MVC desktop example wanted

Hi,

I've been looking and can't find a good example of MVC in a desktop application. I don't mean MVC as it is used in component development (I've seen some examples relating to Swing and Buttonmodels, for instance), but more business-object level. I'm not a Java or Swing expert, but I have been programming for a while and and am pretty comfortable writing non-UI Java classes and simple Swing apps. But I want to know how to do this right.

Here's the simplest example I can think of to explain my confusion:

Suppose I have a class called Customer with fields FirstName and LastName. Suppose further I want to create a desktop GUI that allows the customer to edit that model in two separate windows in such a way that changes in one edit window are immediately reflected in the other, and I want clean separation of presentation and logic.

The example doesn't have to be in Swing, but it shouldn't require a server.

Thanks for any help you can give on this - and, if this isn't the right place to post this query, I'd appreciate a pointer to a more appropriate forum.

[1116 byte] By [WarrenSa] at [2007-10-2 8:20:05]
# 1
My best guess would be Google.
SoulTech2012a at 2007-7-16 22:19:06 > top of Java-index,Other Topics,Patterns & OO Design...
# 2

There are many ways but here is a simple example of how I do it.

******************************* CustomerModel.java

import java.beans.PropertyChangeSupport;

import java.beans.PropertyChangeListener;

/** */

public class CustomerModel

{

/** Change Support Object */

private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);

/** bound property names */

public static final String FIRST_NAME_CHANGED = "firstname";

public static final String LAST_NAME_CHANGED = "lastname";

/** First Name Element */

private String firstName;

/** Last Name Element */

private String lastName;

/** Blank Constructor */

public CustomerModel()

{

super();

}

/**

* Sets the first name element. If value changed a notification is

* sent to all listeners of this property

* @param newFirstName String

*/

public void setFirstName(String newFirstName)

{

String oldFirstName = this.firstName;

this.firstName = newFirstName;

propertyChangeSupport.firePropertyChange(FIRST_NAME_CHANGED, oldFirstName, newFirstName);

}

/**

* @return String

*/

public String getFristName()

{

return firstName;

}

/**

* Sets the last name element. If value changed a notification is

* sent to all listeners of this property

* @param newFirstName String

*/

public void setLastName(String newLastName)

{

String oldLastName = this.lastName;

this.lastName = newLastName;

propertyChangeSupport.firePropertyChange(LAST_NAME_CHANGED, oldLastName, newLastName);

}

/**

* @return String

*/

public String getLastName()

{

return lastName;

}

/** Passthrough method for property change listener */

public void addPropertyChangeListener(String str, PropertyChangeListener pcl)

{

propertyChangeSupport.addPropertyChangeListener(str, pcl);

}

/** Passthrough method for property change listener */

public void removePropertyChangeListener(String str, PropertyChangeListener pcl)

{

propertyChangeSupport.removePropertyChangeListener(str, pcl);

}

}

******************************* CustomerFrame.java

import javax.swing.*;

import java.awt.event.*;

import java.awt.GridLayout;

import java.beans.PropertyChangeListener;

import java.beans.PropertyChangeEvent;

/** */

public class CustomerFrame extends JFrame implements ActionListener, PropertyChangeListener

{

/** Customer to view/control */

private CustomerModel customer;

/** */

private JLabel firstNameLabel = new JLabel("First Name: ");

/** */

private JTextField firstNameEdit = new JTextField();

/** */

private JLabel lastNameLabel = new JLabel("Last Name: ");

/** */

private JTextField lastNameEdit = new JTextField();

/** */

private JButton updateButton = new JButton("Update");

/**

* Constructor that takes a model

* @param customer CustomerModel

*/

public CustomerFrame(CustomerModel customer)

{

// setup this frame

this.setName("Customer Editor");

this.setTitle("Customer Editor");

this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

this.getContentPane().setLayout(new GridLayout(3, 2));

this.getContentPane().add(firstNameLabel);

this.getContentPane().add(firstNameEdit);

this.getContentPane().add(lastNameLabel);

this.getContentPane().add(lastNameEdit);

this.getContentPane().add(updateButton);

// reference the customer locally

this.customer = customer;

// register change listeners

this.customer.addPropertyChangeListener(CustomerModel.FIRST_NAME_CHANGED, this);

this.customer.addPropertyChangeListener(CustomerModel.LAST_NAME_CHANGED, this);

// setup the initial value with values from the model

firstNameEdit.setText(customer.getFristName());

lastNameEdit.setText(customer.getLastName());

// cause the update button to do something

updateButton.addActionListener(this);

// now display everything

this.pack();

this.setVisible(true);

}

/**

* Update the model when update button is clicked

* @param e ActionEvent

*/

public void actionPerformed(ActionEvent e)

{

customer.setFirstName(firstNameEdit.getText());

customer.setLastName(lastNameEdit.getText());

System.out.println("Update Clicked " + e);

}

/**

* Update the view when the model has changed

* @param evt PropertyChangeEvent

*/

public void propertyChange(PropertyChangeEvent evt)

{

if (evt.getPropertyName().equals(CustomerModel.FIRST_NAME_CHANGED))

{

firstNameEdit.setText((String)evt.getNewValue());

}

else if (evt.getPropertyName().equals(CustomerModel.LAST_NAME_CHANGED))

{

lastNameEdit.setText((String)evt.getNewValue());

}

}

}

******************************* MainFrame.java

import javax.swing.JFrame;

import java.awt.event.ActionListener;

import java.awt.event.ActionEvent;

import javax.swing.JButton;

/** */

public class MainFrame extends JFrame implements ActionListener

{

/** Single customer model to send to all spawned frames */

private CustomerModel model = new CustomerModel();

/** Button to click to spawn new frames */

private JButton newEditorButton = new JButton("New Editor");

/** Blank Constructor */

public MainFrame() {

super();

}

/** Create and display the GUI */

public void createAndDisplayGUI()

{

this.setName("MVC Spawner");

this.setTitle("MVC Spawner");

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.newEditorButton.addActionListener(this);

this.getContentPane().add(newEditorButton);

this.pack();

this.setVisible(true);

}

/** Do something when the button is clicked */

public void actionPerformed(ActionEvent e)

{

new CustomerFrame(model);

}

/**

* Creates the main frame to spawn customer edit frames from.

* @param args String[] ignored

*/

public static void main(String[] args) {

MainFrame mainframe = new MainFrame();

mainframe.createAndDisplayGUI();

}

}

CarmonColvina at 2007-7-16 22:19:06 > top of Java-index,Other Topics,Patterns & OO Design...