Java assignment Model View Controller (MVC) architecture Description Write a pro
ID: 3576003 • Letter: J
Question
Java assignment
Model View Controller (MVC) architecture
Description
Write a program that will show two different views of a rectangle: a DrawView and a TextView. DrawView will render a figure representation of the rectangle and TextView a numeric representation of the same rectangle. The DrawView will be a panel containing a drawing of the rectangle. The TextView will be a panel containing two text fields containing length and width values of the same rectangle. The program will keep the two representations in synch. The length and the width of the rectangle drawing in DrawView will be kept proportional to their numeric values in the TextView and vice versa. (See the figures below).
If the length and/or width numeric value is changed in the TextView, the lenght and/or width of the rectangle drawing in DrawView will change accordingly to reflect the change. Similarly, if length and/or width of the drawing in the DrawView is changed, the corresponding numeric values will change automatically to reflect the change.
The program will keep the two views in synch using a Model object. The Model object will not visually display anything. Instead, it will maintain the length and width properties of the rectangle and will help synchronize the values between the two views.
Usage
The user will alter length and/or width values of the rectangle in one of the following two ways.
Using TextView:
The user may change a rectangle by entering new length or width value in the corresponding text field of the TextView. When user enters a value in the textfield and presses the enter key, the drawing in the DrawView will change automatically to reflect the new value.
Using DrawView
The user may change a rectangle by redrawing it in the DrawView using the mouse click and drag mechanism. As the user, draws the new figure, the corresponding length and width numeric values will change automatically in TextView to reflect the change.
Implementation
Implement the above by providing the following classes.
MyPropertyChangeEvent event
Create a MyPropertyChangeEvent class that will contain the following:
A String field for keeping the property name.
An int for keeping the old value of the property.
An int for keeping the new value of the property.
MyPropertyChangeListener interface
Create an interface MyPropertyChangeListener which provides the following:
A single method myPropertyChange with a single parameter of type MyProppertyChangeEvent.
Model class
Create a class Model that will extend class Object and will provide the following:
An int property recLength for keeping length value.
An int property recWidth for keeping width value.
Get/Set methods for the above i.e. getRecLength, getRecWidth, setRecLength, and setRecWidth.
A registration method addMyPropertyChangeListener that would receive a single parameter of type MyPropertyChangeListener.
A deregistration method removeMyPropertyChangeListener.
An event firing method fireMyPropertyChange with a single parameter of type MyPropertyChangeEvent.
(This method will be called from setRecLength and setRecWidth methods).
TextView class
Create a TextView GUI class that extends JPanel and provide the following:
· Two TextFields:
It will provide one textfield for entering length and another one for entering width value. Also it will provide an event handler for each of the two text fields so that when the user enters a value in the text field ending with an enter key, the corresponding event handler will get invoked.
· MyPropertyChangeEvent Listener
It will provide functionality for behaving as a MyPropertyChangeEvent listener with the Model object as the source. For this purpose, it will implement MyPropertyChangeEventListener interface by providing the method myPropertyChange. It will register itself as a MyPropertyChangeListener listener with the Model object. It will do that in its setSource method described below.
DrawView class
Create a DrawView class (bean) that extends JPanel and provides the following:
· Dragging
It will provide functionality for calling setRecLength and setRecWidth methods when user drags the mouse.
· Draw Rectangle
It will provide the functionality for drawing a rectangle. It will draw the rectangle in its paintComponent method.
· PropertyChangeEvent Listener
It will provide functionality for behaving as a MyPropertyChangeEvent listener with the Model object as the source. For this purpose, it will implement MyPropertyChangeEventListener interface by providing the method myPropertyChange. It will register itself as a MyPropertyChangeListener listener with the Model object. It will do that in its setSource method described below.
Application
· Create an application containing the main ( ) method and an extended JFrame object.
· Drop an instance of the TextView bean in the upper (north) part of the extended JFrame.
· Drop an instance of the DrawView bean in the larger lower (center) part of the extended JFrame.
· Drop an instance of Model bean anywhere in the extended JFrame object.
· Using the TextView object’s property sheet, set its source property to the Model object’s reference as indicated below. (In JBuilder, setting this property in this way will automatically generate code in extended JFrame that will call the setSource method of the TextView object and pass it the reference of the Model object).
For setting source property, do the following:
Select the extended JFrame object and go into design view.
Select ContentPane of extended JFrame object.
(ContentPane property sheet will show).
Under the ContentPane, select TextView object.
(TextView object property sheet will show)
Select its Source property
Click the down arrow on the value side of this property.
(A menu with only one item listed, the name of the Model object, will drop down)
Select the only one listed menu item.
(The Model object is now selected as the source)
(Examine the code generated by your selection).
· Using the DrawView object’s property sheet, set its source property to the reference of the Model object as below. (Setting this property in this way will automatically generate code in extended JFrame that will call the setSource method of the TextView object and provide it the reference of the Model object).
For setting source property, do the following:
Select the extended JFrame object and go into design view.
Select ContentPane of extended JFrame object.
(ContentPane property sheet will show).
Under the ContentPane, select DrawView object.
(DrawView object property sheet will show)
Select its Source property
Click the down arrow on the value side of this property.
(A menu with only one item listed, the name of the Model object, will drop down)
Select the only one listed menu item.
(The Model object is now selected as the source)
(Examine the code generated by your selection).
Sample Code
public class MyPropertyChangeEvent {
String propertyName;
int oldValue;
int newValue;
public MyPropertyChangeEvent (String pn, int ov, int nv ){
propertyName = pn;
oldValue = ov;
newValue = nv;
}
public String getPropertyName ( ){
return propertyName;
}
public Object getOldValue (){
return oldValue;
}
public Object getNewValue (){
return newValue;
}
}
public interface MyPropertChangelListener {
public void myPropertyChange (MyPropertyChangeEvent ev);
}
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.util.Vector;
public class Model {
private int recLength;
private int recWidth;
private Vector myPropertyChangeListeners = new Vector();
public Model (int l, int w) {
recLength = l;
recWidth = w;
}
public void setRecLength (int l) {
MyPropertyChangeEvent me = new MyPropertyChangeEvent ("length",recLength,l);
recLength = l;
fireMyPropertyChanged (me);
}
public void setRecWidth (int w) {
MyPropertyChangeEvent me = new MyPropertyChangeEvent ("width",recWidth,w);
recWidth = w;
fireMyPropertyChanged (me);
}
public int getRecLength ( ) {
return recLength;
}
public int getRecWidth ( ) {
return recWidth;
}
public synchronized void fireMyPropertyChanged (MyPropertyChangeEvent ev ){
for (int i=0; i< myPropertyChangeListeners.size(); i++){
((MyPropertChangelListener)myPropertyChangeListeners.elementAt(i)).myPropertyChange(ev);
}
}
public synchronized void addMyPropertyChangeListener (MyPropertChangelListener ml){
if (!myPropertyChangeListeners.contains(ml)){
myPropertyChangeListeners.addElement(ml);
}
}
public synchronized void removeMyPropertyChangeListener (MyPropertChangelListener ml){
if (myPropertyChangeListeners.contains(ml)){
myPropertyChangeListeners.removeElement(ml);
}
}
}
public class DrawView extends JPanel
implements MyPropertChangelListener, MouseListener, MouseMotionListener {
private Model model;
private int xSaved;
private int ySaved;
public void setModel(Model model) {
this.model = model;
model.addMyPropertyChangeListener(this);
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
public void mousePressed(MouseEvent e) {
xSaved = e.getX();
ySaved = e.getY();
repaint();
}
public void mouseDragged(MouseEvent e) {
//This is the controller method
model.setRecLength(e.getX() - xSaved);
model.setRecWidth(e.getY() - ySaved);
}
public void myPropertyChange(MyPropertyChangeEvent ev) {
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(Math.min(xSaved, model.getRecLength()+ xSaved),
Math.min(ySaved, model.getRecWidth()+ ySaved),
Math.abs( model.getRecLength()),
Math.abs(model.getRecWidth()));
}
//TextView Sample Code
private Model model;
private JTextField jtfRecLength;
private JTextField jtfRecWidth;
public void setModel(Model model) {
this.model = model;
model.addMyPropertyChangeListener(this);
}
public void myPropertyChange(MyPropertyChangeEvent ev){
if (ev.propertyName.equalsIgnoreCase("length")){
jtfRecLength.setText(""+ev.getOldValue());
} else if (ev.propertyName.equalsIgnoreCase("width")){
jtfRecWidth.setText(""+ev.getNewValue());
}
}
}
Pictures
The pictures of the beans and the application frame are shown below.
Picture of the Model Bean
Has no picture. It is not a JPanel.
Picture of TextView Bean width: Length Picture of DrawView BeanExplanation / Answer
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Iterator;
public class Mod {
private ArrayList<Rectangle> rectangles = new ArrayList<Rectangle>();
private ArrayList<ModChangedEventListener> listeners = new ArrayList<ModChangedEventListener>();
public void addRectangle(int x, int y, int width, int height) {
rectangles.add(new Rectangle(x, y, width, height));
ModChangedEvent();
}
public ArrayList<Rectangle> getRectangles() {
return rectangles;
}
public synchronized void addModChangedListener(
ModChangedEventListener listener) {
listeners.add(listener);
}
public synchronized void removeModChangedListener(
ModChangedEventListener listener) {
listeners.remove(listener);
}
private synchronized void ModChangedEvent() {
ModChangeEvent event = new ModChangeEvent(this);
Iterator<ModChangedEventListener> i = listeners.iterator();
while (i.hasNext()) {
((ModChangedEventListener) i.next()).handleModChange(event);
}
}
}
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.EventObject;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class View extends JFrame implements ModChangedEventListener {
private static final int DISPLAY_WIDTH = 500;
private static final int DISPLAY_HEIGHT = 500;
private ViewPanel viewPanel;
private Cont controller;
public View(Cont controller)
{
this.controller = controller;
setSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container contentPane = getContentPane();
viewPanel = new ViewPanel();
contentPane.add(viewPanel);
setVisible(true);
}
@Override
public void handleModelChange(EventObject e) {
viewPanel.repaint();
}
@Override
public void handleModChange(ModChangeEvent event) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public class ViewPanel extends JPanel implements MouseListener {
public ViewPanel() {
addMouseListener(this);
}
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
controller.draw(g2);
}
@Override
public void mouseClicked(MouseEvent arg0) {
controller.click(arg0.getX(), arg0.getY());
}
@Override
public void mouseEntered(MouseEvent arg0) {
}
@Override
public void mouseExited(MouseEvent arg0) {
}
@Override
public void mousePressed(MouseEvent arg0) {
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
}
}
import java.awt.Graphics2D;
import java.awt.Rectangle;
public class Cont {
private Mod m;
public Cont(Mod m) {
this.m = m;
}
public void click(int x, int y) {
m.addRectangle(x, y, 250, 250);
}
public void draw(Graphics2D g2) {
for (Rectangle rectangle : m.getRectangles()) {
g2.draw(rectangle);
}
}
}
public class ModChangeEvent extends java.util.EventObject {
private static final long serialVersionUID = 1L;
public ModChangeEvent(Object source) {
super(source);
}
}
import java.util.EventObject;
public interface ModChangedEventListener
{
public void handleModelChange(EventObject e);
public void handleModChange(ModChangeEvent event);
}
public class Test {
public static void main(String[] args) {
Mod model = new Mod();
Cont controller = new Cont(model);
View view = new View(controller);
model.addModChangedListener(view);
}
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.