www.pudn.com > GMapViewer-src.zip > SearchMenu.java



package org.sreid.j2me.gmapviewer;

import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import org.sreid.j2me.util.*;

// Handles search (non-permanent) map pins.
public class SearchMenu extends List implements CommandListener {

	private final GMapViewer app;

	private static final String BACK = "Back";

	private static final String GO_TO_PIN = "Go to location";
	private static final String KEEP_PIN = "Save as map pin";
	private static final String NEW_SEARCH = "New search";
	private static final String CLEAR_ALL = "Clear all";

	private final Vector mapPins = new Vector();

	Displayable cameFrom;

	SearchMenu(GMapViewer app) {
		super("Search results", List.IMPLICIT);
		this.app = app;
		setCommandListener(this);
		addCommand(new Command(BACK, Command.BACK, 1));
		addCommand(new Command(GO_TO_PIN, Command.ITEM, 1));
		addCommand(new Command(KEEP_PIN, Command.ITEM, 1));
		addCommand(new Command(NEW_SEARCH, Command.SCREEN, 2));
		addCommand(new Command(CLEAR_ALL, Command.SCREEN, 3));
		loadList();
	}

	public void commandAction(Command c, Displayable d) {
		final MapPin pin = (getSelectedIndex() < 0 || mapPins.size() == 0 ? null : (MapPin)mapPins.elementAt(getSelectedIndex()));
		String cmd = c.getLabel();
		if (cmd.equals(BACK)) {
			app.display.setCurrent(cameFrom);
		}
		else if (cmd.equals(NEW_SEARCH) || (pin == null && c == List.SELECT_COMMAND)) {
			final Dialog dlg = Dialog.createTextDialog("Search", "Enter search query", "", 200, TextField.ANY);
			dlg.setCallback(new Runnable() { public void run() {
				String search = (String)dlg.getUserResponse();
				if (search != null && search.length() > 0) {
					submitSearch(search);
				}
			}});
			dlg.showOn(app);
		}
		else if (pin == null) {
			// all of the commands below require a map pin
		}
		else if (cmd.equals(GO_TO_PIN) || c == List.SELECT_COMMAND) {
			app.canvas.setXY(pin.x, pin.y);
			app.display.setCurrent(app.canvas);
		}
		else if (cmd.equals(KEEP_PIN)) {
			pin.isPermanent = true;
			app.mpm.keepPin(pin);
			loadList();
		}
		else if (cmd.equals(CLEAR_ALL)) {
			final Dialog dlg = Dialog.createConfirmationDialog("Clear search results", "This will clear all of your search results (blue map pins). Proceed?", "OK", "Cancel");
			dlg.setCallback(new Runnable() { public void run() {
				if (dlg.getUserResponse() == Dialog.USER_CONFIRMED) {
					app.mpm.deleteNonPermanentPins();
					loadList();
				}
			}});
			dlg.showOn(app);
		}
		else {
			throw new IllegalArgumentException("Unrecognized command: " + cmd);
		}
	}

	void loadList() {
		mapPins.removeAllElements();
		while (size() > 0) {
			delete(0);
		}
		for (Enumeration enum = app.mpm.enumeration() ; enum.hasMoreElements() ; ) {
			MapPin mp = (MapPin)enum.nextElement();
			if (!mp.isPermanent) {
				append(mp.text, null);
				mapPins.addElement(mp);
			}
		}
		if (mapPins.size() == 0) {
			append("No search results. Click to enter a new search.", null);
		}
	}

	private void submitSearch(final String search) {
		app.async2.enqueueJob(new Runnable() { public void run() {
			// clear existing results
			app.mpm.deleteNonPermanentPins();
			// show "searching" message
			final Dialog dlg = Dialog.createConfirmationDialog("Searching", "Searching. Please wait.", "", "");
			dlg.showSerially(app, dlg); // cannot be dismissed. Done via showSerially as the search screen may or may not be about to call setDisplay

			byte[] buffer = (byte[])app.sharedBuffers.claimResourceIgnoreInterrupt();
			try {
				// Query server
				GMapCanvas c = app.canvas;
				String params =
				 "&x=" + c.getX() +
				 "&y=" + c.getY() +
				 "&z=" + c.getZ() +
				 "&sw=" + c.getWidth() +
				 "&sh=" + c.getHeight() +
				 "&q=" + Util.urlEncode(search + ' ' + app.prefs.getString("searchTerms", "")) ;
				int len = app.getDataFromServer("search", params, buffer, "SEARCHRESULTS");
				// Parse results
				for (int idx = 0; idx < len; ) {
					int p1 = idx;
					while (buffer[idx++] != 0x20) { } // space
					int p2 = idx;
					while (buffer[idx++] != 0x20) { } // space
					int p3 = idx;
					while (buffer[idx++] != 0x0a) { } // newline
					int p4 = idx;
					String strX = new String(buffer, p1, (p2-1) - p1);
					String strY = new String(buffer, p2, (p3-1) - p2);
					String text = new String(buffer, p3, (p4-1) - p3);
					MapPin mp = new MapPin(Integer.parseInt(strX), Integer.parseInt(strY));
					mp.text = text;
					mp.isPermanent = false; // temporary map pin for showing search results
					app.mpm.keepPin(mp);
				}
				app.online = true;
			}
			catch (Exception e) {
				app.exception("An error occured while processing the search.", e);
			}
			finally {
				app.sharedBuffers.releaseResource(buffer);
			}
			loadList();
			app.display.callSerially(new Runnable() { public void run() {
				// using callSerially to be certain that this doesn't happen before the "searching" dialog gets displayed.
				// That is unlikely (the search would have to be super fast) but may as well account for it.
				app.display.setCurrent(SearchMenu.this);
			}});
		}});
	}
}