Application and Frame Classes
The starting points for a YASL application (see note) are the application class and the frame class.
Application Class
The application class extends org.yasl.arch.impl.application.YASLApplicationBase and implements the main() method.
The following must occur in the main() method:
- Create an instance of the the frame class.
- Create an instance of YASLSwingApplication. This interface is implemented by YASLSwingApplicationImpl and takes the frame class instance in its constructor.
- Create an instance of the application class, passing the YASLSwingApplication instance to the constructor.
- Call the
startApplication()method on the application instance. At a minimum, this method makes a call to the frame class to init the user interface and callssetVisible(true)on the associated JFrame instance. A minimal version of this method is implemented in YASLApplicationBase. Most applications will not need to override this method.
The sample code below is drawn from the YASL Test Application which is used for architecture and component testing.
public class YASLTestApplication
extends YASLApplicationBase {
private YASLTestApplication(YASLSwingApplication swingApp)
throws YASLApplicationException {
super(swingApp,
"/org/yasl/testapp/config/yaslTestAppConfig.xml");
}
public static void main(String[] args) {
try {
// create frame and app
YASLTestAppFrame appFrame =
new YASLTestAppFrame("/org/yasl/testapp/config/yaslTestAppMenuConfig.xml");
YASLSwingApplication swingApp = new YASLSwingApplicationImpl(appFrame);
YASLTestApplication application = new YASLTestApplication(swingApp);
// start application
application.startApplication();
}
// exceptions should be caught before this point
// any exception that reaches this catch is catastrophic
catch (Exception ex) {
ex.printStackTrace();
}
}
}
YASLApplicationBase
The constructor for YASLTestApplication passes an instance of YASLSwingApplication and the fully-qualified name for an xml config file to the YASLApplicationBase constructor. Applications can be configured from xml files, code, or both. The xml config file passed to YASLApplicationBase configures the singletons and actions that the application will use. (See Actions and Singletons and XML Config for Singletons and Actions for detailed information.)
All constructors for YASLApplicationBase eventually call the constructor displayed below. The constructor performs the following steps:
- Sets the application instance in the singleton map using the key
YASLApplication.KEY_APPLICATION. - Tries to initialize the application's singletons and actions from an xml config file.
- Calls
setSingletons()andsetActions(). The default implementations of these methods do nothing. To configure from code, the Application Class must override these methods. - Invokes the action mapped to the
YASLApplication.KEY_ACTION_APPLICATION_STARTkey if one is available. This action handles any initialization that the application needs to perform before presenting the UI to the user. Examples include reading preferences from a properties file or loading information from xml files.
private YASLApplicationBase(YASLApplication app,
String configFileName,
File configFile)
throws YASLApplicationException {
if (app == null) {
throw new YASLApplicationException("app cannot be null");
}
this.app = app;
this.app.setSingleton(YASLApplication.KEY_APPLICATION,
app);
if (configFileName != null) {
ConfigUtils.initFromConfigFile(
new YASLConfigContentHandler(app),
ConfigUtils.getInputSource(configFileName));
}
else if (configFile != null) {
ConfigUtils.initFromConfigFile(
new YASLConfigContentHandler(app),
ConfigUtils.getInputSource(configFile));
}
// Call these methods after trying to config based on an
// xml config file.
setSingletons();
setActions();
// Call application start action to perform other types
// of initialization
Action action = (Action)app.getActionHandler().getActionByKey(
YASLApplication.KEY_ACTION_APPLICATION_START);
if(action != null) {
action.actionPerformed(null);
}
}
The startApplication method handles initializing the the user interface and starting the JFrame instance.
public void startApplication() throws Exception {
YASLApplicationType appType = app.getApplicationType();
switch (appType.getId()) {
case YASLApplicationType.APP_TYPE_ID_SWING:
YASLSwingApplication swingApp = getSwingApplication();
swingApp.getSwingAppFrame().initUI();
swingApp.getJFrame().setVisible(true);
break;
case YASLApplicationType.APP_TYPE_ID_APPLET:
// no op
break;
case YASLApplicationType.APP_TYPE_ID_CMMNDLINE:
// no op
break;
}
}
Frame Class
The frame class extends org.yasl.arch.impl.application.YASLSwingAppFrameImpl and is primarily responsible for handling menu initialization. The menu details are coded in an xml config file (see XML Config for Menus for detailed information) while the work of reading the config file is handled by the parent class (YASLSwingAppFrameImpl). The frame class need only pass the xml config file to its parent's constructor. Other tasks include:
- Setting the title bar text.
- Initializing the frame's display.
- Setting the menu bar.
These tasks are handled in the initUI(Map menuBarMap, Map menuMap) method. This is an abstract method in YASLSwingAppFrameImpl so frame classes must override it. The method is called by YASLSwingAppFrameImpl from its initUI() method. The map arguments passed into this method are created from the menu xml config file.
If you do not handle menu configuration via an xml file, then you should create and set your menus in the initUI(Map menuBarMap, Map menuMap) method.
The sample code below is drawn from the frame class associated with the YASL Test Application.
public YASLTestAppFrame(String menuConfigFileName) {
super(menuConfigFileName);
}
protected void initUI(Map menuBarMap, Map menuMap)
throws Exception {
YASLSwingApplication yaslSwingApp = getSwingApplication();
// set resource manager
YASLResourceManager rmanager = yaslSwingApp.getResourceManager();
// set title bar text
this.setTitle(rmanager.getString(AppConstants.BUNDLE_GUI_STRINGS,
"app.title.bar"));
// get and set menubar
JMenuBar menuBar = (JMenuBar) menuBarMap.get("main_menubar");
this.setJMenuBar(menuBar);
}
YASLSwingAppFrame
This interface defines the methods that a frame class must implement in order to work with other classes in the architecture. It is implemented by YASLSwingAppFrameImpl.
public interface YASLSwingAppFrame {
/**
* Initializes the application menus and other parts of the
* application's GUI.
*
* @throws Exception
*/
public void initUI()
throws Exception;
/**
* Returns the swing application instance associated with
* this frame.
*
* @return YASLSwingApplication
*/
public YASLSwingApplication getSwingApplication();
/**
* Returns this frame as a JFrame.
*
* @return JFrame
*/
public JFrame getJFrame();
}
YASLSwingAppFrameImpl
YASLSwingAppFrameImpl is the base class for frame classes. It extends javax.swing.JFrame and implements YASLSwingAppFrame and java.awt.event.WindowListener. Its primary responsibilities are:
- Processing the xml menu config file.
- Handling window closing events.
The first task is handled in the initUI() method. After processing the xml config file, YASLSwingAppFrameImpl calls initUI(Map menuBarMap, Map menuMap) passing the menuBar and menu maps created during the xml processing. The initUI() method is final.
The second task is handled in the windowClosing(WindowEvent e) method. This method is invoked when the user attempts to close the window from the window's system menu. If an action has been mapped to YASLApplication.KEY_ACTION_APPLICATION_EXIT, the action will be invoked.
public final void initUI()
throws Exception {
YASLMenuConfigContentHandler contentHandler =
new YASLMenuConfigContentHandler(swingApp);
if (menuConfigFileName != null) {
ConfigUtils.initFromConfigFile(
contentHandler,
ConfigUtils.getInputSource(menuConfigFileName));
}
else if (menuConfigFile != null) {
ConfigUtils.initFromConfigFile(
contentHandler,
ConfigUtils.getInputSource(menuConfigFile));
}
initUI(contentHandler.getMenuBarMap(),
contentHandler.getMenuMap());
}
/**
* Invoked when the user attempts to close the window
* from the window's system menu. If the program does not
* explicitly hide or dispose the window while processing
* this event, the window close operation will be cancelled.
*/
public void windowClosing(WindowEvent e) {
try {
Action exitAction = swingApp.getActionHandler().getActionByKey(
swingApp.KEY_ACTION_APPLICATION_EXIT);
exitAction.actionPerformed(null);
}
catch (YASLApplicationException ex) {
// log this and exit??
}
}
Note: YASL can be used to write console applications, desktop applications, and applets. Unless otherwise noted, the documentation will focus on desktop applications.
