/*--------------------------------------------------
* ViewPngThread.java
*
* Download and view a png file. The download is
* done in the background with a separate thread
*
* Example from the book: Core J2ME Technology
* Copyright John W. Muchow http://www.CoreJ2ME.com
* You may use/modify for any non-commercial purpose
*-------------------------------------------------*/
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import java.io.*;
public class ViewPngThread extends MIDlet implements CommandListener
{
private Display display;
private TextBox tbMain;
private Alert alStatus;
private Form fmViewPng;
private Command cmExit;
private Command cmView;
private Command cmBack;
private static final int ALERT_DISPLAY_TIME = 3000;
Image im = null;
public ViewPngThread()
{
display = Display.getDisplay(this);
// Create the Main textbox with a maximum of 75 characters
tbMain = new TextBox("Enter url", "http://www.corej2me.com/midpbook_v1e1/ch14/bird.png", 75, 0);
// Create commands and add to textbox
cmExit = new Command("Exit", Command.EXIT, 1);
cmView = new Command("View", Command.SCREEN, 2);
tbMain.addCommand(cmExit);
tbMain.addCommand(cmView );
// Set up a listener for textbox
tbMain.setCommandListener(this);
// Create the form that will hold the png image
fmViewPng = new Form("");
// Create commands and add to form
cmBack = new Command("Back", Command.BACK, 1);
fmViewPng.addCommand(cmBack);
// Set up a listener for form
fmViewPng.setCommandListener(this);
}
public void startApp()
{
display.setCurrent(tbMain);
}
public void pauseApp()
{ }
public void destroyApp(boolean unconditional)
{ }
/*--------------------------------------------------
* Process events
*-------------------------------------------------*/
public void commandAction(Command c, Displayable s)
{
// If the Command button pressed was "Exit"
if (c == cmExit)
{
destroyApp(false);
notifyDestroyed();
}
else if (c == cmView)
{
// Show alert indicating we are starting a download.
// This alert is NOT modal, it appears for
// approximately 3 seconds (see ALERT_DISPLAY_TIME)
showAlert("Downloading", false, tbMain);
// Create an instance of the class that will
// download the file in a separate thread
Download dl = new Download(tbMain.getString(), this);
// Start the thread/download
dl.start();
}
else if (c == cmBack)
{
display.setCurrent(tbMain);
}
}
/*--------------------------------------------------
* Called by the thread after attempting to download
* an image. If the parameter is 'true' the download
* was successful, and the image is shown on a form.
* If parameter is 'false' the download failed, and
* the user is returned to the textbox.
*
* In either case, show an alert indicating the
* the result of the download.
*-------------------------------------------------*/
public void showImage(boolean flag)
{
// Download failed...
if (flag == false)
{
// Alert followed by the main textbox
showAlert("Download Failure", true, tbMain);
}
else // Successful download...
{
ImageItem ii = new ImageItem(null, im, ImageItem.LAYOUT_DEFAULT, null);
// If there is already an image, set (replace) it
if (fmViewPng.size() != 0)
fmViewPng.set(0, ii);
else // Append the image to the empty form
fmViewPng.append(ii);
// Alert followed by the form holding the image
showAlert("Download Successful", true, fmViewPng);
}
}
/*--------------------------------------------------
* Show an alert with the parameters determining
* the type (modal or not) and the displayable to
* show after the alert is dismissed
*-------------------------------------------------*/
public void showAlert(String msg, boolean modal, Displayable displayable)
{
// Create alert, add text, associate a sound
alStatus = new Alert("Status", msg, null, AlertType.INFO);
// Set the alert type
if (modal)
alStatus.setTimeout(Alert.FOREVER);
else
alStatus.setTimeout(ALERT_DISPLAY_TIME);
// Show the alert, followed by the displayable
display.setCurrent(alStatus, displayable);
}
}
/*--------------------------------------------------
* Class - Download
*
* Download an image file in a separate thread
*-------------------------------------------------*/
class Download implements Runnable
{
private String url;
private ViewPngThread MIDlet;
private boolean downloadSuccess = false;
public Download(String url, ViewPngThread MIDlet)
{
this.url = url;
this.MIDlet = MIDlet;
}
/*--------------------------------------------------
* Download the image
*-------------------------------------------------*/
public void run()
{
try
{
getImage(url);
}
catch (Exception e)
{
System.err.println("Msg: " + e.toString());
}
}
/*--------------------------------------------------
* Create and start the new thread
*-------------------------------------------------*/
public void start()
{
Thread thread = new Thread(this);
try
{
thread.start();
}
catch (Exception e)
{
}
}
/*--------------------------------------------------
* Open connection and download png into a byte array.
*-------------------------------------------------*/
private void getImage(String url) throws IOException
{
ContentConnection connection = (ContentConnection) Connector.open(url);
// * There is a bug in MIDP 1.0.3 in which read() sometimes returns
// an invalid length. To work around this, I have changed the
// stream to DataInputStream and called readFully() instead of read()
// InputStream iStrm = connection.openInputStream();
DataInputStream iStrm = connection.openDataInputStream();
ByteArrayOutputStream bStrm = null;
Image im = null;
try
{
// ContentConnection includes a length method
byte imageData[];
int length = (int) connection.getLength();
if (length != -1)
{
imageData = new byte[length];
// Read the png into an array
// iStrm.read(imageData);
iStrm.readFully(imageData);
}
else // Length not available...
{
bStrm = new ByteArrayOutputStream();
int ch;
while ((ch = iStrm.read()) != -1)
bStrm.write(ch);
imageData = bStrm.toByteArray();
}
// Create the image from the byte array
im = Image.createImage(imageData, 0, imageData.length);
}
finally
{
// Clean up
if (connection != null)
connection.close();
if (iStrm != null)
iStrm.close();
if (bStrm != null)
bStrm.close();
}
// Return to the caller the status of the download
if (im == null)
MIDlet.showImage(false);
else
{
MIDlet.im = im;
MIDlet.showImage(true);
}
}
}
|