|
||||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
Interface Summary | |
ModelSupport | |
PresentationModelIF | A presentation model is both a producer of and consumer of events. |
QueueElement | |
WindowModelIF |
Class Summary | |
ApplicationBootstrap | |
AsynchStatusManager | Set the default status manager to be an instance of this class if you wish to support asynchronous events. |
ConfigurationProperties | A utility class that will load property information in from a property file. |
EventPool | Any events generated by any of the Producers will be passed on to all PresentationModel consumers. |
EventSupport | Used to facilitate Events. |
PresentationModel | |
Queue | An event queue. |
UIManager | This class actually handles the frame/dialog opening, frame/dialog closing, and system exit functions of the application. |
WindowModel | A window model is different from a presentation model in that it holds the common event pool. |
An attempt to capture some common application architecture related code, such as: Screen Flow, Security, and application initialization.
When an application begins, there are set of core initialization routines that may need execution. After we initialize all aspects of our application, we typically need to Logon to our system. Once we have sucessfully logged into our system, we open the main screen of the application. Application is launched!
Many of the initialization routines are quite common. There exists a class com.objectwave.appArch.security.StartupRoutine
that contains the common functions necessary at startup. Here are the functions most commonly used:
setLookAndFeel()
is used to set the look and feel of the application
to WindowLookAndFeel. This method exists to provide compatability between different Swing versions. Eventually,
this will no longer be needed.
loadDefaults(Object)
will load in a properties resource. This properties
resource will be obtained with the java.lang.Class>>getResourceAsStream(String) method, hence the reason
it takes an argument. The Object argument should either be a class or an object, and this argument will be used
when locating the resource. The String is the ini file name. You can also call the loadDefaults(Object, String)
method to both load the speficied resource and set the static StartupRoutine variable 'ini'. This variable is the
initialization file name.
initPersistence(String [])
is a common way to setup all of the necessary
persistence related information. If the parameter is empty, then there is nothing special about the persistence.
If the parameter contains at least one value, that value is expected to the name of a serialized object pool. If
the object pool is located, then we will NOT connect to the database. Our default Broker will be the ObjectPoolBroker.
If object pool is not found, we connect to the database and begin using the object pool support. When the application
is exited, the object pool is written to the provided file name.
logExceptionsToFile(String fileName)
. The name of this method says it
all. Write any exceptions that occur in the named file.
manageTransactionWithScreenActivation()
This call will cause our setContext
method to be called on the TransactionLog with a parameter of what every screen is activated. This can be VERY
useful if screens define the beginning and end of a Transaction.
This process is mix of custom application specific code, and some generic Logon support. The com.objectwave.uiWidget.LoginDialog contains a UserName and Password text fields. When the Dialog is closed, it fires a com.objectwave.uiWidget.LoginEvent. Every associated com.objectwave.uiWidget.LoginListener receives this event, however, what is done with the event is application specific. This class validates the login in some manor, and in some way communicates the success or failure of the login with the launching application class.
To open a screen that is adhering to the PresentationModel design approach, requires some setup.
We have implemented an Event based approach for all interaction between various screens. This minimized coupling between our screens and our various panels allowing the developer to use those screens and sub panels that accomplish what is needed. This eliminated many dependencies of one screen upon another, and allows the developer to change the look and feel of the application, without impact on the behavior. To fully understand the presentation model you need a firm grasp of Java's AWT event model, since our event approach is very similar. The com.objectwave.appArch.PresentationModel for a given class can also be referred to as the 'controller' object, since it manages the interaction between the business model and the User Interface.
Let's look at an example.
Every PresentationModel(PM) can produce events (fireEvents) or consume events (respond to packetAvailable method
calls). It is with these events that a PM interacts with the rest of the system. A PM may have 1, many, or no consumers
attached to it. And a given PM may or may not be a producer to any other PM. This is the loose coupling that our
Event model provides. Hence, if we wish to change the system, or reuse a component in a another part of the system,
we merely need to hook up the PMs and fire the appropriate events.
( a java.awt.Component ) |
||||
/\ |
-- has a -> | PresentationModel --> | has many > | Consumers |
{ (a Custom UI) } |
|
has many > |
Producers |
|
implements ModelSupport |
|
|
Upon the creation of a composite component (one that has many components implementing ModelSupport) the code would typically go like this.
{
comp = new SubComponet();
this
.add(comp);
ModelSupport supp = (ModelSupport)comp;
PresenationModel pm = supp.getPresentationModel();
this
.getPresentationModel().addPresentationModel(pm);
}
When using the '
PresentationModel>>addPresentationModel(PresenationModel
pm)
'
method the parameter 'pm' is added as both a consumer and a producer to the receiving
presentation model. If you wish to 'hear' events from another presentation model, but not allow the other presentation
model to 'hear' your events, use the PresentationModel>>addProducer(PresenationModel
pm)
method.
The PresentationModel>>addConsumer(PresenationModel pm)
method would allow the parameter 'pm' to hear my events, but I won't hear any of the parameter's
events.
Since many objects may produce and consume the same events, it is important that the objects are 'hooked' up correctly. Strange, or inconsistent, behavior may occur if your events are delivered to listeners that you may not suspect.
Most of our Composite Components may wish to avoid connecting one PM to another PM and instead place all PMs into a common pool. The com.objectwave.appArch.EventPool class provides this behavior. Any event generated from one of the PMs in the event pool will be delivered to each and every PM in the pool (other than the source PM). Since this is common situation when creating Frames we have specialized PresentationModel that automatically places elements into the Pool called com.objectwave.appArch.WindowModel. In addition to providing pool support, the WindowModel class provides listeners to handle the open(), and closing() of a frame.
The actual setVisible(true) call comes from the com.objectwave.appArch.UIManager
class. All windows (be them Dialogs or Frames) should be opened with the UIManager. Failure to do so eliminates
our ability to actively manage screen navigation and controlled system exits.
To exit the application our code will do something like the following
try {
UIManager.getDefaultManager().exitApplication();
} catch (PropertyVetoException e)
{ System.out.println("Exit was vetoed for some reason!");
}
By using the UIManager to exit the application, you are giving all of the registered PropertyVetoListeners a chance
to Veto the system exit. The property name will be SystemExit when the firePropertyVetoChange method is called.
|
||||||||||
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |