001: /* Browser.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Mon Nov 27 17:22:06 2006, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2006 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: }}IS_RIGHT
016: */
017: package org.zkoss.zkmob;
018:
019: import javax.microedition.midlet.MIDlet;
020: import javax.microedition.midlet.MIDletStateChangeException;
021: import javax.microedition.lcdui.Alert;
022: import javax.microedition.lcdui.AlertType;
023: import javax.microedition.lcdui.Command;
024: import javax.microedition.lcdui.CommandListener;
025: import javax.microedition.lcdui.Display;
026: import javax.microedition.lcdui.Displayable;
027: import javax.microedition.lcdui.Form;
028: import javax.microedition.lcdui.Item;
029: import javax.microedition.lcdui.ItemCommandListener;
030: import javax.microedition.lcdui.List;
031: import javax.microedition.lcdui.TextField;
032:
033: import org.zkoss.zkmob.ui.ZkDesktop;
034: import org.zkoss.zkmob.ui.ZkList;
035: import org.zkoss.zkmob.ui.ZkListItem;
036:
037: import org.xml.sax.SAXException;
038: import java.io.IOException;
039: import java.io.InputStream;
040:
041: /**
042: * The ZK Mobile Browser for Raw Mobile Interactive Language(RMIL).
043: *
044: * @author tomyeh
045: */
046: public class Browser extends MIDlet {
047: private static final int HISTORY_MAX = 10; //miximum history record
048:
049: private Display _display; //display of this MIDlet
050:
051: private Displayable _prev; //previous Displayable before pause
052: private Displayable _curr; //current Displayble before go Home
053:
054: private ZkDesktop _zkMobile; //zkMobile desktop
055: private Form _home; //zkMobile home page
056: private Command _backCommand; //home page back command
057: private Alert _exitAlert; //zkMobile exit alert
058: private List _history; //zkMobile history list (most ten most recent record)
059: private CommandListener _commandListener;
060: private ItemCommandListener _itemCommandListener;
061:
062: private ZkDesktop _desktop; //current browsed desktop
063:
064: //super//
065: protected void startApp() throws MIDletStateChangeException {
066: init();
067: }
068:
069: protected void pauseApp() {
070: System.out.println("**pause");
071: if (_display != null) {
072: _prev = _display.getCurrent();
073: }
074: }
075:
076: protected void destroyApp(boolean unconditional)
077: throws MIDletStateChangeException {
078: exit();
079: }
080:
081: public Display getDisplay() {
082: return _display;
083: }
084:
085: public void setDesktop(ZkDesktop zk, String url) {
086: _desktop = zk;
087: zk.setBrowser(this );
088:
089: if (url != null) {
090: adjustHistory(url);
091: }
092: }
093:
094: //private//
095: /** Initializes this MIDlet. */
096: private void init() {
097: if (_prev != null) {
098: System.out.println("++ resume");
099: _display.setCurrent(_prev);
100: } else if (_display == null) {
101: //prepare the display
102: _display = Display.getDisplay(this );
103:
104: InputStream is = null;
105: try {
106: //prepare the CommandListener
107: _commandListener = new CommandListener() {
108: public void commandAction(Command c, Displayable d) {
109: final ZkComponent cmd = (ZkComponent) c;
110: final String cmdid = cmd.getId();
111: //home page
112: if ("back".equals(cmd.getId())) {
113: if (_curr != null) {
114: _display.setCurrent(_curr);
115: }
116: //exitalert
117: } else if ("yes".equals(cmdid)) {
118: exit();
119: } else if ("no".equals(cmdid)) {
120: _display.setCurrent(_home);
121: //hlist
122: } else if ("hhome".equals(cmd.getId())) {
123: _display.setCurrent(_home);
124: } else if ("hgo".equals(cmdid)) {
125: final int index = _history
126: .getSelectedIndex();
127: if (index >= 0) {
128: final String url = _history
129: .getString(index);
130: setHomeURL(url);
131: UiManager.loadPageOnThread(
132: Browser.this , url);
133: }
134: }
135:
136: }
137: };
138:
139: //prepare the ItemCommandListener
140: _itemCommandListener = new ItemCommandListener() {
141: public void commandAction(Command c, Item i) {
142: final ZkComponent cmd = (ZkComponent) c;
143: final String cmdid = cmd.getId();
144: if ("go".equals(cmdid)) {
145: final TextField tf = (TextField) i;
146: final String url = tf.getString();
147: UiManager.loadPageOnThread(Browser.this ,
148: url);
149: } else if ("hcmd".equals(cmdid)) {
150: _display.setCurrent(_history);
151: } else if ("ecmd".equals(cmdid)) {
152: _display.setCurrent(_exitAlert);
153: }
154: }
155: };
156:
157: //load the browser template
158: is = getClass().getResourceAsStream(
159: "/pages/browser.rmil");
160: _zkMobile = UiManager.loadPage(this , is, null, "~.",
161: "~.");
162:
163: //prepare browser home page
164: _home = (Form) _zkMobile.lookupUi("home");
165: _home.setItemStateListener(null);
166: _home.setCommandListener(_commandListener);
167:
168: //prepare browser home page back command
169: _backCommand = (Command) _zkMobile.lookupUi("back");
170: _home.removeCommand(_backCommand);
171:
172: //prepare exitAlert
173: _exitAlert = (Alert) _zkMobile.lookupUi("exitalert");
174: _exitAlert.setTimeout(Alert.FOREVER);
175: _exitAlert.setCommandListener(_commandListener);
176:
177: //prepare history list
178: _history = (List) _zkMobile.lookupUi("hlist");
179: _history.setCommandListener(_commandListener);
180: for (int j = 0; j < HISTORY_MAX; ++j) {
181: final String historyURL = getAppProperty("zkmob-history"
182: + j);
183: if (historyURL == null) {
184: break;
185: }
186: _history.append(historyURL, null);
187: }
188:
189: //prepare items in the home page
190: final Item url = (Item) _zkMobile.lookupUi("url");
191: url.setItemCommandListener(_itemCommandListener);
192: final Item history = (Item) _zkMobile.lookupUi("hist");
193: history.setItemCommandListener(_itemCommandListener);
194: final Item exit = (Item) _zkMobile.lookupUi("exit");
195: exit.setItemCommandListener(_itemCommandListener);
196:
197: //preapre the zkmob.targetURL
198: final String targetURL = getAppProperty("zkmob-defaultURL");
199: if (targetURL != null) {
200: ((TextField) url).setString(targetURL);
201:
202: final String autoRun = getAppProperty("zkmob-autoRun");
203: if ("true".equals(autoRun)) {
204: UiManager.loadPageOnThread(this , targetURL);
205: }
206: }
207: } catch (SAXException ex) {
208: alert(ex);
209: exit();
210: } catch (IOException ex) {
211: alert(ex);
212: exit();
213: } finally {
214: if (is != null) {
215: try {
216: is.close();
217: } catch (IOException ex) {
218: //ignore
219: }
220: }
221: }
222: }
223: }
224:
225: //trim away ;jssessionid
226: private String trimSessionid(String url) {
227: final int k = url.indexOf(";jsessionid=");
228: if (k >= 0) {
229: final int m = url.lastIndexOf('?', k);
230: if (m < 0) {
231: url = url.substring(0, k);
232: } else {
233: url = url.substring(0, k) + url.substring(m);
234: }
235: }
236: return url;
237: }
238:
239: //adjust history after successfully go to the specified URL
240: private void adjustHistory(String url) {
241: url = trimSessionid(url);
242: final int sz = _history.size();
243: int j = 0;
244: for (; j < sz; ++j) {
245: final String old = _history.getString(j);
246: if (old.equals(url)) {
247: ((ZkList) _history).super Delete(j);
248: break;
249: }
250: }
251: _history.insert(0, url, null);
252: if (_history.size() > HISTORY_MAX) { //most ten records
253: ((ZkList) _history).super Delete(HISTORY_MAX);
254: }
255: }
256:
257: public void setHomeURL(String url) {
258: if (url != null) {
259: final TextField urlText = (TextField) _zkMobile
260: .lookupUi("url");
261: urlText.setString(url);
262: }
263: }
264:
265: public void goHome(String url) {
266: setHomeURL(url);
267: Displayable curr = _display.getCurrent();
268: if (curr != null && curr != _home && !(curr instanceof Alert)) {
269: _curr = curr; //so home page's back command can back here
270: if (_curr != null) { //home page add "back" command
271: _home.addCommand(_backCommand);
272: }
273: }
274: _display.setCurrent(_home);
275: }
276:
277: //alert
278: private void alert(Throwable ex) {
279: final Alert al = new Alert("Exception:",
280: "Cannot start ZK Mobile: " + ex.toString(),
281: null /*image*/, AlertType.ERROR);
282: al.setTimeout(Alert.FOREVER);
283: _display.setCurrent(al);
284: }
285:
286: //exit the midlet
287: private void exit() {
288: //clean up
289: notifyDestroyed();
290: }
291: }
|