| ACartesianPlane.java |
package lectures.composite.objects_shapes;
import util.annotations.WebDocuments;
import util.annotations.StructurePattern;
import util.annotations.StructurePatternNames;
import lectures.graphics.ALine;
import lectures.graphics.AStringShape;
import lectures.graphics.Line;
import lectures.graphics.StringShape;
import bus.uigen.OEFrame;
import bus.uigen.ObjectEditor;
/*
* The purpose of this class is to draw a scalable Cartesian Plane with labeled X and
* Y axes.
*
* An editable AxesLength property can be used to magnify and shrink the plane.
*
*/
@StructurePattern(StructurePatternNames.BEAN_PATTERN)
@WebDocuments({"Lectures/CompositeObjectsShapes.pptx", "Lectures/CompositeObjectsShapes.pdf", "Videos/CompositeObjectsShapes.avi"})
public class ACartesianPlane implements CartesianPlane {
protected int originX, originY;
protected int axesLength;
protected Line xAxis;
protected Line yAxis;
protected StringShape xLabel;
protected StringShape yLabel;
/*
* ACartesianPlane has:
* a) only primitive components in its physical structure.
* b) only object components in its physical structure.
* c) both primitive and object components in its physical structure.
*/
public ACartesianPlane (int theAxesLength, int theOriginX, int theOriginY ) {
axesLength = theAxesLength;
originX = theOriginX;
originY = theOriginY;
/*
* Creating the initial structure based on the initial axeslength.
*/
xAxis = new ALine(toXAxisX(), toXAxisY(), axesLength, 0);
yAxis = new ALine(toYAxisX(), toYAxisY(), 0, axesLength);
xLabel = new AStringShape ("X", toXLabelX(), toXLabelY());
yLabel = new AStringShape ("Y", toYLabelX(), toYLabelY());
}
/*
* The constructor of ACartesianPlane:
* (a) does not initialize its object variables.
* (b) assigns its parameters to its object variables.
* (c) creates new instances and assigns them to its object variables.
*
*/
public Line getXAxis() {
System.out.println ("X Axis:" + xAxis);
return xAxis;
}
/*
* (T/F) getAxis() of ACartesianPlane creates and returns a new object each time
* it is called.
*/
public Line getYAxis() {
return yAxis;
}
public StringShape getXLabel() {
return xLabel;
}
public StringShape getYLabel() {
return yLabel;
}
public int getAxesLength() {
return axesLength;
}
/*
* setAxesLength modifies the graphical components to be consistent with
* the new axeslength.
*/
public void setAxesLength(int anAxesLength) {
System.out.println ("New axes length:" + anAxesLength);
axesLength = anAxesLength;
xAxis.setWidth(axesLength);
yAxis.setHeight(axesLength);
xAxis.setX(toXAxisX());
xAxis.setY(toXAxisY());
yAxis.setX(toYAxisX());
yAxis.setY(toYAxisY());
xLabel.setX(toXLabelX());
xLabel.setY(toXLabelY());
yLabel.setX(toYLabelX());
yLabel.setY(toYLabelY());
}
/*
* Calling setAxesLength in ACartesianPlane, changes the:
* (a) object variable xAxis, that is,
* assigns a new object to this variable.
* (b) primitive X property of the existing object stored in the xAxis variable.
* (c) None of the above.
*
* Calling setAxesLength in ACartesianPlane changes:
* (a) leaf nodes in the physical structure.
* (b) object nodes in the physical structure.
* (c) None of the above
*/
/*
* These methods are used for calculating the locations of the line and label objects
*/
protected int toXAxisX() {
return originX - axesLength/2;
}
protected int toXAxisY() {
return originY;
}
protected int toYAxisX() {
return originX;
}
protected int toYAxisY() {
return originY - axesLength/2;
}
protected int toXLabelX() {
return originX + axesLength/2;
}
protected int toXLabelY() {
return originY;
}
protected int toYLabelX() {
return originX;
}
protected int toYLabelY() {
return originY - axesLength/2;
}
public static void main (String[] args) {
CartesianPlane aCartesianPlane =
new ACartesianPlane(INIT_AXES_LENGTH, INIT_ORIGIN_X, INIT_ORIGIN_Y);
OEFrame anOEFrame = ObjectEditor.edit(aCartesianPlane);
anOEFrame.showTreePanel();
anOEFrame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
/*
* set a break point on setter call
*/
aCartesianPlane.setAxesLength(aCartesianPlane.getAxesLength()*2);
anOEFrame.refresh();
// to hide the main panel, you can execute
// anOEFrame.hideMainPanel();
}
}
/*
* Study the class and draw or imagine the logical and physical structure
* of the instance created by main.
*
* Which properties have setters?
*
* (T/F) AxesLength is a readonly property of ACartesianPlane.
*
* (T/F) XAxis is readonly property of ACartesianPlane.
*
* (T/F) All object properties of ACartesianPlane are readonly.
*
* (T/F) XAxis is a stored property of ACartesianPlane, that is, its value
* is stored in an instance variable.
*
* (T/F) In ACartesianPlane, each time a getter of an object property is called,
* a new object is returned.
*/
/*
*
* Run in debug mode and stop at the breakpoint, and step into the getter,
* step return, and then step into the setter.
*
* Look at the physical structure displayed by the debugger.
*
* (T/F) xAxesLength is a leaf variable of ACartesianPlane.
*
* (T/F) xAxis is a leaf variable of ACartesianPlane.
*
* Look at the logical structure displayed by ObjectEditor.
*
* Is the content of the graphics panel predicted?
*
* Is the content of the main panel predicted?
*
* (T/F) Every property of an object is displayed in the ObjectEditor tree panel.
*
* (T/F) Every property of an object is displayed in the main panel.
*
* (T/F) Every property of an object is displayed either in the main panel
* or the graphics panel.
*
* Resume the execution to see the behavior of the program.
* Edit the AxesLength to call setAxesLength and see the effect.
*
* When the setter above is called, did any of the leaf nodes change in the structure?
.
* Did any of the composite nodes change, that is, did they get new children or
* lose children?
*
* Look at the console output. Is it what you would predict.
*
* Look at the code in setAxesLength and getAxis and review your answers about it.
*
* The next example is more concise but also inefficient:
* AnInefficientCartesianPlane
*/