001: /*
002: *
003: * Copyright (c) 2007, Sun Microsystems, Inc.
004: *
005: * All rights reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * * Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * * Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: * * Neither the name of Sun Microsystems nor the names of its contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032: package example.bluetooth.demo;
033:
034: // midp/cldc classes
035: import java.io.IOException;
036:
037: import java.util.Enumeration;
038: import java.util.Hashtable;
039:
040: // midp GUI classes
041: import javax.microedition.lcdui.Alert;
042: import javax.microedition.lcdui.AlertType;
043: import javax.microedition.lcdui.Command;
044: import javax.microedition.lcdui.CommandListener;
045: import javax.microedition.lcdui.Display;
046: import javax.microedition.lcdui.Displayable;
047: import javax.microedition.lcdui.Form;
048: import javax.microedition.lcdui.Gauge;
049: import javax.microedition.lcdui.Image;
050: import javax.microedition.lcdui.ImageItem;
051: import javax.microedition.lcdui.List;
052: import javax.microedition.lcdui.StringItem;
053:
054: /**
055: * Provides a GUI to present the download options
056: * to used, gives a chance to make a choice,
057: * finally shows the downloaded image.
058: *
059: * @version ,
060: */
061: final class GUIImageClient implements CommandListener {
062: /** This command goes to demo main screen. */
063: private final Command SCR_MAIN_BACK_CMD = new Command("Back",
064: Command.BACK, 2);
065:
066: /** Starts the proper services search. */
067: private final Command SCR_MAIN_SEARCH_CMD = new Command("Find",
068: Command.OK, 1);
069:
070: /** Cancels the device/services discovering. */
071: private final Command SCR_SEARCH_CANCEL_CMD = new Command("Cancel",
072: Command.BACK, 2);
073:
074: /** This command goes to client main screen. */
075: private final Command SCR_IMAGES_BACK_CMD = new Command("Back",
076: Command.BACK, 2);
077:
078: /** Start the chosen image download. */
079: private final Command SCR_IMAGES_LOAD_CMD = new Command("Load",
080: Command.OK, 1);
081:
082: /** Cancels the image download. */
083: private final Command SCR_LOAD_CANCEL_CMD = new Command("Cancel",
084: Command.BACK, 2);
085:
086: /** This command goes from image screen to images list one. */
087: private final Command SCR_SHOW_BACK_CMD = new Command("Back",
088: Command.BACK, 2);
089:
090: /** The main screen of the client part. */
091: private final Form mainScreen = new Form("Image Viewer");
092:
093: /** The screen with found images names. */
094: private final List listScreen = new List("Image Viewer",
095: List.IMPLICIT);
096:
097: /** The screen with download image. */
098: private final Form imageScreen = new Form("Image Viewer");
099:
100: /** Keeps the parent MIDlet reference to process specific actions. */
101: private DemoMIDlet parent;
102:
103: /** This object handles the real transmission. */
104: private BTImageClient bt_client;
105:
106: /** Constructs client GUI. */
107: GUIImageClient(DemoMIDlet parent) {
108: this .parent = parent;
109: bt_client = new BTImageClient(this );
110: mainScreen.addCommand(SCR_MAIN_BACK_CMD);
111: mainScreen.addCommand(SCR_MAIN_SEARCH_CMD);
112: mainScreen.setCommandListener(this );
113: listScreen.addCommand(SCR_IMAGES_BACK_CMD);
114: listScreen.addCommand(SCR_IMAGES_LOAD_CMD);
115: listScreen.setCommandListener(this );
116: imageScreen.addCommand(SCR_SHOW_BACK_CMD);
117: imageScreen.setCommandListener(this );
118: }
119:
120: /**
121: * Process the command events.
122: *
123: * @param c - the issued command.
124: * @param d - the screen object the command was issued for.
125: */
126: public void commandAction(Command c, Displayable d) {
127: // back to demo main screen
128: if (c == SCR_MAIN_BACK_CMD) {
129: destroy();
130: parent.show();
131:
132: return;
133: }
134:
135: // starts images (device/services) search
136: if (c == SCR_MAIN_SEARCH_CMD) {
137: Form f = new Form("Searching...");
138: f.addCommand(SCR_SEARCH_CANCEL_CMD);
139: f.setCommandListener(this );
140: f.append(new Gauge("Searching images...", false,
141: Gauge.INDEFINITE, Gauge.CONTINUOUS_RUNNING));
142: Display.getDisplay(parent).setCurrent(f);
143: bt_client.requestSearch();
144:
145: return;
146: }
147:
148: // cancels device/services search
149: if (c == SCR_SEARCH_CANCEL_CMD) {
150: bt_client.cancelSearch();
151: Display.getDisplay(parent).setCurrent(mainScreen);
152:
153: return;
154: }
155:
156: // back to client main screen
157: if (c == SCR_IMAGES_BACK_CMD) {
158: bt_client.requestLoad(null);
159: Display.getDisplay(parent).setCurrent(mainScreen);
160:
161: return;
162: }
163:
164: // starts image download
165: if (c == SCR_IMAGES_LOAD_CMD) {
166: Form f = new Form("Loading...");
167: f.addCommand(SCR_LOAD_CANCEL_CMD);
168: f.setCommandListener(this );
169: f.append(new Gauge("Loading image...", false,
170: Gauge.INDEFINITE, Gauge.CONTINUOUS_RUNNING));
171: Display.getDisplay(parent).setCurrent(f);
172:
173: List l = (List) d;
174: bt_client.requestLoad(l.getString(l.getSelectedIndex()));
175:
176: return;
177: }
178:
179: // cancels image load
180: if (c == SCR_LOAD_CANCEL_CMD) {
181: bt_client.cancelLoad();
182: Display.getDisplay(parent).setCurrent(listScreen);
183:
184: return;
185: }
186:
187: // back to client main screen
188: if (c == SCR_SHOW_BACK_CMD) {
189: Display.getDisplay(parent).setCurrent(listScreen);
190:
191: return;
192: }
193: }
194:
195: /**
196: * We have to provide this method due to "do not do network
197: * operation in command listener method" restriction, which
198: * is caused by crooked midp design.
199: *
200: * This method is called by BTImageClient after it is done
201: * with bluetooth initialization and next screen is ready
202: * to appear.
203: */
204: void completeInitialization(boolean isBTReady) {
205: // bluetooth was initialized successfully.
206: if (isBTReady) {
207: StringItem si = new StringItem("Ready for images search!",
208: null);
209: si.setLayout(StringItem.LAYOUT_CENTER
210: | StringItem.LAYOUT_VCENTER);
211: mainScreen.append(si);
212: Display.getDisplay(parent).setCurrent(mainScreen);
213:
214: return;
215: }
216:
217: // something wrong
218: Alert al = new Alert("Error", "Can't initialize bluetooth",
219: null, AlertType.ERROR);
220: al.setTimeout(DemoMIDlet.ALERT_TIMEOUT);
221: Display.getDisplay(parent).setCurrent(al,
222: parent.getDisplayable());
223: }
224:
225: /** Destroys this component. */
226: void destroy() {
227: // finalize the image client work
228: bt_client.destroy();
229: }
230:
231: /**
232: * Informs the error during the images search.
233: */
234: void informSearchError(String resMsg) {
235: Alert al = new Alert("Error", resMsg, null, AlertType.ERROR);
236: al.setTimeout(DemoMIDlet.ALERT_TIMEOUT);
237: Display.getDisplay(parent).setCurrent(al, mainScreen);
238: }
239:
240: /**
241: * Informs the error during the selected image load.
242: */
243: void informLoadError(String resMsg) {
244: Alert al = new Alert("Error", resMsg, null, AlertType.ERROR);
245: al.setTimeout(DemoMIDlet.ALERT_TIMEOUT);
246: Display.getDisplay(parent).setCurrent(al, listScreen);
247: }
248:
249: /**
250: * Shows the downloaded image.
251: */
252: void showImage(Image img, String imgName) {
253: imageScreen.deleteAll();
254: imageScreen.append(new ImageItem(imgName, img,
255: ImageItem.LAYOUT_CENTER | ImageItem.LAYOUT_VCENTER,
256: "Downloaded image: " + imgName));
257: Display.getDisplay(parent).setCurrent(imageScreen);
258: }
259:
260: /**
261: * Shows the available images names.
262: *
263: * @returns false if no images names were found actually
264: */
265: boolean showImagesNames(Hashtable base) {
266: Enumeration keys = base.keys();
267:
268: // no images actually
269: if (!keys.hasMoreElements()) {
270: informSearchError("No images names in found services");
271:
272: return false;
273: }
274:
275: // prepare the list to be shown
276: while (listScreen.size() != 0) {
277: listScreen.delete(0);
278: }
279:
280: while (keys.hasMoreElements()) {
281: listScreen.append((String) keys.nextElement(), null);
282: }
283:
284: Display.getDisplay(parent).setCurrent(listScreen);
285:
286: return true;
287: }
288: } // end of class 'GUIImageClient' definition
|