package org.syzygy.gps.midp; import org.syzygy.gps.*; import org.syzygy.util.PropertySource; import org.syzygy.util.midp.FileUtil; import javax.microedition.io.Connector; import javax.microedition.io.file.FileConnection; import javax.microedition.lcdui.*; import java.io.IOException; import java.util.Enumeration; /** * Replays a previously-saved trace over a map retrieved from the Internet. * <p/> * This class was written by Stephen Crane (jscrane@gmail.com) * and is released under the terms of the GNU GPL * (http://www.gnu.org/licenses/gpl.html). */ public abstract class ReplayMIDlet extends LocationAwareMIDlet { protected ReplayMIDlet(String name) throws Exception { String mapperName = props.getProperty("gps.coordinate.mapper"); String cacheName = props.getProperty("gps.midlet.maps"); CoordinateMapper cm = (CoordinateMapper) Class.forName(mapperName).newInstance(); this.location = new LocationCanvas(cm, new EventListener() { public void pan(final int x, final int y) { new Thread(new ExceptionHandler("pan") { public void doRun() throws Exception { location.setTile(x == 0 && y == 0 ? map.panOff() : map.pan(x, y)); } }).start(); } public void zoomIn() { new Thread(new ExceptionHandler("zoomIn") { public void doRun() throws Exception { location.setTile(map.zoomIn()); } }).start(); } public void zoomOut() { new Thread(new ExceptionHandler("zoomOut") { public void doRun() throws Exception { location.setTile(map.zoomOut()); } }).start(); } public void speedUp() { new Thread(new ExceptionHandler("speedUp") { public void doRun() throws Exception { ((ReplaySource) reader).speedUp(); } }).start(); } public void slowDown() { new Thread(new ExceptionHandler("slowDown") { public void doRun() throws Exception { ((ReplaySource) reader).slowDown(); } }).start(); } public void exit() { quit(false); } }); this.map = new PanningZoomingMapper(cm, 12); cm.setMapCache(new FileMapCache(cacheName, cm)); this.name = name; } protected abstract String getLocations(); protected LocationSource createSource(PropertySource props) { return new ReplaySource(); } protected void startApp() { location.setFullScreenMode(true); reader.addListener(new ErrorListenerAdapter() { protected void onLocation(Location l) { if (!l.getIsError()) try { location.setTile(map.fromLocation(l)); } catch (Exception e) { error(e, "onLocation"); } location.setLocation(l); } }); final Command ok = new Command("OK", Command.SCREEN, 1); final Command delete = new Command("Delete", Command.SCREEN, 1); final List choices = new List(name, ChoiceGroup.IMPLICIT); FileConnection traceDir = null; try { traceDir = (FileConnection) Connector.open(getLocations(), Connector.READ); for (Enumeration files = traceDir.list(); files.hasMoreElements();) choices.append((String) files.nextElement(), null); } catch (IOException e) { FileUtil.safeClose(traceDir); error(e, "Loading"); } choices.addCommand(ok); choices.addCommand(delete); choices.setSelectCommand(ok); choices.setCommandListener(new CommandListener() { public void commandAction(Command c, Displayable d) { final int sel = choices.getSelectedIndex(); if (sel == -1) quit(true); else { final String choice = getLocations() + "/" + choices.getString(sel); if (c == ok) { ((ReplaySource) reader).setPath(choice); display.setCurrent(location); new Thread(reader).start(); } else if (c == delete) { new Thread(new ExceptionHandler("delete") { public void doRun() throws Exception { FileConnection file = (FileConnection) Connector.open(choice); try { file.delete(); choices.delete(sel); } finally { file.close(); } } }).start(); } } } }); display.setCurrent(choices); } private final LocationCanvas location; private final String name; private PanningZoomingMapper map; }