Any method within a naked object that is prefixed with 'action',
and that returns either a NakedObject type or
void , is made available to the user. Methods defined this
way that take no arguments are displayed on the object's pop-up menu, as
shown in the example below. The name used on the menu defaults to the
method name stripped of its prefix and with spaces added where uppercase
characters are found.
Methods that take a single parameter (which must be of the type
NakedObject ) are made available through drag and drop
gestures.
When one of these action methods returns a non-null value, the
framework will attempt to show that returned object to the user -
typically in a new window. This is indicated on the pop-up menu by an
ellipsis (...) being added to the menu name, e.g. the Return
Booking... option shown above will display a new object, whereas
Check Availability won't.
Instance methods
A typical action method (taken from the City class)
is shown below. It creates a new Location object and
sets its city field so it refers to the city object that the method
was called on. This newly created and persisted object is then
returned to the user. This method shows itself as New
Location... on the city's pop-up menu and is invoked when
that menu item is selected.
public Location actionNewLocation() {
Location loc = (Location) createInstance(Location.class);
loc.setCity(this);
return loc;
}
The next method (taken from the Location class)
creates a new booking object. This method requires another location
object to be provided as an argument, so that it can set up both the
new booking's pick up and drop off fields. This method is invoked by
dropping one location object onto another.
public Booking actionNewBooking(Location location) {
Booking booking = (Booking) createInstance(Booking.class);
Customer customer = location.getCustomer();
booking.setPickUp(location);
booking.setDropOff(this);
if (customer != null) {
booking.setCustomer(customer);
booking.setPaymentMethod(customer.getPreferredPaymentMethod());
}
booking.setCity(location.getCity());
return booking;
}
On the screenshot below you can see the dragged object, whose
title and labels have changed to purple; the object it was dropped
on, whose title and labels flash green to indicate a valid
drop; and the resulting new booking with its Customer,
Pick Up, Drop Off and
City fields set up using the information from the two
objects involved in the invoked method.
Most often, action methods are used to change the state of an
object. This example from the Booking class changes
the status value object and then associates the
pickUp and dropOff
locations, and the paymentMethod used in the
newly-confirmed booking directly with the existing customer object
that the booking was made for - so that they can easily be re-used
in a future booking for that customer. Note that this method does not
return anything; it only changes the state of the two objects:
public void actionConfirm() {
getStatus().setValue("Confirmed");
getCustomer().associateLocations(getPickUp());
getCustomer().associateLocations(getDropOff());
if (getCustomer().getPreferredPaymentMethod() == null) {
getCustomer().setPreferredPaymentMethod(getPaymentMethod());
}
}
Disabling methods
Action methods may be rendered unavailable because a user lacks
appropriate authority, or the object is not in an appropriate state,
or because of some other business rule. The availability of an
action... method can be controlled by adding a
corresponding about... method. This method must
return an About object, have the same method name with
'about' prefixed, and have exactly the same parameter list. The
following code shows two action... methods and their
about... methods. The first makes the
NewLocation method available if the
city field contains something. The second
disables the NewBooking method if the location that
will be used to invoke the action method is the same location as the
one the method will be invoked on, i.e. if the user attempts to drop
the location object onto itself.
public Location actionNewLocation() {}
public About aboutActionNewLocation() {
if(city.isEmpty()) {
return ActionAbout.DISABLE;
} else {
return ActionAbout.ENABLE;
}
}
public Booking actionNewBooking(Location location) {}
public About aboutActionNewBooking(Location location) {
return ActionAbout.disable(location.equals(this));
}
When an about... method disables a
zero-parameter action method, that method is greyed out on
the object's menu.
When it disables a one-parameter method, the framework will flash
the target object red as the user tries to drag an object (even of
the right type) over it.
Method ordering
The ordering of listed methods, particularly for menu items
displayed on an object's pop-up menu, is based on the array of action
methods that is produced by Java's reflection mechanism. The
ordering, therefore, is dependent on how the JVM you are running
collects the data about your class, and you have no direct
control over this. You may, however, specify an order within your
class definition, which the viewing mechanism can then interpret.
This is done by adding a static method called actionOrder
that returns a String listing the names derived
from the methods separated by commas. These need to be the reflected
names and not the method identifiers. For example the string 'Call
Back' would be used to refer to the actionCallBack
method. (Case is ignored.)
The following example from the Booking class
specifies a suitable order for its action methods:
public static String actionOrder() {
return "Check Availability, Confirm, Copy Booking, Return Booking";
}
Any listed name that does not match a method is simply ignored,
and methods that are not listed will be placed after all
the specified methods.
Class methods
It is also possible to write methods that are invoked on a class
rather than on a specific instance. These can be used to find
instances that match given criteria - for example, to find bookings
that use a specific location; or to create one object based on
another, such as a city being used to create a new location in
that city.
The same principles apply when defining such a method, but the method
is declared as static. The following shows a typical
class method (within the Booking class) that creates a
new booking for a customer. This would be invoked by dropping a
customer object onto the Bookings class and would
result in a new booking being returned in a new window:
public static Booking actionNewBooking(Customer customer) {
Booking newBooking = (Booking) createInstance(Booking.class);
newBooking.setCustomer(customer);
newBooking.setPaymentMethod(customer.getPreferredPaymentMethod());
return newBooking;
}
Class method ordering
You can order class methods in the same manner as
instance methods, but using the static method called
classActionOrder .
|