This is a discussion on J2ME Tips & Tricks within the J2ME forums, part of the Mobile Software Development category; The Problem: J2ME's TimerTask is run on a background thread independant of the event thread thus causing potential synchronization ...
| |||||||
| Register | FAQ | Members List | Calendar | Mark Forums Read |
| |||
| The Problem: J2ME's TimerTask is run on a background thread independant of the event thread thus causing potential synchronization problems with things like drawing to the screen etc. The solution: Derive from the TimerTask a threadsafe TimerTask that calls itself serially thus placing itself in the event thread. The following derived class has an option to run serialized on the event thread or as a normal TimerTask. Code: import java.util.TimerTask;
public class GeneralTimerTask extends TimerTask
{
private boolean runOnEventThread;
public GeneralTimerTask(boolean runOnEventThread)
{
this.runOnEventThread= runOnEventThread;
}
private Thread timerThread;
public void run()
{
if (timerThread == null)
{ // first run through will be on the timer thread
timerThread = Thread.currentThread();
}
if (timerThread==Thread.currentThread() && runOnEventThread)
{
MApp.mainApp.d.callSerially(this);
}
else
{
(call whatever handler/function you want to execute here)
}
}
} Code: Timer timer; GeneralTimerTask timerTask; long updateDelay = 500; // milliseconds ... timerTask = new GeneralTimerTask(true); timer.schedule(timerTask, updateDelay); // GeneralTimerTask:run will now be called every 500ms ... timerTask.cancel(); Last edited by prasannavigneshr : 08-21-2007 at 03:14 AM. |
| Sponsored Links |
| |||
| Adding JSR75 Contacts: To set up contacts for the WTK or Sprint emulator for JSR75 access you need to make some vcards. The vcards should have the following format: begin:vcard fn:Will Perone n:Perone; Will;; TEL;HOME; VOICE:123-456-7890 TEL; CELL; VOICE:987-654-3210 URL; HOME:Prasanna Vignesh EMAIL;INTERNET:mail@office. version:2.1 end:vcard The TEL, UTL and EMAIL lines are all optional (and I think the n and fn too). You can go here to find out more about the vcard format. The cards should be saved in .vcf files (If you have Outlook or Outlook Express you can create contacts in there and save them as vcard files as well). Put the vcards in the (toolkit)/appdb/(phone)/pim/contacts/Contacts and that's it! Now your j2me app will be able to access some contacts in the emulator. You can go here for more info. Last edited by prasannavigneshr : 07-24-2008 at 09:42 PM. |
| |||
| Script Error 909: Figuring out what is going on when we get a 909 error while trying to install our application may take quite some time (trust me). Here are some things to check: If this is a developer phone, make sure you have activated it on the Sprint Developer Site. When you type in the ESN for activation (this is on the back of the phone behind the battery) make sure the letters are the correct case (usually upper case); typing in the wrong case letters will not activate the phone. Also there will be no notification sent when the phone is activated but usually it's the same day. If the phone is not developer enabled and you have an application with a developer certificate (not a Verisign certificate) then you will also get this error. This can be eliminated by removing the certificate and Midlet-Permissions from the jad altogether. Also on some phones (Sanyo mainly) this error can come up if the manifest file and the jad file have their Midlet-Permissions mismatching. According to the Manifest file format, the lines are supposed to wrap at 72 characters and the next line will insert a space and continue the previous line. The jad file will end up with one long line for the Midlet-Permissions while the Manifest have a bunch of lines. This can cause some phones to give a 909 error. To correct it you need to actually go back into the Manifest file in the jar and take out the line breaks/spaces so that Midlet-Permissions is exactly the same as the jad file. After you do this you need to make sure you update the jad with the correct jar size. Unfortunately there is no way to get the jad file to do multiple lines for a property so you will likely need a post processing step in your build process to unjar, correct the manifest, rejar then rewrite the jad. On a related note, you will get a 910 error if you have no certificate in the jad but have Midlet-Permissions. Also Make sure that the phone hasn't cached the jad/jar otherwise it will not download the new version of the program. You can do this by adding a ?(some letter) to the end of the url to grab the jad from on the phone. Hope Usefull. |
| |||
| Image Scaling in J2ME: This function scales images using an optimized form of bresenham's formula. You can also add bilinear sampling and such to it but I figured since it's on a cell phone it won't matter much and will also cause it to be slower. Code: public static Image scaleImage(Image original, int newWidth, int newHeight)
{
int[] rawInput = new int[original.getHeight() * original.getWidth()];
original.getRGB(rawInput, 0, original.getWidth(), 0, 0, original.getWidth(), original.getHeight());
int[] rawOutput = new int[newWidth*newHeight];
// YD compensates for the x loop by subtracting the width back out
int YD = (original.getHeight() / newHeight) * original.getWidth() - original.getWidth();
int YR = original.getHeight() % newHeight; int XD = original.getWidth() / newWidth;
int XR = original.getWidth() % newWidth;
int outOffset= 0;
int inOffset= 0;
for (int y= newHeight, YE= 0; y > 0; y--)
{
for (int x= newWidth, XE= 0; x > 0; x--)
{
rawOutput[outOffset++]= rawInput[inOffset];
inOffset+=XD;
XE+=XR;
if (XE >= newWidth)
{
XE-= newWidth; inOffset++;
}
}
inOffset+= YD;
YE+= YR;
if (YE >= newHeight)
{
YE -= newHeight; inOffset+=original.getWidth();
}
}
return Image.createRGBImage(rawOutput, newWidth, newHeight, false);
} |
| |||
| J2ME Tips & tricks: Consider the following two pieces of code Code: if (screenSize==SMALL_SCREEN)
x = 2;
else if (screenSize==LARGE_SCREEN)
x = 4;
else if (screenSize==QVGA_SCREEN) x = 6; Code: switch(screenSize)
{
case SMALL_SCREEN: x = 2;
break;
case LARGE_SCREEN: x = 4;
break;
case QVGA_SCREEN: x = 6;
break;
} Code: public static final int SMALL_SCREEN = 0; public static final int LARGE_SCREEN = 1; public static final int QVGA_SCREEN = 2; Code: public static final int screenSize = ${screenSize}; |
| |||
| Draw mutable image on a canvas import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class MutableImageWithCanvas extends MIDlet { private Display display; // The display private ImageCanvas canvas; // Canvas public MutableImageWithCanvas() { display = Display.getDisplay(this); canvas = new ImageCanvas(this); } protected void startApp() { display.setCurrent( canvas ); } protected void pauseApp() { } protected void destroyApp( boolean unconditional ) { } public void exitMIDlet() { destroyApp(true); notifyDestroyed(); } } /*-------------------------------------------------- * Class ImageCanvas * * Draw mutable image *-------------------------------------------------*/ class ImageCanvas extends Canvas implements CommandListener { private Command cmExit; // Exit midlet private MutableImage midlet; private Image im = null; private String message = "Core J2ME"; public ImageCanvas(MutableImage midlet) { this.midlet = midlet; // Create exit command & listen for events cmExit = new Command("Exit", Command.EXIT, 1); addCommand(cmExit); setCommandListener(this); try { // Create mutable image im = Image.createImage(80, 20); // Get graphics object to draw onto the image Graphics graphics = im.getGraphics(); // Specify a font face, style and size Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM); graphics.setFont(font); // Draw a filled (black) rectangle graphics.setColor(0, 0, 0); graphics.fillRoundRect(0,0, im.getWidth()-1, im.getHeight()-1, 20, 20); // Center text horizontally in the image. Draw text in white graphics.setColor(255, 255, 255); graphics.drawString(message, (im.getWidth() / 2) - (font.stringWidth(message) / 2), 0, Graphics.TOP | Graphics.LEFT); } catch (Exception e) { System.err.println("Error during image creation"); } } /*-------------------------------------------------- * Draw mutable image *-------------------------------------------------*/ protected void paint(Graphics g) { // Center the image on the display if (im != null) g.drawImage(im, getWidth() / 2, getHeight() / 2, Graphics.VCENTER | Graphics.HCENTER); } public void commandAction(Command c, Displayable d) { if (c == cmExit) midlet.exitMIDlet(); } } |
| |||
| Load Image - J2ME Code: import java.io.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class ImageLoader extends MIDlet
implements CommandListener, Runnable {
private Display mDisplay;
private Form mForm;
public ImageLoader() {
mForm = new Form("Connecting...");
mForm.addCommand(new Command("Exit", Command.EXIT, 0));
mForm.setCommandListener(this);
}
public void startApp() {
if (mDisplay == null) mDisplay = Display.getDisplay(this);
mDisplay.setCurrent(mForm);
// Do network loading in a separate thread.
Thread t = new Thread(this);
t.start();
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
public void commandAction(Command c, Displayable s) {
if (c.getCommandType() == Command.EXIT)
notifyDestroyed();
}
public void run() {
HttpConnection hc = null;
DataInputStream in = null;
try {
String url = getAppProperty("ImageLoader-URL");
hc = (HttpConnection)Connector.open(url);
int length = (int)hc.getLength();
byte[] data = null;
if (length != -1) {
data = new byte[length];
in = new DataInputStream(hc.openInputStream());
in.readFully(data);
}
else {
// If content length is not given, read in chunks.
int chunkSize = 512;
int index = 0;
int readLength = 0;
in = new DataInputStream(hc.openInputStream());
data = new byte[chunkSize];
do {
if (data.length < index + chunkSize) {
byte[] newData = new byte[index + chunkSize];
System.arraycopy(data, 0, newData, 0, data.length);
data = newData;
}
readLength = in.read(data, index, chunkSize);
index += readLength;
} while (readLength == chunkSize);
length = index;
}
Image image = Image.createImage(data, 0, length);
ImageItem imageItem = new ImageItem(null, image, 0, null);
mForm.append(imageItem);
mForm.setTitle("Done.");
}
catch (IOException ioe) {
StringItem stringItem = new StringItem(null, ioe.toString());
mForm.append(stringItem);
mForm.setTitle("Done.");
}
finally {
try {
if (in != null) in.close();
if (hc != null) hc.close();
}
catch (IOException ioe) {}
}
}
} |
| |||
| Image Transparency in J2ME Firstly, the native transparent file format in MIDP is the .png file. On the Series 40 (7210, 6610, 6100), a .png file allows not only entirely transparent pixels, but also translucent ones. Unfortunately, with the Series 60 (3650, 7650) as far as I can see, only transparent pixels can be used - which is the main thing. Save a .png file with a transparency mask. To do this in paint shop pro: 1. File->New Image. 2. Draw Image. 3. Masks->New->Show All. 4. Masks->View Mask 5. Masks->Edit 6. The colour palette will change to grey scale - select absolute black (0,0,0) 7. Paint over the pixels in your image that you wish to be invisible. 8. Masks->Save to Alpha Channel. 9. Hit OK twice. 10. Save the image. To use the newly created image in your app. 1. Make sure you have the path with the graphics files mounted (right click on File Systems->Mount->Local Directory) 2. Include the .png file in your jar file - In Sun One, right click the Midlet Suite Icon and select 'Edit Suite', then the tab 'Jar Contents'. Browse on the left side to the newly mounted directory, and select the png file. Click 'Add'. Click 'OK'. 3. Create a class variable: [Image MadCrazyDudeImage=null;] 4. In your Class constructor (or wherever appropriate), create the image from the .png file. [MadCrazyDudeImage= Image.createImage("/MadCrazyDude.png");] It is vital that the case of the name is the correct case, and that you preceed the filename with the forward slash. 5. Create a DirectGraphics object in your paint routine, and initialise it: [DirectGraphics dg; dg=DirectUtils.getDirectGraphics(graphics);] 6. Draw the image to the canvas. [dg.drawImage(MadCrazyDudeImage, 0, 0, Graphics.TOP | Graphics.LEFT, 0);] If this doesn't work, it may be that you are trying to read the graphics out of a graphics strip first (this is the part that threw me when porting my first Series 40 to a Series 60 phone). To do this, you cannot use a Graphics object alone to create your individual images. They have to be passed through a DirectGraphics object for the transparency to be maintained. I include the code that I use below: In the class global area: Image imReceptors=null; Image Receptors[]=new Image[12]; imReceptors=Image.createImage("/S60receptors.png"); for (int i=0; i<12; i++) { Receptors[i]=DirectUtils.createImage(21, 20, 0x00000000); Graphics g = Receptors[i].getGraphics(); DirectGraphics dgtemp=DirectUtils.getDirectGraphics(g); dgtemp.drawImage(imReceptors, -21*i, 0, Graphics.TOP | Graphics.LEFT, 0); } imReceptors=null; It's best to put a try...catch block around your graphics creation code to make sure that there isn't a problem there (i usually just add a System.out.println("Graphics Error here") type of statemnt to the catch block). If using Sun One, you may be getting frustrated because Sun One is expecting the graphics to be located a sub folder up from where you would expect it to look for them. Try placing the images into the parent directory of your app project if Sun One is struggling to find them in the main app directory. Thanks |
| |||
| This j2ME tips illustrates method of using a ChoiceGroup in mobile applications. ChoiceGroup is a group of selectable elements intended to be placed within a Form. Code: import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class ChoiceGroupDemo extends MIDlet implements CommandListener {
private boolean boolMotion=false;
Display mDisplay;
Form frm;
ChoiceGroup cg;
Command cmd;
ChoiceGroupDemo() {
frm=new Form("Choice Group Demo");
cg=new ChoiceGroup("Choose Movie:",Choice.MULTIPLE);
cmd=new Command("OK",Command.OK,1);
cg.append("Horror",null);
cg.append("Comedy",null);
cg.append("Action",null);
frm.append(cg);
frm.setCommandListener(this);
}
public void commandAction(Command c, Displayable d) {
for(int i=0;i<3;i++) {
if(cg.isSelected(i)) {
System.out.println("u selected :" +
cg.getString(elementNum));
return;
}
}
}
public void startApp() {
mDisplay = Display.getDisplay(this);
mDisplay.setCurrent(frm);
}
public void pauseApp() {}
public void destroyApp(boolean unconditional){}
} |
| |||
| The Java tips describes methods of using different fonts in J2ME application. The Font class represents fonts and font metrics. Fonts cannot be created by applications. The setFont(Font font) method of graphic class sets the font for all subsequent text rendering operations. And there is no call to showNotify and hideNotify method on some the device. This application will help game developer to find out the exact behaviour of mobile device. import javax.microedition.midlet.*; import javax.microedition.lcdui.*; Code: public class FontDemo extends MIDlet {
private boolean boolMotion=false;
private int iX=10, iY=60;
Display mDisplay;
Thread th;
public void destroyApp(boolean unconditional){}
public void pauseApp() {}
public void startApp() {
mDisplay = Display.getDisplay(this);
final MyCanvas can = new MyCanvas();
mDisplay.setCurrent(can);
}
}
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class MyCanvas extends Canvas {
Font font;
String msg;
public MyCanvas() {
font=Font.getFont(Font.FACE_MONOSPACE,
Font.STYLE_ITALIC, Font.SIZE_LARGE);
msg = "Font:FACE_MONOSPACE Font.STYLE_ITALIC Font.SIZE_LARGE";
}
public void paint(Graphics g) {
g.setFont(font);
g.drawString(msg,0,10,g.TOP|g.LEFT);
g.drawString("press NUM KEY: 1 2 or 3",0,80,g.TOP|g.LEFT);
}
void changeValue(int change) {
switch(change) {
case '1':
font=Font.getFont(Font.FACE_MONOSPACE,
Font.STYLE_ITALIC, Font.SIZE_LARGE) ;
msg="Font:FACE_MONOSPACE Font.STYLE_ITALIC "+
"Font.SIZE_LARGE";
break;
case '2':
font=Font.getFont(Font.FACE_PROPORTIONAL,
Font.STYLE_ITALIC, Font.SMALL) ;
msg = "Font:FACE_PROPORTIONAL Font.STYLE_ITALIC "+
"Font.SIZE_SMALL";
break;
case '3':
font=Font.getFont(Font.FACE_SYSTEM ,
Font.STYLE_BOLD, Font.SIZE_LARGE) ;
msg="Font:FACE_SYSTEM Font.STYLE_BOLD "+
"Font.SIZE_LARGE";
break;
}
}
//Handling keyEvents
protected void keyPressed(int keyCode) {
changeValue(keyCode);
repaint();
}
} |
| |||
| Canvas class of javax.microedition.lcdui package gives faciltiy of low level level graphics on mobile. An application gets the drawing area by methods getWidth() and getHeight(). The illustration below draws a rectangle on the mobile device's screen: Code: public void paint(Graphics g)
{
// get the dimensions of the screen:
int width = getWidth ();
int height = getHeight();
// clear the screen (paint it white):
g.setColor(0xffffff);
g.fillRect(0, 0, width, height);
Font font = g.getFont();
int fontHeight = font.getHeight();
int fontWidth = font.stringWidth("Hello World!");
// set the text color to red:
g.setColor(255, 0, 0);
g.setFont(font);
g.drawString("Hello World!", (width - fontWidth)/2,
(height - fontHeight)/2,g.TOP|g.LEFT);
} |
| |||
| * Eliminate unnecessary features. * Avoid inner classes: make the main class implement the required Listener interfaces and handle the callbacks there. * Use built-in classes if functionality is close enough, and work around their limitations. * Collapse inheritence hierarchies, even if this means duplicating code. * Shorten all names (packages, classes, methods, data variables). Some obfuscators can do this automatically. MIDP applications are completely self-contained, so you can use the default package with no possible name-clash. * Convert array initialization from code to extract data from a binary string or data file. Array initialization generates many bytecodes as each element is separately initialized. |
| |||
| Flicker-free graphics with the Mobile Information Device Profile * Use double buffering: draw into an offscreen buffer, then copy into the display buffer. Copying buffers is very fast on most devices, while directly drawing to a display sometimes causes users to see a flicker, as individual parts of the display are updated. Double buffering avoids flickering by combining multiple individual drawing operations into a single copy operation. * Use the Canvas.isDoubleBuffered() method, to determine if double buffering is already automatically used: on some implementations the Canvas object's paint method is already a Graphics object of an offscreen buffer managed by the system. (The system then takes care of copying the offscreen buffer to the display.) * Use javax.microedition.lcdui.Image class to create an offscreen memory buffer, and use Graphics to draw to the offscreen buffer and to copy the contents of the offscreen buffer onto the display. The offscreen buffer is created by calling one of the Image.createImage methods. * Double buffering does have some overhead: if only making small changes to the display, it might be slower to use double buffering. * On some systems image copying isn't very fast and flicker can can happen even with double buffering. * Keep the number of offscreen buffers to a minimum. There is a memory penalty to pay for double buffering: the offscreen memory buffer can consume a large amount of memory. * Free the offscreen buffer whenever the canvas is hidden (use the canvas' hideNotify() and showNotify() methods.) |
| |||
| The various J2ME JSR documents define system property names that can be queried at runtime. These provide two services: To indicate the availability of an optional package: For example, if the device supports the Location API for J2ME then the property microedition.location.version will be present. The value associated with it will be "1.0", to indicate compliance with JSR 179. To provide platform-dependent configuration data For instance, the property microedition.commports is present in the MIDP 2.0 specification. Its value is a comma-separated list of ports you can use to build a URL, which the Generic Connection Framework can in turn use to create a javax.microedition.io.CommConnection object. |
| |||
| The Mobile Media API (MMAPI) is an optional package within the Java 2 Platform, Micro Edition (J2ME), that provides a standard API for rendering and capturing time-based media, such as audio tracks and video clips. Developed within the Java Community process as JSR 135, MMAPI was designed to be flexible and platform-independent; it makes no assumptions about media formats, protocols, or features supported by various devices. MMAPI is already making its way into mobile devices; the Nokia 3650, for example, includes an implementation. Other devices that support MMAPI can be found at "J2ME Devices." This article services the latest developments in MMAPI: the new security considerations raised in MMAPI 1.1, the differences between MMAPI and the MIDP 2.0 Media API, J2ME Wireless Toolkit 2.2 support for MMAPI, and JSR 234, Advanced Multimedia Supplements. If you're looking for a tutorial on MMAPI as well as code samples, for an audio/video player, for instance, see the articles "The J2ME Mobile Media API" and "Taking Pictures With MMAPI." Overview of MMAPI Components MMAPI has four main components: Player is used to play content. It provides methods to manage a Player's life-cycle, and to manage various playback features. Manager is the overall controller of the media. It creates Players. DataSource represents a protocol handler, usually not visible to the application developer. The protocol handler reads the media data and fetches it to Player for playback. Control controls various features of Player and playback operations. Supported MMAPI Controls MMAPI has 12 controls, in the package javax.microedition.control: MetaDataControl retrieves metadata information from the media. MIDIControl provides access to MIDI rendering and transmitting devices. GUIControl represents a control that provides a UI component. PitchControl raises or lowers the playback pitch without changing the playback speed. RateControl controls the playback rate. TempoControl controls the tempo of a MIDI song. VolumeControl controls the volume. VideoControl controls the display of visual content. FramePositioningControl enables precise positioning to a video frame. RecordControl records what is currently being played by the Player. StopTimeControl enables an application to define a preset stop time for a Player. ToneControl is an interface that enables playback of user-defined tone sequences. Be aware that not all MMAPI implementations support all types of controls. You can find out what a device does support by calling System.getProperty(String key). The specification defines these properties: microedition.media.version returns a string representing the version of MMAPI implemented, "1.0" or "1.1" if MMAPI is supported, or null if it isn't. supports.mixing returns true if mixing is supported, false if it isn't. supports.audio.capture returns true if audio capture is supported, false if it isn't. supports.video.capture returns true if video capture is supported, false if it isn't. supports.recording returns true if recording is supported, false if it isn't. audio.encodings returns a string representing the supported audio capture formats, or null if audio capture isn't supported. video.encodings returns a string representing the supported video capture formats, or null if video capture isn't supported. video.snapshot.encodings returns a string representing the supported image capture formats, or null if video snapshot isn't supported. streamable.contents returns a string representing the supported streamable content types, in MIME syntax. |
| |||
| The PushRegistry maintains a list of inbound connections. An application can register the inbound connections with an entry in the JAD file or by dynamically calling the registerConnection method. If a notification arrives for a registered MIDlet when the application is not running, the AMS will start the MIDlet via the MIDlet.startApp method. Code: /*Display the list of all inbound connections.*/
public void displayConnections() {
String[] allConnections = PushRegistry.listConnections(false);
StringBuffer sbuf = new StringBuffer();
if (allConnections != null && allConnections.length > 0) {
for (int i = 0; i < allConnections.length; i++ ) {
sbuf.append(allConnections[i]);
sbuf.append("\n");
}
}
String str = sbf.toString();
}
/*Register or Unregister an inbound connection*/
public void regConnection() {
try {
String url = "socket://";
String classname = "Midlet" //Midlet to be launched
if (register) {
PushRegistry.registerConnection(url, classname, "*");
} else {
PushRegistry.unregisterConnection(url);
}
} catch (IllegalArgumentException iae) {
} catch (IOException ioe) {
}
}
/*register an alarm*/
public void setAlarm() {
try {
Date d = new Date();
String classname = "Midlet"
long previousAlarmTime = PushRegistry.registerAlarm(
classname,d.getTime() + MILLISECONDS_TILL_ALARM);
} catch (Exception e) {
}
}
/*Connect to Url*/
public void connectUrl() {
try {
String[] connections = PushRegistry.listConnections(true);
if (connections != null && connections.length > 0) {
for (int i = 0; i < connections.length; i++ ) {
ServerSocketConnection serverConnection =
(ServerSocketConnection)Connector.open(connections[i]);
SocketConnection socketConnection =
(SocketConnection)serverConnection.acceptAndOpen();
socketConnection.close();
serverConnection.close();
}
}
} catch (Exception e) {
}
} |
| |||
| How to Play sound in Java ME The following code helps to play sound which is embedded in your jar file InputStream is = getClass().getResourceAsStream("sound.wav"); Player p = Manager.createPlayer(is, "audio/X-wav"); p.start(); The following code helps to play sound which is stored in a web server Player p = Manager.createPlayer("http://server/sound.wav"); p.start(); You may also try other sound formats by minor changing ie; by changing the mime type.
__________________ thanx n regards jeyaprakash.c |
| |||
| How to check whether the phone supports camera from Java ME This can be retrieved by String videoCapture = System.getProperty("supports.video.capture"); Gives whether camera is supported or not You can also check if the Manager.createPlayer() method call returns MediaException. This means that the specific locator is not supported. (Note: You should have the createPlayer() call inside a try-clause anyway)
__________________ thanx n regards jeyaprakash.c |
|
#19 |