|
Articles Index | Java TV Articles Index | Wireless Initiative
By Monica Pawlan
February 2001
As television viewers become more sophisticated, the demands for more
interactive technology will increase. To meet this demand, Sun is
releasing the Java TV API.
Java TV applications enhance the broadcast and viewing
experience by providing such features as programming information and
announcements, selectable applications such as the ability to play along
with a game show, broadcast data such as a stock ticker banner running
across the screen, or media control such as an interactive
program-related survey.
Television viewers with Java-enabled digital television receivers
will be able to receive and interact with Java TV applications while
watching network programming. The tool for interacting with Java TV
applications is the viewer's television remote.
The newly released Java TV reference
implementation implements of the Java TV specification that
includes the Java TV and Java Media Framework (JMF) APIs. It requires a
PersonalJava
virtual machine and class libraries to run. The source base is currently
available to licensed digital
receiver manufacturers (Java TV licensees) so Java-enabled digital receivers
should be available to consumers soon. Developers working for licensed
companies that specialize in creating digital TV content will use the
Java TV API to write digital television applications that either reside
on or are downloaded to Java-enabled digital TV receivers.
The Java TV API will be available to the public at a later date through
Sun's Community
Source Licensing program. At that time, developers who work for television
networks can use the Java TV API to write digital television applications that
accompany network program broadcasts. While there are a wide variety of digital
television receivers with varying capabilities, the Java TV API lets developers
access their common features and scales across different receiver implementations.
This article introduces the Java TV API and presents short examples
to show the structure of a Java TV application. However, unless you
have access to a Java TV compliant environment, you cannot run
and test the examples.
Xlets
Another name for Java TV applications is Xlets. Like applets, Xlets
are controlled by the software that runs them. In the case of an applet, the
underlying software is a browser or the appletviewer tool. In the case of an
Xlet, the underlying software is the digital television receiver or set-top
box that supports the Java TV platform.
There is no main method and Xlets always implement the
Xlet interface. Like applets, Xlets have a life
cycle, and the life cycle method signatures are defined by the
Xlet interface.
Life Cycle
The Xlet interface provides life cycle methods to signal
the following Xlet state changes:
- Create
- Initialize
- Start
- Pause
- Destroy
All Java TV implementations have an application manager that calls the life
cycle methods to move one or more Xlets through their various application
states. For example, the viewer might be playing a game along with a game
show and decide to check program listings. If the program listings and
game are both Xlets, the software in the receiver is signaled that an Xlet
is present when the viewer selects the program listings. At this point, the
application manager pauses the game Xlet, and the receiver downloads the
program listings Xlet into the receiver. The application manager loads and
starts the program listing Xlet. If the viewer goes back to the game, the
application manager pauses the program listing Xlet and starts the game Xlet.
The Xlet interface provides no implementations for
its life cycle methods. The developer provides application-specific
implementations for those methods by defining what happens at each point
in the Xlet life cycle. For example, the initXlet method
for the game Xlet might create the user interface components.
An Xlet can initiate some state changes itself and inform the application manager
of those state changes by invoking methods on the XletContext
interface. An XletContext object is passed to an Xlet when the
Xlet is initialized to give the Xlet a way to retrieve properties and signal
internal state changes.
Packages
The Java TV API reference implementation requires the
PersonalJava Application
Environment, Version 3.1, which provides core Java
capabilities including the Abstract Window Toolkit (AWT) for
building user interfaces. Some core Java packages are included in the
PersonalJava platform without change from Java 2 Standard Edition,
while others have been subsetted by removing functionality not
appropriate for consumer products.
The Java TV API consists of classes and interfaces grouped
into the following packages. These packages contain classes and
interfaces to process the video, audio, and data sent to the digital
receiver through the broadcast stream sent by the television networks.
The digital receiver gets video, audio, and data from the broadcast
stream and processes it through a broadcast media and data pipeline.
javax.tv.carousel provides access to remote file
and directory data contained in the broadcast.
javax.tv.graphics enables simple compositing
(imposing one image over another to create one image) and
provides a container for building a user interfaced with AWT components.
javax.tv.locator provides access to data and resources
addressable within a television receiver. Locators can reference broadcast
file systems, portions of service information, sources of audio and
visual content, and interactive applications.
javax.tv.media defines extensions to the
Java Media Framework (JMF) to manage the broadcast media pipeline
which contains real-time audio and visual content.
javax.tv.media.protocol provides access to generic
streaming data in the television broadcast.
javax.tv.net provides access to Internet Protocol
(IP) datagrams transmitted in the broadcast stream.
javax.tv.service provides access to the service
information (SI) database and basic SI APIs common to its
subpackages.
javax.tv.service.guide supports electronic
program guides with schedules, events, and ratings.
javax.tv.service.navigation supports hierarchical service
and service information navigation.
javax.tv.service.selection supports service selection
menus.
javax.tv.service.transport lets you query the broadcast
delivery mechanisms.
javax.tv.util supports the creation and management
of timer events.
javax.tv.xlet provides life cycle and property management
methods.
Example Xlets
Xlets are typically small programs that perform simple functions
such as electronic programming guides (EPGs), interactive games,
enhanced content, managing the broadcast media pipeline, or managing
the broadcast data signal.
This section presents two example Xlets. The first example displays
a selectable list of services (channels); the second example
retrieves and rotates through a list of programs and services
presenting each service at the command line for 10 seconds.
When run on a digital receiver, the second example Xlet presents
the programs and services in the broadcast receiver where they
can be retrieved by another Xlet and displayed in a user interface.
Display List of Selectable Services
The SvcDispXlet class displays a list
of selectable services. The user can select a service and display
details related to the selected service.
The SvcDispXlet implements the Xlet
interface. In the initXlet method, the root
container of the user interface is retrieved and the user interface
created. Additionally, an instance of the SIManager
class is acquired. This object is used to access the SI information
that will be displayed by the Xlet.
The Xlet implements the ActionListener interface
so it can listen for action events generated by the user interface
components. In this example, the Xlet listens for action events
generated by the list of programs and services and by a
Refresh button. The Refresh button
updates the service list by adding new programs and services and
removing old ones.
- The Xlet is made an action listener for action events
generated by the list when the user selects a program or service.
- The Xlet is made an action listener for action events
generated by the
Refresh button when the viewer uses
the remote to select it.
The underlying Java platform calls the Xlet's actionPerformed
method when action events are generated by user interface components for
which the Xlet has been made an action listener. The actionPerformed
method checks which component generated the event and passes it to the
UpdateList method where the appropriate action is taken based on
whether the list or button generated the event.
The SIManager object created with the call to
SIManager.createInstance() is the entry point
into the SI database.
The SIManager is used in the updateList
method to create and manage the programs and services list.
The Xlet defines a Retriever class, which
implements the SIRequestor interface. This interface is
implemented by application classes to receive the results of
asynchronous SI retrieval requests. The updateList method
calls the getPrograms method in the Retriever
class to retrieve the updated programs and services list.
import javax.tv.xlet.*;
import javax.tv.graphics.*;
import javax.tv.service.*;
import javax.tv.service.guide.*;
import javax.tv.service.navigation.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Date;
import java.text.DateFormat;
public class SvcDispXlet implements Xlet,
ActionListener {
private Container root_container = null;
private Panel panel = null;
private List slist = null;
private List plist = null;
private Button button = null;
private SIManager si_manager = null;
private Retriever retriever = new Retriever();
// init method
public void initXlet(XletContext ctx){
root_container = TVContainer.getRootContainer(ctx);
panel = new Panel();
panel.setBackground(Color.black);
root_container.setLayout(null);
root_container.setBounds(0,0,400,300);
root_container.add(panel);
panel.setBounds(0, 0,
root_container.getSize().height,
root_container.getSize().width - 50);
panel.setLayout(new GridLayout(2,1));
slist = new List();
slist.setBackground(Color.lightGray);
slist.addActionListener(this);
panel.add(slist);
plist = new List();
plist.setBackground(Color.lightGray);
panel.add(plist);
button = new Button("Refresh");
button.setBackground(Color.darkGray);
button.setForeground(Color.white);
button.addActionListener(this);
root_container.add(button);
button.setBounds(0,
root_container.getSize().width-50,
root_container.getSize().height,
50);
root_container.validate();
root_container.setVisible(true);
si_manager = SIManager.createInstance();
}
// start method
// Do an initial update of the slist
public void startXlet(){
panel.validate();
updateList(slist);
}
// pause
public void pauseXlet(){}
// destroy
public void destroyXlet(boolean unconditional){}
// called when the refresh button is pressed
// or service is selected in the list
public void actionPerformed(ActionEvent evt){
if(evt.getSource() == button){
this.updateList(slist);
plist.removeAll();
} else if (evt.getSource() == slist) {
this.updateList(plist);
}
}
private void updateList(List list){
//Clear out the old list
list.removeAll();
ServiceList collection =
si_manager.filterServices(null);
ServiceIterator si =
collection.createServiceIterator();
si.toEnd();
if(list == slist) {
while(si.hasPrevious()){
slist.addItem(
si.previousService().getName(), 0);
}
} else {
while(si.hasPrevious()){
Service s = si.previousService();
if(slist.getSelectedItem().
equals(s.getName())) {
retriever.getPrograms(s);
break;
}
}
}
}
class Retriever implements SIRequestor {
DateFormat dfmt =
DateFormat.getDateInstance(DateFormat.SHORT);
DateFormat tfmt =
DateFormat.getTimeInstance(DateFormat.SHORT);
void getPrograms(Service s) {
try{
SIManager.createInstance().
retrieveServiceDetails(
s.getLocator(), this);
} catch (Exception e) {
e.printStackTrace();
}
}
public void notifySuccess(
SIRetrievable[] result) {
if(result[0] instanceof ServiceDetails) {
try{
((ServiceDetails)result[0]).
getProgramSchedule().
retrieveFutureProgramEvents(new Date(),
new Date(System.currentTimeMillis()
+ 600000000), this);
catch (SIException e) {}
} else if (result[0] instanceof ProgramEvent) {
for(int i = 0; i < result.length; i++ ) {
ProgramEvent e = (ProgramEvent)result[i];
plist.addItem(e.getName() + " : "
+ dfmt.format(e.getStartTime())
+ " "
+ tfmt.format(e.getStartTime()));
}
}
}
public void notifyFailure(
SIRequestFailureType reason) {}
} //End Retriever class
} //End SvcDispXlet class
|
Present Rotating List of Programs and Services
The ServiceSelectorXlet Xlet
presents a rotating list of selectable services. Each service presents
(is printed to the command line) for 10 seconds before rotating to the next
service.
This Xlet implements ServiceContextListener so it
can listen to action events related to service contexts. A service
context represents an environment in which services are presented
in a broadcast receiver. The initXlet method creates a
ServiceContext object, and the Xlet uses the
ServiceContext object to select new services in the
broadcast media to be presented to the digital receiver.
The startXlet method checks for a service context object,
and creates one if none currently exists. Once a service context object
is created either by init or start, the Xlet is made an action listener
for action events generated by the service context. When a service
context event is generated, the underlying Java platform calls the
receiveServiceContextEvent method, which checks which
context event occurred and handles the action event accordingly.
The context event can indicate that the presentation changed, terminated,
or failed. A change is a success, and the name of the changed service is
printed to the command line with a notice that it succeeded. If the
presentation terminated or failed, the reason for the termination or
failure is retrieved and printed to the command line.
import javax.tv.locator.*;
import javax.tv.service.*;
import javax.tv.service.navigation.*;
import javax.tv.service.selection.*;
import javax.tv.xlet.*;
public class ServiceSelectorXlet
implements Xlet, ServiceContextListener {
ServiceContextFactory scf;
ServiceContext sc;
public void initXlet(XletContext context) {
scf = ServiceContextFactory.getInstance();
try{
sc = scf.getServiceContext(context);
} catch (Exception e) {}
}
public void pauseXlet() {}
public void destroyXlet( boolean unconditional ) {}
public void startXlet() {
//If fail to get a service context at initXlet
if(sc == null) {
try{
//Get all existing service contexts
ServiceContext[] ctxs = scf.getServiceContexts();
if(ctxs.length > 0) {
sc = ctxs[0];
} else {
// none available, try to create one then.
sc = scf.createServiceContext();
}
} catch (Exception e) {
System.out.println(
"Cannot obtain a valid ServiceContext: "
+ e);
return;
}
}
// Add ServiceContextListener
sc.addListener(this);
//Get all available Services from SIManager
ServiceList list = SIManager.createInstance().
filterServices(null);
//Iterate the list to tune
for(int i = 0; i < list.size(); i++ ) {
try{
Service s = list.getService(i);
System.out.println("selecting: "
+ s.getName());
sc.select(s);
Thread.sleep(20000);
} catch (Exception e) {
System.out.println("selection failed: " + e);
}
}
System.out.println("End of startXlet()");
}
//Invoked when selection completes
public void receiveServiceContextEvent(
ServiceContextEvent event) {
//Selection success
if(event instanceof PresentationChangedEvent) {
Service currentService =
event.getServiceContext().getService();
System.out.println("Selection succeeded for: "
+ currentService.getName());
//Selection terminated
} else if (event instanceof
PresentationTerminatedEvent) {
int reason = ((PresentationTerminatedEvent)event).
getReason();
System.out.println(
"Selection terminated with a reason: "
+ reason);
//Selection failed
} else if (event instanceof SelectionFailedEvent) {
int reason = ((
SelectionFailedEvent)event).getReason();
System.out.println(
"Selection failed with a reason: "
+ reason);
}
}
}
|
More Information
You can find more information on the Java TV platform at the
following web sites and forums:

Monica Pawlan is a manager and writer at Sun Microsystems, Inc., who enjoys learning and writing about new Java platform technologies. She also likes to garden, play guitar, and travel.
Have a question about programming?
Use Java Online Support.
1 As used on this web site, the terms Java virtual
machine or Java VM mean a virtual machine for the Java platform.
|