7.4 Personal Java


7.4.1 Abstract Windows Toolkit

Java AWT is the basic Java GUI library. It hides the underlying details of the GUI at a high level of abstraction. The documentation for the package is available at java.sun.com [AWT].

The structure of the AWT is rather simple. Components are added to, and live within, Containers. The layout of the components within their containers is controlled by Layout objects. Available are a variety of event handling, menu, fonts, and graphics classes in addition to those two. Use of threads is allowed, as well as video, audio, I/O, and networking classes alongside the AWT. Figure 7.2 present the AWT subset associated with components and containers.

7.4.1.1 Containers

Containers are Frames, Dialogs, Windows, and Panels. They can contain components and are themselves components, thus can be added to Containers. Containers usually handle events that occurred to the Components, although nothing prevents the handling events within the component. In short all classes derived from Container can be one.

All Containers have common functionality, due to the fact they are derived from Container class which includes many pre-defined event handling methods called listeners or callbacks. These events are useful for handling user input in specialized Container classes which override the default behavior by overriding the Container's class methods.

7.4.1.2 Components

Components are generally with what the viewer interacts . Components include Windows, Buttons, TextAreas, Scrollbars, and so on., which are added to a container and allow displaying Windows and Buttons, lists, selectors, and edit boxes.

7.4.1.3 Layouts

Layouts control how Components are laid out within a Container. An abstract class called the LayoutManager is used to manage layouts; because it is abstract, to be used it is subclassed and extended with functionality. There are a number of layouts built-into the AWT framework:

  • BorderLayout : This scheme lays out the Component in 5 ways

    North : Northern part of the Container

    South : Southern part of the Container

    East : Eastern part of the Container

    West : Western part of the Container

    Center : Centered in the Container

  • CardLayout : Allows for tabbed dialogs or dynamic dialogs.

  • GridLayout : Allows for the layout of Components in a gridlike fashion.

  • GridBagLayout : This is the closets to an HTML table style of layout

  • FlowLayout : Allows for Component to be laid out in a row and aligned (left, right, center).

To use a layout within a Container one needs to invoke the setLayout() method of that Container, with an instance of a subclass of the LayoutManager class. The interfaces used with each layout are different. For example, with BorderLayout one needs to specify the location of a component to be one of north, south, east, west, or center.

7.4.1.4 Events

GUIs and Windowing systems use the event-driven model rather than the old procedural-grab-the-input-yourself model. The operating system is polling for events, and when it finds one, it forwards that event to the appropriate component. The component receives the event through a registered listener, or callback. By default, no listeners are registered and events are ignored.

AWT Events could be classified into Mouse, Keyboard, Window, and Action events. Mouse events occur when the mouse pointer moves over, into, or out of a rectangle associated with a component. Keyboard events occur when a key in the remote-control is pressed or released; they are routed to the component with the input focus at the time the event occurs. Window events occur as the window is shown, hidden, moved or resized. Finally, action events are application-specific events used to allow an event-driven programming model.

7.4.1.5 Mouseless Operation

iTV environments differ from typical computer environment in that they are not mouse-driven (if at all available, a remote-control track ball is often more practical than a mouse). As a result, mouseless operation is critical for usability of iTV applications. Java AWT 1.0 does not provide any explicit facilities for building mouseless operation into Java programs, except where the native peer components provide it by default (i.e., tabbed focus traversal, spacebar activation, and so on). For JDK 1.1, however, some baseline support was added to better enable mouseless mode in Java programs. Middleware implementations implementing the HAVi Level 2 GUI API perform much of what is described next using HAVi classes. However, the concepts and approach is similar [HAVI].

Focus Traversal

Focus traversal is defined as the ability to use keystrokes (not the mouse) to traverse components capable of accepting keyboard focus. Those keystrokes are defined to be <Tab> to move forward and <Shift-Tab> to move backward. Once the focus is owned by a component then it should be possible to activate/drive that component with further defined keystrokes (e.g., <space> to press a button). It is the responsibility of the component (not the AWT) to implement the proper activation once it has focus.

The AWT internally tracks which component has the focus so that it can move the focus forward or backward in response to a Tab or Shift-Tab keyboard event. This is handled by a private FocusManager object that is registered on the Window. The FocusManager can manage this focus migration correctly, no matter how deeply nested a window's containers are. The order of this traversal is the same order of the components contained in the containers; by default this is the same order in which the children were added to the container, however the Container.add(Component c, int pos) method can be used to control this ordering. The FocusManager automatically checks to see if a focusTraversable component is both visible and active before it assigns it the focus (hence, the isFocusTraversable() method need not take this state into account for its return value).

A component capable of accepting focus should always render some form of visual feedback when it gets focus. Typically, in iTV environment, this feedback takes the form of a colored bounding box drawn around the component. The native toolkits on each platform provide varying degrees of support for focus traversal by default. In AWT, the Focus traversal API is extremely simple; it consists of the method isFocusTraversable() that returns true if the component is a type inherently capable of accepting keyboard focus and returns false otherwise .

The reason this method exists for the peer class is because the native peer components that are created by the AWT components have different traversal rules on different platforms. This allows the tailoring of this attribute appropriately on each platform. All AWT components should have this attribute set properly by default. Implementers have the option of subclassing a component and overriding this method. In particular, when subclassing java.awt.Canvas to build a custom component that is designed to take keyboard focus, one should override isFocusTraversable() to return true, catch the mouse-down event on the component, invoke requestFocus() , and when the component gets focus, provide visual feedback (e.g., highlighting the bounding box) to indicate that it has indeed received the focus.

Menu Shortcuts

The goal for the AWT Shortcut API is to provide an easy way for application developers to provide shortcuts as an aid to menu navigation. This API only addresses menu shortcuts and does not touch on any other mouseless menu navigation issues.

A shortcut is defined to be a keyboard equivalent of a menu command, such that invoking the appropriate key combination causes the same action to be initiated as if the menu item had been selected. Shortcuts are also known as keyboard equivalents or accelerators. The AWT Shortcuts API consists of a class java.awt.MenuShortcut , and the following java.awt.MenuItem methods:

 public MenuItem(String label, MenuShortcut s) public MenuShortcut getShortcut() public void setShortcut(MenuShortcut s) public void deleteShortcut(); java.awt.MenuBar has the following additional methods: public MenuItem getShortcutMenuItem(MenuShortcut s); public Enumeration shortcuts(); boolean handleShortcut(KeyEvent e); public void deleteShortcut(MenuShortcut s); 

Although most of the shortcut API is implemented in shared code, the getMenuShortcutKeyMask() method was added to java.awt.Toolkit to return the appropriate modifier per platform.

7.4.1.6 The Platform Glue

From the point of view of a middleware developer, execution environment implementer or platform integrator, the java.awt.Toolkit class is key, as JDK 1.1.8 is common to all iTV middleware specifications. It is the abstract superclass of all actual implementations of the AWT. The toolkit is used to bind the various components to a particular native implementation. These methods (Table 7.4) are the glue that joins the platform-independent classes in the java.awt package with their counterparts in java.awt.peer . Some methods defined by Toolkit query the native operating system directly. Most applications should not call any of the toolkit methods directly.

Table 7.4. The java.awt.Toolkit Methods

Toolkit ('Glue') Method

Description

beep()

Emits an audio beep; this is the 'basic' audio function.

checkImage()

Indicates the construction status of a specified image that is being prepared for display.

java.awt.peer.ButtonPeer() , createCanvas() , createChoice() , createCheckbox() , createCheckboxMenuItem()

Creates the toolkit's implementation of Button , Canvas Checkbox , CheckboxMenuItem , and Choice , respectively, using the specified peer interface.

createComponent()

Creates a windowless peer for a component or container that allows extending it with windowless components that are defined entirely in java and do not rely on native interfaces.

createCustomCursor()

Creates a new custom cursor object. This is a very useful function not supported in AWT 1.1.8 and therefore may not be supported by some iTV middlewares. If the image to display is invalid, the cursor becomes transparent, and the hot spot is set to (0, 0).

createDialog() , createFileDialog()

Creates the toolkit's implementation of Dialog or FileDialog using the specified peer interface.

createFrame()

Creates the implementation of Frame using a peer interface.

createImage()

Creates an image which decodes the image stored in the specified byte array. Optionally, one may specify offset and length, image producer, file name , or URL. The data is in an image format supported by the middleware implementation (e.g., GIF, JPEG).

createLabel() , createList() , createMenu() , createMenuBar() , createMenuItem() , createPanel() , createScrollbar() , createPopupMenu() , createScrollPane() , createTextField() , createTextField() , createWindow()

Creates the toolkit's implementation of Label , List , Menu , MenuBar , MenuItem , Panel , PopupMenu , Scrollbar , ScrollPane , TextArea , TextField , Window , respectively, using the specified peer interface.

getColorModel()

Determines the color model of this toolkit's screen. This method is called by the getColorModel method of the Component class. The latter encapsulates the ability to translate between the pixel values of an image and its red, green, blue, and alpha components.

getDefaultToolkit()

Gets the default toolkit. If there is a system property named awt.toolkit , that property is treated as the name of a class that is a subclass of Toolkit. If the system property does not exist, then the default toolkit used is the class named "sun.awt.motif.MToolkit", which is a motif implementation of the Abstract Window Toolkit.

Additional classes are loaded using the property assistive_technologies specified in the Sun reference implementation by a line in the accessibility.properties file. Each class is loaded in the order given and a single instance of each is created using Class.forName(class).newInstance() . This is done after the AWT toolkit is created; errors throw AWTError exception.

getFontList()

Deprecated in subsequent versions after 1.1.8; replaced by GraphicsEnvironment.getAvailableFont-FamilyNames() .

getFontMetrics()

Deprecated in subsequent versions after 1.1.8; replaced by Font.getLineMetrics .

getFontPeer()

Deprecated in subsequent versions after 1.1.8; replaced by GraphicsEnvironment.getAllFonts .

getImage()

Returns an image which gets pixel data from the specified file or URL, whose format can be either GIF, JPEG, or PNG.

getLockingKeyState()

Not supported by AWT 1.1.8 but important for iTV implementations. Returns whether the given locking key on the keyboard is currently in its "on" state.

getMaximumCursorColors()

Not supported by AWT 1.1.8 but important for iTV implementations. Returns the maximum number of colors the Toolkit supports in a custom cursor palette.

getMenuShortcutKeyMask()

Determines which modifier key is the appropriate accelerator key for menu shortcuts. Menu shortcuts, which are embodied in the MenuShortcut class, are handled by the MenuBar class. By default, this method returns Event.CTRL_MASK. Toolkit implementations should override this method if the Control key isn't the correct key for accelerators.

getNativeContainer()

Give native peers the ability to query the native container given a native component (e.g., the direct parent may be lightweight).

getPrintJob()

Gets a PrintJob object which is the result of initiating a print operation on the toolkit's platform. Typically not useful for iTV implementations, since set-top boxes typically do not connect to printers. In some cases, could be useful for printing coons.

getProperty()

Gets a property with the specified key and default. Properties are typically used for discovery implementation-specific characteristics and APIs. Some iTV standards specify pre-defined properties. This method returns defaultValue if the property is not found.

getScreenInsets()

Gets the insets of the screen. Not supported by AWT 1.1.8 but important for iTV implementations.

getScreenResolution()

Returns the screen resolution in dots-per-inch.

getScreenSize()

Gets the size of the screen in pixels.

getSystemClipboard()

Typically, this function is not useful for iTV implementations.

getSystemEventQueue() , getSystemEventQueueImpl()

Get the application's EventQueue instance. Depending on the Toolkit implementation, different EventQueues may be returned for different JavaTV Xlets (see section 7.6.2). Xlets should therefore not assume that the EventQueue instance returned by this method is shared by other Xlets or the system.

If there is a security manager, its checkAwtEventQueueAccess method is called. If the default implementation of checkAwtEventQueueAccess is used (i.e., that method is not overriden), then this results in a call to the security manager's checkPermission method with an AWTPermission ("accessEventQueue") permission.

loadSystemColors()

Fills in the integer array that is supplied as an argument with the current system color values.

prepareImage()

Prepares an image for rendering. The image data is downloaded asynchronously in another thread, and an appropriately scaled screen representation of the image is generated.

setLockingKeyState()

Not supported by AWT 1.1.8 but important for iTV middleware implementations. Sets the state of the given locking key on the keyboard. Valid key codes are VK_CAPS_LOCK , VK_NUM_LOCK , VK_SCROLL_LOCK , and VK_KANA_LOCK . Depending on the platform, setting the state of a locking key may involve event processing and therefore may not be immediately observable through getLockingKeyState.

sync()

Synchronizes this toolkit's graphics state rendering the display up-to-date. Some window systems may buffer graphics events.

7.4.1.7 Binding Graphics Contexts

One of the critical aspect of an iTV platform implementation is the binding of graphics libraries. Since the java.awt.Graphics class is an abstract class, applications cannot call its constructor directly. Graphics contexts are obtained from other graphics contexts or are created by calling getGraphics() on a component. The Graphics.create() method on a Graphics of a components is often used internally to create a new Graphics object with a translation and clip area. Although the HAVi API overrides most of the Java AWT APIs, it does not override the getGraphics() method of the AWT component. Therefore, the getGraphics() method remains an important link to the graphic drivers.

7.4.2 Java Reflection

Reflection is one important innovative concept that the Java technology has introduced. It enables Java programmers to manipulate code in a fashion that was previously solely the realm of debuggers . It enables Java code to discover information about the fields, methods, and constructors of loaded classes, and them within a fully controlled security environment. This enables, for example, discovering which APIs a receiver execution environment supports, as well as detecting which components are bundled with a JavaTV Xlet or a plug-in.

One should avoid the temptation to use the reflection mechanism when other tools more natural to the language would suffice. Nevertheless, the reflection API accommodates applications that need access to either the public members of a target object (based on its run-time class) or the members declared by a given class. More specifically , the reflection API enables the following operations:

  • Determine the class of an object.

  • Get information about a class's modifiers, fields, methods, constructors, and superclasses.

  • Find out what constants and method declarations belong to an interface.

  • Create an instance of a class whose name is not known until run time.

  • Get and set the value of an object's field, even if the field name is unknown until run time.

  • Invoke a method on an object, even if the method is not known until run time.

  • Create a new array, whose size and component type are not known until run time, and then modify the array's components

For each class, the Java Run-time Environment (JRE) maintains an immutable Class object which represents, or reflects, the class [JRE]. The reflection API allows invoking methods on that Class object which return Constructor , Method , and Field objects. One can also invoke Class methods to find out about an interface's modifiers, methods, and public constants. However, not all of the Class methods are appropriate when a Class object reflects an interface. For example, it is not appropriate to invoke getConstructors() when the Class object represents an interface.

7.4.3 Java Class Loaders

Typically, the JVM instantiates classes from the local file system in a platform-dependent manner. For example, on UNIX and Windows systems, the JVM loads classes from the directory defined by the CLASSPATH environment variable. The class ClassLoader is an abstract class, which can be subclassed to extend the manner in which the JVM instantiates classes.

The methods and constructors of objects created by a class loader may reference other classes. To determine the class(es) referred to, the JVM invokes the loadClass() method of the class loader that originally created the referring class. To determine the existence of a class, there is no need to know its superclass, in which case resolution is disabled by setting the resolve flag to false. However, if an instance of the class is being created or any of its methods are being called, the class must also be resolved. In this case the resolve flag is set to true, and the resolveClass() method should be called.

Consider an application that creates a custom class loader to download class files from a DSM-CC transport (see Example 7.3). In this example, the DSM-CC class loader must define the method loadClass() to load a class from the MPEG DSM-CC transport. Once it has downloaded the data bytes that make up the class, it should use the method defineClass() to create a class instance (see Example 7.4 for a sample implementation).

Example 7.3 Creating a class using a custom class loader.
  ClassLoader loader = new DSMCC_ClassLoader(TSID, CarouselID, ModuleID, ObjectrKey);   Object main = loader.loadClass("XletMain", true).newInstance();  
Example 7.4 Customization of the class loader.
  class DSMCC_ClassLoader {int TSID, int carouselID,   int moduleID, String objectKey) {   Hashtable cache = new Hashtable();   private byte loadClassData(String name)[] {   // code to load the class data from the MPEG DSMCC transport   }   public synchronized Class loadClass(String name, boolean resolve) {   Class c = cache.get(name);   if (c == null) {   byte data[] = loadClassData(name);   c = defineClass(data, 0, data.length);   cache.put(name, c);   }   if (resolve) resolveClass(c);   return c;   }   }  

Because overriding class loaders opens the door for malicious code to perform unexpected operations or even damage the system, most implementations and iTV standards prohibit its usage by the downloaded JavaTV Xlet. It should only be used by code authorized by the manufacturer of a platform.



ITV Handbook. Technologies and Standards
ITV Handbook: Technologies and Standards
ISBN: 0131003127
EAN: 2147483647
Year: 2003
Pages: 170

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net