Introduction to JClient: A Simplified Guide

An Oracle9i JDeveloper Technical Whitepaper
February 2002

Content

  • Introduction
  • Understanding the Java 2 Platform(J2EE)
  • Introduction to Java Clients
  • Introduction to JClient
  • Accessing Objects through the API
  • Summary
  • Introduction

    JClient is Oracle9i JDeveloper's offering for building Java clients.  The purpose of this paper is to give a simple introduction to the JClient architecture, allowing the user to understand how Swing components are bound to business component data sources provided by the Business Components for Java (BC4J) J2EE-compliant framework.  While the JClient wizards generate the code and implement many of the concepts, understanding what is being created will improve your ability to customize the code, use the online documentation, and work with the API javadoc.

    Understanding the Java 2 Platform (J2EE)

    Oracle9i JDeveloper is Oracle's development environment targeted at the Java™ 2 Platform, Enterprise Edition (J2EE).  J2EE is a set of standards and open architecture for building enterprise applications that deploy to any J2EE-compliant application server
    and use any SQL-compliant relational database.

    Figure 1: J2EE Architecture

    J2EE services are performed in the middle tier between the user's browser and the enterprise's databases and legacy information systems.  The core J2EE component is Enterprise Java Beans (EJB), followed by JavaServer Pages (JSP) and Java servlets, and a variety of interfaces for linking to the information resources in the enterprise.

    Introduction to Java Clients

    JClient simplifies the way to bind Swing UIs to BC4J.  Before we examine JClient, it is worth confirming our understanding of Java clients generally.

    Figure 2: Example of a JClient UI

    The first concept to re-affirm is one which is familiar to many Swing developers - MVC.

    The Model-View-Controller (MVC) Architecture

    Swing is based on the concept of a Model-View-Controller architecture.  This allows the separation of the different roles of a control.

    Figure 3: The Model View Controller

    Model

    The Model represents the data or state of the component.  For example,  the model of a scrollbar will hold information on the minimum and maximum limits and the current position (current value).  This information is the same regardless of the visual representation of the widget.

    View

    The View is the actual physical representation of the object.  For example, a button could be a square or rounded yet it is still a button.

    Controller

    The Controller decides how the control will act when an action is performed on it.  For example, if the control gains focus or receives a mouse click, the controller is responsible for deciding how the control will act (if at all).  With Swing, the View and the Controller are often represented as one component called the UI Delegate.


    The advantage of this architecture means that data, as defined by the model, can have different visual representations simply by defining a different UI delegate on top of the same model.  So a list of employees and their salaries could be displayed as a chart or a table and be bound to the same data source.

    Setting the Model for a Control

    Each Swing control has a method for setting the model that the control will use.  For most controls the method is called setModel(), but for text fields the method is called setDocument().  A call to this method will pass in an object which defines the the model for the control.

    Introduction to JClient

    Now we have established some understanding of Swing, the next step is to see how JClient makes things easier for us to access BC4J data sources.  JClient is the generic name given to the the area of JDeveloper which helps you to build Java clients.  However, more specifically, JClient is a thin layer that is used to establish and manage the communication between the Swing components and the underlying BC4J data sources.

    In the previous section you learned that the setModel() or setDocument()  method is used to define the model to which the control would be bound.  JClient does not provide a model for binding to BC4J*.  Instead, JClient uses these specific setter methods to register the control using a binding helper class.  This helper class is a "utility" which will construct a model based on a number of parameters passed.

    * There are some exceptions to this rule.

    The BC4J Application Module

    BC4J has the concept of an application module.  The application module is the tier with which the client and the database will interact.  It contains the view objects which represent your view of the data and manages the transactions on that data.  For example, you may have an application module which performs actions (such as handling online orders or processing salary increases).

    How the Application Module is Used in a JClient Application

    In order to access the data in your application, your client will need to bind to it.  JClient provides an object for accessing the application module.

    JUApplication app = JUMetaObjectManager.createApplicationObject("MyProject.Mypackage1Module", null, new JUEnvInfoProvider());

    The above statement reads the JClient project file (myproject.cpx) for an application module called MypackageModule and will use the connection information defined for that application module to establish a connection to the middle tier.

    The JClient Panel Binding

    Through the above code that returns a JUApplication object, JClient has established the call required to bind to a particular application module. The next step is to create a number of data structures which will manage the binding. To accomplish this, unique branches of your UI (usually beginning with a panel) will have a structure called a Panel Binding which will contain Iterators.

    private JUPanelBinding panelBinding = new JUPanelBinding("jclient.Mypackage1Module", this);

    The above statement creates a new panel binding and the following statement registers this panel binding with the JUApplication object which was created earlier.

    panelBinding.setApplication(app);

    A panel binding provides boths a container and a scope for Iterators. An iterator instance is a pointer or an index into the model for a particular control, and is created when the call is made to setDocument() or setModel(). The control uses the Iterator to get an index into the model (or data) and ultimately to reference the underlying rows of data in the BC4J data source. The JClient application benefits from using panel bindings specific to unique branches of the UI because:

    • As a container, all panels that share the same panel binding track the state of the current or active iterator, which allows your panels to share a Navigation Bar and Status Bar.

    • Relative to the scope, all iterators created for a given panel binding will automatically be cleaned up for you when the last reference to the panel binding is removed.

    Consider this example, in which a separate panel binding is created for the topmost panels of two UI branches. Perhaps the application starts with a menu that lets the user choose different UI branches, say Orders and Catalog. The top panel for Orders will have an OrdersPanelBinding and the top panel for Catalog will have a CatalogPanelBinding. After the user chooses Orders and then goes back to the menu to open the Catalog UI, the OrdersPanelBinding will disappear and all its iterators will be cleaned up. Whereas, if the application includes an informational dialog that users can display from both UI branches, then it might be desirable for the application to create the panel binding InfoPanelBinding on the frame that contains both UI branches. By changing the scope of a panel binding, you can make the iterators persistent across UI branches and avoid the overhead of creating the same iterators each time the user opens a common dialog.

    Understanding that the panel binding instance defines both a container and a scope helps you decide whether to share a previously created panel binding or to create a new panel binding when you create a new UI branch in your application.

    Binding the Controls to BC4J

    The final step is to actually call the SetDocument() or setModel() method to bind the control to the BC4J data source.  This is done with the following line of code:

    mDepartmentId.setDocument(JUTextFieldBinding.createAttributeBinding(panelBinding, mDepartmentId, "DepartmentsView", null, "DepartmentsViewIter", "DepartmentId"));

    Here, the document for the text field is being set.  The object JUTextFieldBinding is a helper class which will, using the parameters supplied, create a document object which will define the binding between the control and the data source.  The parameters being passed include the panel binding, the iterator, and the name of the BC4J view objects and attribute to which the control is bound.

    At this point the JClient application checks to determine whether the panel binding already contains the binding to the view object iterator. If the panel binding contains the iterator, the application will reuse it. Otherwise, the application will create and register one. Note, it is at this point where decisions concerning sharing the existing panel binding and iterator instances will determine your application's behavior.

    In the above statement, the JClient application creates the binding and registers listeners for that binding to the DepartmentId Swing control.  It will add this control binding to the panelBinding container and register it in a table as DepartmentsViewIter.

    Figure 4: Setting the Document for a text field

    Accessing Objects through the API

    Once you have an understanding of the components which make up the a JClient UI it becomes easier to extend it.  There are two main actions which you will probably want to perform:

    • Change a property on the control itself

    • Change a property of the underlying data

    Referencing the Swing Control

    The most obvious change you may want to make is to the visual representation of the control.  For example, to change the color of the foreground text you would call:

    mManagerId.setForeground(Color.red);

    Another action you may want to perform is provide your own model (which for example does client-side validation) and use this in addition to the default model which binds the control to BC4J. For example:

    mDepartmentId.setDocument(myModel); //Define your own model

    /* The following line of code is the code which is generated for you. This will take the existing model and bind the BC4J model "on top" */
    mDepartmentId.setDocument(JUTextFieldBinding.createAttributeBinding(getPanelBind...

    Referencing BC4J the Business Components

    Through some UI actions (such as clicking on a button) you may want to set a property of the underlying data: for example, filtering the data using a where clause.  This is a property of the view object and using the following code you can access the BC4J view object.

    //Get the handle to the view object
    oracle.jbo.ViewObject vo = panelBinding.findIterBinding("DepartmentsViewIter").getViewObject();

    //Set properties on the view object
    vo.setWhereClause("LOCATION_ID > 1800");
    vo.setOrderByClause("DEPARTMENT_NAME");

    //Re-execute the query on the binding.
    panelBinding.findIterBinding("DepartmentsViewIter").executeQuery();

    Another example would be to delete a record from the view object:

    //Get the handle to the view object
    oracle.jbo.ViewObject vo = panelBinding.findIterBinding("DepartmentsViewIter").getViewObject();

    //Remove the selected row from the view object
    vo.removeCurrentRow();

    //Set an indication that the transaction have been edited
    if (!app.isTransactionModified())
    {
       app.transactionStateChanged(true);
    }

    Summary

    While the JClient wizards free the developer from much of the code to link the UI and the data, it is expected that developers will then modify the code to meet their own requirements.  Understanding that the panel binding instance defines both a scope and container helps you decide whether to share a previously created panel binding or to create a new panel binding when you create a new UI branch in your application. Much of this information is contained within the extensive online help; however, this white paper brings together JClient concepts to give a simple introduction to the architecture.
    Oracle Corporation
    World Headquarters
    500 Oracle Parkway
    Redwood Shores, CA 94065, USA
    http://www.oracle.com
    Worldwide Inquiries:
    1-800-ORACLE1
    Fax 650.506.7200 
    Copyright and Corporate Info
E-mail this page
Printer View Printer View
Oracle Is The Information Company About Oracle | Oracle RSS Feeds | Careers | Contact Us | Site Maps | Legal Notices | Terms of Use | Privacy