objecteditor prasun dewan comp 114. objecteditor automatic user-interface generation. you only write...

96
ObjectEditor Prasun Dewan Comp 114

Post on 21-Dec-2015

219 views

Category:

Documents


0 download

TRANSCRIPT

ObjectEditor

Prasun Dewan

Comp 114

ObjectEditor

• Automatic user-interface generation.

• You only write computation code

• Separate object to do I/O

• Main just instantiates it

• Can replace it with own UI later.

• Serves as training wheels

• Serves to separate UI from computation

Example Class

package bmi;public class ABMICalculator implements BMICalculator {

public double calculateBMI (double weight, double height) {return weight/(height*height);

}}

Example Main Class

package main;import bus.uigen.ObjectEditor;import bmi.ABMICalculator;public class ABMIDisplayer {

public static void main(String[] args) {ObjectEditor.edit(new ABMICalculator());

}}

ABMICalculator UI

ABMICalculator UI

Adding a library in JBuilder

Adding a library in JBuilder

Adding a library in JBuilder

Adding a library in JBuilder

Adding a library in JBuilder

Adding a library in JBuilder

Adding a library in JBuilder

Location of Libraries• http://www.cs.unc.edu/~dewan/oe• Use Internet explorer (not Netscape) to download

files• Library names

– oe.jar – shapes.jar

• oe2.jar version 2 of oe.jar• Try oe2 first and in case of bugs use oe.jar• oe.jar used by comp14 students• oe has lots of bugs!• Send me mail for workarounds bugs.

Location of Libraries

What-if BMI Calculations

Unchanging value retyped

BMI Spreadsheet

State: Data Remembered by an Object between computations

Instance VariablesABMICalculator Instance

calculateBMI

Parameters

Body

accesses

ABMISpreadsheet Instance

getBMI

InstanceVariables

Body accesses

Belong to a single method

Belong to all methods of an instance

local variable global variable

State-less Vs State-ful Objects

~ car radios without presets

~ car radios with presets

Identical Instances

Different Instances

ABMISpreadsheetpublic class ABMISpreadsheet {

double height, weight;public double getHeight() {

return height;}public void setHeight(double newHeight) {

height = newHeight;}public double getWeight() {

return weight;}public void setWeight(double newWeight) {

weight = newWeight;}public double getBMI() {

return weight/(height*height);}

}

Height

Weight

BMI

public class C {

}

Read-Only and Editable Properties

public T getP() { ...}

Typed, Named Unit of Exported Object State

Name: P

Type: T

Readonlypublic void setP(T newValue) { ...}

Editable

newP

obtainPViolates Bean Conventions

Bean

Conventions for

•humans

•tools

Getter methodSetter method

Properties Classificationpublic class ABMISpreadsheet {

double height;public double getHeight() {

return height;}public void setHeight(double newHeight) {

height = newHeight;}double weight;public double getWeight() {

return weight;}public void setWeight(double newWeight) {

weight = newWeight;}public double getBMI() {

return weight/(height*height);}

Height

Weight

BMI

Editable

Editable

Read-only

Independent

Independent

Dependent

Read-Only

Calling Getter and Setter Methods

• When ObjectEditor window is created

•Getter method of each property called to display initial value of property

• When property is changed to a new value

•Setter method of property is called with new value as actual parameter

•Getter method of each property is called to refresh display

Calling Getter and Setter Methodspublic class ABMISpreadsheet {

double height = 1.77;public double getHeight() {

return height;}public void setHeight(double newHeight) {

height = newHeight;}double weight = 77;public double getWeight() {

return weight;}public void setWeight(double newWeight) {

weight = newWeight;}public double getBMI() {

return weight/(height*height);}

}

Tracing Method Callspublic class ABMISpreadsheet {

double height = 1.77;public double getHeight() {

System.out.println (“getHeight Called”);return height;

}public void setHeight(double newHeight) {

System.out.println (“setWeight Called”);height = newHeight;

}double weight = 77;public double getWeight() {

System.out.println (“getWeight Called”);

return weight;}public void setWeight(double newWeight) {

System.out.println (“setWeight Called”);weight = newWeight;

}public double getBMI() {

System.out.println (“getBMI Called”);return weight/(height*height);

}}

Actual Trace

Modified ABMISpreadsheetpublic class ABMISpreadsheet {

double height, weight;public double getHeight() {

return height;}public void setHeight(double newHeight) {

height = newHeight;}public double getWeight() {

return weight;}public void setWeight(double newWeight) {

weight = newWeight;}public double getBMI() {

return calculateBMI(weight, height);}public double calculateBMI(double weight, double height) {

return weight / (height*height);|

}

How will above UI change?

Properties + Class Menu

Editing in slow motion : Initial value

Editing in slow motion: text string edited

Editing in slow motion: return triggers setter and getter calls

Renaming getter methodpublic class ABMISpreadsheet {

double height, weight;public double height() {

return height;}public void setHeight(double newHeight) {

height = newHeight;}public double getWeight() {

return weight;}public void setWeight(double newWeight) {

weight = newWeight;}public double getBMI() {

return calculateBMI(weight, height);}public double calculateBMI(double weight, double height) {

return weight / (height*height);|

}

ObjectEditor does not know it is getter

Reducing Accesspublic class ABMISpreadsheet {

double height, weight;double getHeight() {

return height;}public void setHeight(double newHeight) {

height = newHeight;}public double getWeight() {

return weight;}public void setWeight(double newWeight) {

weight = newWeight;}public double getBMI() {

return calculateBMI(weight, height);}public double calculateBMI(double weight, double height) {

return weight / (height*height);|

}

Height is not a readable property

Changing setterpublic class ABMISpreadsheet {

double height, weight;public double getHeight() {

return height;}public int setHeight(double newHeight) {

height = newHeight;return height;

}public double getWeight() {

return weight;}public void setWeight(double newWeight) {

weight = newWeight;}public double getBMI() {

return calculateBMI(weight, height);}public double calculateBMI(double weight, double height) {

return weight / (height*height);|

}

Height is not a writeable property

An alternative class

public class AStringHistory implements StringHistory { public static final int MAX_SIZE = 50; String[] contents = new String[MAX_SIZE]; int size = 0; public int size() { return size;} public String elementAt (int index) { return contents[index]; } boolean isFull() { return size == MAX_SIZE; } public void addElement(String element) { if (isFull())

System.out.println("Adding item to a full history"); else {

contents[size] = element; size++;}

} }

Variable number of dynamically created indexed properties

ObjectEditor Conventions for Variable-Sized Collection

public interface I {public void addElement (T t);public T elementAt (int index);

public int size();}

Arbitrary Type

(Must be Object Type to be

recognized by ObjectEditor)

Read methods

Write method

(name does not matter to OE)

Initial State

Adding an element

Name does not matter to ObjectEditor

Adding an element

Adding an element

ObjectEditor calls all elementAt () and getter() methods after each method call

Adding another element

Adding another element

Public Class Constants

Public Class Constants

Non Public Class Constant

public class AStringHistory implements StringHistory { static final int MAX_SIZE = 50; String[] contents = new String[MAX_SIZE]; int size = 0; public int size() { return size;} public String elementAt (int index) { return contents[index]; } boolean isFull() { return size == MAX_SIZE; } public void addElement(String element) { if (isFull())

System.out.println("Adding item to a full history"); else {

contents[size] = element; size++;}

} }

Non-Public Class Constant

Non constants menu

Public Instance Constant

public class AStringHistory implements StringHistory { public final int MAX_SIZE = 50; String[] contents = new String[MAX_SIZE]; int size = 0; public int size() { return size;} public String elementAt (int index) { return contents[index]; } boolean isFull() { return size == MAX_SIZE; } public void addElement(String element) { if (isFull())

System.out.println("Adding item to a full history"); else {

contents[size] = element; size++;}

} }

Public Instance Constant

Public instance variables also displayed.

Considered part of displayable instance state.

Breaking of encapsulation is visible in the display!

Mixing static and dynamic properties

Mixing static and dynamic properties

Mixing static and dynamic properties

Another UI

Another UI

Another UI

New Class (edit)

public class AStringHistory implements StringHistory { public static final int MAX_SIZE = 50; String[] contents = new String[MAX_SIZE]; int size = 0; public int size() { return size;} public String elementAt (int index) { return contents[index]; } boolean isFull() { return size == MAX_SIZE; } public void addElement(String element) { if (isFull())

System.out.println("Adding item to a full history"); else {

contents[size] = element; size++;}

} }

New Class (edited)

public class AStringHistory implements StringHistory { public static final int MAX_SIZE = 50; String[] contents = new String[MAX_SIZE]; int size = 0; public int size() { return size;} public String elementAt (int index) { return contents[index]; } boolean isFull() { return size == MAX_SIZE; }

String newString = “”; public String getNewString() {return newString;} public void setNewString(String newVal) {

addElement(newVal);newString = newVal;}….

}

New Classpublic class AStringHistory implements StringHistory {

String newString = "";public void setNewString(String newVal ) {

newString = newVal;addElement(newString);

}public String getNewString() {

return newString;}

public static final int MAX_SIZE = 50; String[] contents = new String[MAX_SIZE]; int size = 0; public int size() { return size;} public String elementAt (int index) { return contents[index]; } boolean isFull() { return size == MAX_SIZE; } public void addElement(String element) { …

} }

Uninitialized propertiespublic class AStringHistory implements StringHistory {

String newString;public void setNewString(String newVal ) {

newString = newVal;addElement(newString);

}public String getNewString() {

return newString;}

public static final int MAX_SIZE = 50; String[] contents = new String[MAX_SIZE]; int size = 0; public int size() { return size;} public String elementAt (int index) { return contents[index]; } boolean isFull() { return size == MAX_SIZE; } public void addElement(String element) { …

} }

Uninitialized properties

Non-public size()public class AStringHistory implements StringHistory {

String newString;public void setNewString(String newVal ) {

newString = newVal;addElement(newString);

}public String getNewString() {

return newString;}

public static final int MAX_SIZE = 50; String[] contents = new String[MAX_SIZE]; int size = 0; int size() { return size;} public String elementAt (int index) { return contents[index]; } boolean isFull() { return size == MAX_SIZE; } public void addElement(String element) { …

} }

Non-public size()

ObjectEditor discovers only one fixed property

“Recursion” in ObjectEditing

package main;import bus.uigen.ObjectEditor;public class AnObectEditorDisplayer {

public static void main(String[] args) {ObjectEditor.edit(new ObjectEditor());

}}

ObjectEditor Properties

ObjectEditor Properties and Commands

Newly instantiated and displayed object

Bean Methods

Getters and setters shown in separate menu

Usually invoked implicitly as side effect of editing

“Recursion” in ObjectEditing

package main;import bus.uigen.ObjectEditor;public class AnObectEditorDisplayer {

public static void main(String[] args) {ObjectEditor.edit(new ObjectEditor());

}}

Application-independent!

ObjectEditor has a main method that does this automatically!

Running ObjectEditor

java bus.uigen.ObjectEditor

= ObjectEditor.edit(new ObjectEditor())

java bus.uigen.ObjectEditor C

= ObjectEditor.edit (new C())

Running ObjectEditor Main

Running ObjectEditor Main

Running ObjectEditor Main

Running ObjectEditor Main

Running ObjectEditor Main

Object parameters

Object parameters

Object parameters

Object parameters

Object parameters

Object parameters

Object parameters

Object parameters

Object parameters

Object parameters

Object parameters

Object parameters

Object parameters

Constructors with parameters

Constructors with parameters

Interface

Constructors with parameters

Constructors with parameters

Constructors with parameters

Constructors with parameters

Constructors with parameters