Application Client

Sometimes, enterprise applications use a stand-alone client application for handling tasks such as system or application administration. For example, the Duke's Bank application uses an application client to administer customers and accounts. This capability is useful in the event that the site becomes inaccessible for any reason or if a customer prefers to communicate things such as changes to account information by phone.

The application client shown in Figure 36-4 handles basic customer and account administration for the banking application through a Swing user interface. The bank administrator can perform any of the following functions by making menu selections.

Duke's Bank Application Client

Figure 36-4 Application Client

Customer administration:

Account administration:

Error and informational messages appear in the left pane under Application message watch:, and data is entered and displayed in the right pane.

The Classes and Their Relationships

The source code for the application client is in the <INSTALL>/j2eetutorial14/examples/bank/src/com/sun/ebank/appclient/ directory. The application client is divided into three classes: BankAdmin, EventHandle, and DataModel; the relationships among the classes are depicted in Figure 36-5.

Application Client Class Relationships

Figure 36-5 Relationships among Application Client Classes

BankAdmin builds the initial user interface, creates the EventHandle object, and provides methods for the EventHandle and DataModel objects to call when they update the user interface.

EventHandle listens for button clicks by the user, takes action based on which button the user clicks, creates the DataModel object, calls methods in the DataModel object to write data to and read data from the enterprise beans, and calls methods in the BankAdmin object to update the user interface when actions complete.

DataModel retrieves data from the user interface, performs data checks, writes valid data to and reads stored data from the underlying database, and calls methods in the BankAdmin object to update the user interface based on the success of the database read or write operation.

BankAdmin Class

The BankAdmin class, which creates the user interface, is the class that contains the main method and provides protected methods for the other BankAdmin application classes to call.

main Method

The main method creates instances of the BankAdmin and EventHandle classes. Arguments passed to the main method are used to initialize a locale, which is passed to the BankAdmin constructor.

public static void main(String args[]) {
  String language, country;
  if(args.length == 1) {
    language = new String(args[0]);
    currentLocale = new Locale(language, "");
  } else if(args.length == 2) {
    language = new String(args[0]);
    country = new String(args[1]);
    currentLocale = new Locale(language, country);
  } else 
    currentLocale = Locale.getDefault();
    frame = new BankAdmin(currentLocale);
    frame.setTitle(messages.getString(
      "CustAndAccountAdmin"));
    WindowListener l = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
      System.exit(0);
    }
  };
  frame.addWindowListener(l);
  frame.pack();
  frame.setVisible(true);
  ehandle = new EventHandle(frame, messages);
  System.exit(0);
  }
} 

Constructor

The BankAdmin constructor creates the initial user interface, which consists of a menu bar and two panels. The menu bar contains the customer and account menus, the left panel contains a message area, and the right panel is a data display or update area.

Class Methods

The BankAdmin class provides methods that other objects call when they need to update the user interface. These methods are as follows:

EventHandle Class

The EventHandle class implements the ActionListener interface, which provides a method interface for handling action events. Like all other interfaces in the Java programming language, ActionListener defines a set of methods but does not implement their behavior. Instead, you provide the implementations because they take application-specific actions.

Constructor

The constructor receives an instance of the ResourceBundle and BankAdmin classes and assigns them to its private instance variable so that the EventHandle object has access to the application client's localized text and can update the user interface as needed. The constructor also calls the hookupEvents method to create the inner classes to listen for and handle action events.

public EventHandle(BankAdmin frame, ResourceBundle messages) {
   this.frame = frame;
   this.messages = messages;
   this.dataModel = new DataModel(frame, messages);
   //Hook up action events
   hookupEvents();
} 

actionPerformed Method

The ActionListener interface has only one method, the actionPerformed method. This method handles action events generated by the BankAdmin user interface when users create a new account. Specifically, it sets the account description when a bank administrator selects an account type radio button, and it sets the current balance to the beginning balance for new accounts when a bank administrator presses the Return key in the Beginning Balance field.

hookupEvents Method

The hookupEvents method uses inner classes to handle menu and button press events. An inner class is a class that is nested or defined inside another class. Using inner classes in this way modularizes the code, making it easier to read and maintain. EventHandle inner classes manage the following application client operations:

DataModel Class

The DataModel class provides methods for reading data from the database, writing data to the database, retrieving data from the user interface, and checking that data before it is written to the database.

Constructor

The constructor receives an instance of the BankAdmin class and assigns it to its private instance variable so that the DataModel object can display error messages in the user interface when its checkActData, checkCustData, or writeData method detects errors. The constructor also receives an instance of the ResourceBundle class and assigns it to its private instance variable so that the DataModel object has access to the application client's localized text.

Because the DataModel class interacts with the database, the constructor also has the code to establish connections with the remote interfaces for the CustomerControllerBean and AccountControllerBean enterprise beans, and the code to use their remote interfaces to create instances of the CustomerControllerBean and AccountControllerBean enterprise beans.

//Constructor
public DataModel(BankAdmin frame, ResourceBundle messages) {
  this.frame = frame;
  this.messages = messages;
//Look up and create CustomerController bean
  try {
    CustomerControllerHome customerControllerHome =
      EJBGetter.getCustomerControllerHome();
    customer = customerControllerHome.create();
  } catch (Exception namingException) {
    namingException.printStackTrace();
  }
//Look up and create AccountController bean
  try {
    AccountControllerHome accountControllerHome = 
      EJBGetter.getAccountControllerHome();
    account = accountControllerHome.create();
  } catch (Exception namingException) {
    namingException.printStackTrace();
  }
} 

Methods

The getData method retrieves data from the user interface text fields and uses the String.trim method to remove extra control characters such as spaces and returns. Its one parameter is a JTextfield so that any instance of the JTextfield class can be passed in for processing.

private String getData(JTextField component) {
   String text, trimmed;
   if(component.getText().length() > 0) {
    text = component.getText();
    trimmed = text.trim();
    return trimmed;
  } else {
    text = null;
    return text;
  }
} 

The checkCustData method stores customer data retrieved by the getData method, but first it checks the data to be sure that all required fields have data, that the middle initial is no longer than one character, and that the state is no longer than two characters. If everything checks out, the writeData method is called. If there are errors, they are printed to the user interface in the BankAdmin object. The checkActData method uses a similar model to check and store account data.

The createCustInf and createActInf methods are called by the EventHandle class to refresh the customer and account information display in the event of a view, update, or add action event.

Create Customer Information

For a view or update event, the createCustInf method gets the customer information for the specified customer from the database and passes it to the createCustFields method in the BankAdmin class. A Boolean variable is used to determine whether the createCustFields method should create read-only fields for a view event or writable fields for an update event.

For a create event, the createCustInf method calls the createCustFields method in the BankAdmin class with null data and a Boolean variable to create empty editable fields for the user to enter customer data.

Create Account Information

For a view or update event, the createActInf method gets the account information for the specified account from the database and passes it to the createActFields method in the BankAdmin class. A Boolean variable is used to determine whether the createActFields method should create read-only fields for a view event or writable fields for an update event.

For a create event, the createActInf method calls the createActFields method in the BankAdmin class with null data and a Boolean variable to create empty editable fields for the user to enter customer data.

Adding a customer to an account or removing an account events operate directly on the database without creating any user interface components.