HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

Most Web-based applications today confine users to the frame of their browser, restricting them to viewing only one Web page at a time. Technologies such as JavaScript make additional browser windows possible, but this approach doesn't enable the kind of customized menus, toolbars and windowing features available in a traditional client/server application. Java Swing provides additional capabilities such as the ability to create windows outside the browser that have the look and feel of a traditional client application. The techniques described in this article can be used to migrate traditional client/server applications to a Web-based environment.

Event-monitoring applications that display and continuously update event information in real time stand to benefit from such an approach. For example, applications that monitor changes in financial data, network activity or weather conditions and require the continuous display of information must be updated in real time based on events occurring on the server. These applications usually require long-running applets that monopolize the browser, which in a Web-based environment obliges users to open a second instance of the browser if they want to view additional information. This creates a need for Web-based applications that behave similarly to typical client/server multiwindowing applications because these don't monopolize the browser window space.

A combination of Java Swing and CORBA provides the ability to build applications of this nature, referred to as "self-contained client applets." These applets use CORBA to communicate with a server in real time and Java Swing to create an effective GUI. Java-enabled Web browsers act as a common platform from which applets using CORBA may be launched. Once the self-contained client applet is launched, the user has the option of visiting other Web pages or minimizing the browser.

One integral part of this applet is the use of CORBA, as demonstrated in our November 1999 article "Real-Time Web-Based Applications with Java and CORBA" (JDJ, Vol. 4, issue 11). An ORBlet-enabled Web browser permits the execution of CORBA-enabled applets.

The CORBA callback is a well-defined, easy-to-use technique for developing real-time, Web-based clients. Clients wanting to receive real-time data register with the server by passing it a client object reference. The server stores a reference to each client that receives data in real time. As the state of the server changes, client references in the server are used to send data to the client. Callbacks are an effective way to have clients receive data from the server without having to poll the server. Another approach that can be used to notify clients of events is the CORBA-defined Event Notification Service. Remember to keep performance requirements in mind when deciding which approach to use.

Swing components allow you to execute applets within the secured, well-defined browser environment while creating an effective GUI outside the browser's frame. Applets that create windows outside the browser's frame make it possible for users to view other Web pages or minimize the browser as the applet executes. Combining applets and CORBA allows an application to behave like a traditional client/server without requiring any software installation or configuration on the client. The user simply accesses a Web page containing a CORBA-enabled applet that binds to the CORBA server, establishing a client/server connection. Creating applications in this manner gives you the best of both worlds and allows you to create powerful, effective applications.

Overview of Swing
In an effort to make Java more consistent across platforms, the Java Foundation Classes were created jointly by Sun Microsystems, IBM, Netscape and Lighthouse Designs (now a part of Sun Microsystems). JFC is a suite of GUI classes that includes Abstract Windowing Toolkit (AWT), Drag and Drop, Java 2D, Accessibility and Swing. Based on AWT and written entirely in Java, Swing provides users with a GUI that looks consistent across platforms and provides developers with a GUI that performs identically across platforms. JFC is part of Java 2 and can be integrated with any JDK version newer than 1.1.5.

Java Swing components are based on Netscape's Internet Foundation Classes. Written in Java, the IFC was created to simplify the creation and management of Java GUI components and greatly extends the AWT. The AWT Container class was extended by Swing with the introduction of the JComponent, the superclass of most Swing components. This class is a member of the javax.swing package.

A "J" precedes all component classes in Swing ­ JLabel, JButton, JTree and so on. Classes derived from JComponent provide various characteristics including platform-independent presentation, shortcut keys (termed mnemonics) and common event-handling capabilities. Swing components derived from JComponent are written entirely in Java and their look and feel are independent of the platform they're executed on, which is why they're termed lightweight (see Figure 1).

Figure 1
Figure 1:

A Java program that uses AWT has a different look and feel depending on the platform it's being executed on. Running on a Macintosh, it looks and feels different from the same program executing in a Microsoft Windows environment. These differences may cause a GUI component to vary drastically in appearance depending on which platform the component is used on ­ the amount of space a component occupies may differ, for example. Swing's creators took the best features of existing GUIs and implemented them in a look and feel termed Metal ­ Swing uses it by default ­ that delivers a uniform look and feel across platforms. There's also a Windows or a Motif look and feel that you can specify. The Swing class javax.swing.UIManager is used to manage the default look and feel of a Java Swing program.

Not all "J" classes are lightweight. The Swing containers JFrame, JDialog, JWindow and JApplet are heavyweight containers. These classes are derived not from JComponent but from an AWT class and they're termed heavyweight because their presentation is less flexible than lightweight components and is linked directly to the native platform's windowing system. These components are constrained (or weighed down) to the native platform's GUI capabilities. Heavyweight components don't necessarily perform or look the same on different platforms. The heavyweight component's AWT peer manages the interactions between the native platform and the Swing component (see Figure 2).

Figure 2
Figure 2:

Model-View-Controller
One distinct advantage Swing has over AWT is its employment of the Model-View-Controller (MVC) design pattern (see Figure 3). This design pattern, employed when using object-oriented techniques with user interfaces, was first introduced with Smalltalk. In MVC there are three objects: the model, view and controller. The model has nothing to do with the presentation of data, but with the essential data attributes and their associated values. It notifies views interested in the model when data values change. The presentation or appearance of the user interface is the view object ­ this ensures that the presentation of the model is accurate. As the view object receives notification that a model has changed, it updates the appearance. Any number of views may be associated with a model. For example, one model may be displayed with views as a pie chart, graph or spreadsheet. The controller object manages how the user interface responds to user interactions, such as a button press or movement of a mouse.

Figure 3
Figure 3:

The view and controller objects play less of a role in Web-based applications than in typical desktop user interfaces. The view object is less significant because most Web-based clients must poll for the current state of the model. Except rarely, the model object doesn't notify the view object when a value has changed. The controller object is less significant because Web-based applications have less user interaction than their desktop counterparts. Accordingly, Swing fuses the view and controller objects into a delegate object, a design called a separable model architecture. The delegate object both reacts to user interaction and presents the model. Each component's delegate is derived from the ComponentUI class. For example, the JButton component uses a ButtonUI class and the JLabel component uses a LabelUI class, both of which are derived from the ComponentUI class. These are known as the pluggable look and feel interfaces (see Figure 4). Methods in this class ­ e.g., paint, updateUI ­ deal with the appearance of a component.

Figure 4
Figure 4:

Description of a Self-Contained Client Applet
To illustrate the concept of a self-contained client applet we're going to use the example of a building-monitoring system. This is a system for monitoring the security, temperature and power within a building. The server receives events from telemetry equipment, records them, correlates them when possible and reports them to the building-monitoring clients registered with the server.

When the monitoring client applet is downloaded and started, the main monitor menu is displayed in the browser. The menu contains items such as file, edit, view and help. A "peel- off" menu created from the main menu causes the applet to peel itself from the browser and act as a stand-alone window. Users may perform various actions that create windows within the application ­ e.g., they can customize the monitoring client to view particular areas of a building or the entire building. A panel containing an event list displays each room or section of the building.

The room name and time of the latest event is displayed at the top of each panel. Events are color-coded based on their importance. If, for example, the room temperature were configured at 70 degrees and the temperature rose to 75 degrees, a minor event would be generated and it would appear as a yellow button within the list. But if the temperature were to rise above 80 degrees it would become a major event and would appear as a red button. To help them understand the events, users can click on any one of these buttons and a separate detail window will pop up.

Users can acknowledge the event to indicate they're currently investigating it and can enter notes about events at any time. Once an event has been resolved, the user can clear it. A user can have several windows open simultaneously and navigate between them, or minimize any one of them. The monitoring windows will be updated in real time as events are received from the server, even if the monitoring window isn't the current active window. Even though these actions are performed by an applet running in the confinement of the browser's environment, the behavior appears as though it's a typical multiwindowing client/server application executing outside the browser. All GUI and communication components required by the application are encapsulated within the downloaded self-contained client applet.

Comparing Applet and JApplet Classes
In lieu of the java.awt.Applet class, the com.sun.java.swing.JApplet class is used for support of Swing components. Extended from java.awt.Applet, the com.sun.java.swing.JApplet class is a heavyweight component since it isn't extended from the JComponent class. One of the differences between the com.sun.java.swing.JApplet class and the java.awt.Applet class is that it supports the JMenuBar Swing component and Swing lightweight components.

Components aren't added directly to a JApplet, as they are to an Applet. Swing heavyweight components use the com.sun.java.swing.JRootPane class to manage their operations. The JRootPane class, the only child of heavyweight components, is obtained by using the heavyweight component's getContentPane method. The JRootPane returned by the getContentPane method is used to add components to the heavyweight container. Components added to lightweight containers are added directly to the container using the add method of the container concerned.

For example, you add a JPanel to a JApplet as follows:

public class demoClass extends JApplet {
public void init() {
JPanel panelToAdd = new Jpanel();
getContentPane().add(panelToAdd);
}
}

The JApplet class makes use of the BorderLayout, rather than FlowLayout, as the default LayoutManager ­ as does the Applet class. Just as with adding components, the getRootPane method is used to set JApplet's layout manager. For example, to set a JApplet's layout manager to BoxLayout:

public class demoClass extends JApplet {
public void init() {
getContentPane().setLayout(new BoxLayout());
}
}

Creating Menus with Swing Components
One element of our example that runs inside the browser frame is the main menu. This is an excellent example of creating a GUI using components as building blocks. A menu bar, created by using the JMenuBar class extended from the JComponent class, consists of any number of JMenu objects, each one with any number of pull-down menu items that can be selected with either a mouse click or a keyboard shortcut.

The JMenu class provides methods for creating menus that contain menu items. The JMenuItem class provides methods for creating menu items contained within a JMenu. JMenuItem objects allow users to request program functionality by being selected. In the example application, the selection of the "view as a separate window" JMenuItem causes a main menu to be peeled off the browser and appear outside the browser's frame.

JMenuItems may contain a text label or an icon. A number of constructors exist for the JMenuItem class, permitting the specification of a label or icon. The default constructor may be used to create a JMenuItem at one point in the code, then set the label later by using the setText method. The example code will create a fully populated JMenuBar, starting with the creation of JMenuItems with a label:

JMenuItem newMenu = new JMenuItem("New");
JMenuItem openMenu = new JMenuItem("Open");
JMenuItem saveMenu = new JMenuItem("Save");

The JMenu class has three constructors. A JMenu may be instantiated (1) with no label, using the JMenu default constructor, (2) with a label using the JMenu constructor with a String or (3) with a label and boolean variable indicating the state of the JMenu. A number of JMenu classes will be instantiated here with a label. These will contain the JMenuItems created above.

JMenu fileMenu = new JMenu("File");
JMenu editMenu = new JMenu("Edit");
JMenu toolsMenu = new JMenu("Tools");
JMenu helpMenu = new JMenu("Help");

JMenuItems are added to a JMenu with the add method:

fileMenu.add(newMenu);
fileMenu.add(openMenu);
fileMenu.add(saveMenu);

Finally, a JMenuBar will be created to contain the JMenus. The JMenuBar has one constructor, the default constructor:

JMenuBar menuBar = new JMenuBar();

JMenus are added to the JMenuBar with the add method:

menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(helpMenu);
menuBar.add(toolsMenu);

The Observer Design Pattern and Events in Java
JDK 1.1 introduced the delegation-based event-handling mechanism. Also known as the publish-subscribe model, it's based on the Observer design pattern, used when consistency is to be maintained between objects. Java implemented the Observer design pattern by creating Subject and Observer objects. The Subject maintains a list of Observers that are notified when the Subject's state changes. This set may contain one or more Observers. Observers provide an interface through which the Subject notifies them of a state change. As the Observers are notified of this change, they can examine the Subject to determine how they should behave. In this scenario there's very low coupling between the Subject and Observer objects since the Subject is unaware what information the Observer object needs or how it behaves.

In Java, Subjects must create an event extended from the java.util.EventObject. In the example application the Subject is a JMenuItem that creates an ActionEvent derived from EventObject. Observers or listeners must implement the java.util.EventListener interface. In this example the actionPerformed method of the ActionListener interface, extended from the EventListener, is implemented.

The addActionListener method is used to register an Observer or listener with a Subject or JMenuItem. If the listener were contained in a class other than the class containing the JMenuItem, an instance of the class would be created, then registered with the JMenuItem by using the addActionListener method. In our example the class containing the listener is the same class that contains the JMenuItem:

openMenu.addActionListener(this);

Defining the actionPerformed method of the ActionListener interface specifies an Observer or listener. This method is executed when the ActionListener receives an action event generated by the Subject. One listener can be associated with any number of JMenuItems. The ActionEvent class inherits the getSource method from the EventObject class. This method returns the object that caused the event. In this case it's used to determine which JMenuItem caused the action event.

public void actionPerformed(ActionEvent e) {
if(e.getSource() == openMenu) {
// handle action event for openMenu JMenuItem
} else if(e.getSource() == peelMenu) {
// handle action event for peelMenu JMenuItem
}
}

Swing ToolTips
It's often helpful to provide users with more information about a menu item than the label in that item itself. All Swing lightweight components inherit JComponent's setToolTip method. This method may be used to specify text that appears when the mouse remains over a Swing component for a given period of time, helping users know what the component is for. In our example we associate a tool tip with a JMenuItem, but a tool tip may be associated with any Swing lightweight component.

newMenu.setToolTipText("Used to Create Something New");

Creating a Window Outside the Browser
Both JFrame and JApplet are heavyweight containers that can be used in very similar ways. The JFrame container can be used to create a window that's not visually contained within the browser. As a heavyweight container, the JFrame will appear differently on different platforms. The most noticeable difference between platforms will be the appearance of buttons used to minimize, maximize and close the JFrame.

From the user's point of view, once the JFrame is created, the applet appears to be running independently of the browser. In reality, it continues to execute from within the browser and is restricted to behaving like any other applet. Any connections the applet has to a server are still present in a JFrame appearing outside the browser's window. Once a window is created outside the browser's window, users can visit other Web pages or minimize the browser.

In Listing 1, if the peelMenu JMenuItem is selected, the event handler for the peelMenu will cause a main menu to appear ­ not within the JApplet, but within a JFrame outside the browser window. The steps to perform this task are identical to those you take to perform it within a JApplet, with the exception of having first to create a JFrame. The java.awt.Window method pack is called to lay out and position all components contained in the Window at their proper size.

Description of Event Panel
A class that implements the ListSelectionListener interface is used to contain each event panel. The valueChanged method in this interface is provided to handle activity when a JList selection value changes. A ListSelectionEvent object is received by the valueChanged method, which can be queried to determine more information about the selection list that generated the event. The Swing JList, a component used to create a multiple-selection list, is used to display events occurring in each building section being monitored. The JList is created, then associated with a renderer with the following calls:

class EventPanel extends Jpanel implements ListSelectionListener {
public EventPanel() {
JList list = new JList();
list.setCellRenderer(new ARenderer());
}
public void valueChanged(ListSelectEvent event) {
// handle selection list value change
}
}

Customizations to the JList include the specification of a horizontal and vertical scroll pane, as needed:

JScrollPane scrollPane = new JScrollPane(list,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);

After all customizations are made to the JList, it's added to a JPanel that also contains JLabels for the identification of the building section (see Figure 5).

Figure 5
Figure 5:

Cell Rendering
The ListCellRenderer interface is used to specify how a component represents data in a list. The ListCellRenderer has one method, getListCellRendererComponent, that appropriately displays a data value. This method receives the object being represented in the list and returns a component used for rendering the item. This method is invoked each time the cell is required to be repainted, such as when a window is resized. Time-consuming operations, such as retrieving data from a server or expensive GUI operations, shouldn't be placed in the getListCellRendererComponent method. Server-side data may be cached in the client for use by the getListCellRendererComponent method. A constructor for the class implementing the ListCellRenderer interface may be used to perform time-consuming operations or operations that need occur only once. To avoid performance degradation, for example, the constructor of the ARenderer class in Listing 2 creates the borders and fonts when the class is instantiated.

The method should contain only operations required to dynamically change the appearance of the data being represented. For example, the renderer may visually represent an object in different forms based on the events and data it receives from a server. The getListCellRendererComponent method can be used to translate an integer value into text. Another example: if an attribute of the object exceeds a certain value, the background of the label can be set to a certain color (see Listing 2).

Summary
Java Swing introduces a new GUI architecture supported by a host of GUI components that can be used to create effective GUI tools that look and behave similarly to client/server windowing applications. Long-running applets can use these components to provide users with windows outside the browser's frame, permitting them to visit other Web pages and thus making the use of the long-running applets more productive.

Author Bios
Thomas Czernik is a member of AT&T's technical staff with 18 years of systems development experience. Tom holds an MS in computer science.  [email protected]

Rolf Kamp is a member of AT&T's technical staff where he develops network operation software. An adjunct faculty member at Brookdale Community College, Rolf holds an MS in computer science and an MBA.  [email protected]

	

Listing 1 

JFrame menuFrame = new JFrame("MONITOR MENU"); 
NotifyMenu mainMenu = new NotifyMenu(); 
JPanel pPanel = new JPanel(); 
JLabel lLabel = new JLabel("MONITOR MENU"); 
Font lFont = new Font("Serif",Font.BOLD|Font.ITALIC,24); 
lLabel.setFont(lFont); 
lLabel.setForeground(Color.white); 
pPanel.setBackground(Color.blue); 
pPanel.add(lLabel); 
menuFrame.setJMenuBar(mainMenu.getMenuBar()); 
menuFrame.getContentPane().add(pp); 
menuFrame.pack(); 
menuFrame.show();
 
Listing 2 

class ARenderer extends JLabel implements ListCellRenderer   { 
  static Font f = new Font("Helvetica",Font.BOLD,10); 
  static SoftBevelBorder sbb = new SoftBevelBorder(Soft- 
  BevelBorder.RAISED); 
  static CompoundBorder cb = new CompoundBorder(new Matte- 
  Border(2,2,2,2, 
  Color.green),new SoftBevelBorder(SoftBevelBorder.RAISED)); 

public ARenderer()  { 
  setOpaque(true); 
  setFont(f); 
  setForeground(Color.black); 
} 
public Component getListCellRendererComponent(JList l, 
  Object v, int i, boolean isSelected, boolean cellHasFocus)  { 
  LocalEvent a = (LocalEvent)v; 
  setToolTipText(a.description); 
  setText(a.symbol); 
  if (a.severity == 0) { 
    setBackground(Color.gray); 
  } else if (a.severity == 1) { 
    setBackground(Color.cyan); 
  } else { 
    setBackground(Color.white); 
} 
} 
// additional customization codeŠ 
return this; 
} 
} 




 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.