View Png Thread
/*-------------------------------------------------- * 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); } } }