📄 utils.java
字号:
/* * * Copyright (c) 2007, Sun Microsystems, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */package example.mmademo;import javax.microedition.midlet.*;import javax.microedition.lcdui.*;import javax.microedition.media.*;import javax.microedition.media.control.*;import java.util.*;import java.io.*;/** * Utility functions and listener interfaces * * @version 1.5 */public class Utils { public static boolean DEBUG = false; private Utils() { //prevent accidental instantiation } public static void debugOut(String s) { if (DEBUG) System.out.println(s); } public static void debugOut(Throwable t) { if (DEBUG) System.out.println(t.toString()); if (DEBUG) t.printStackTrace(); } public static void error(Throwable t, BreadCrumbTrail bct) { if (DEBUG) t.printStackTrace(); error(friendlyException(t), bct); } public static void error(String s, BreadCrumbTrail bct) { Alert alert = new Alert("Error", s, null, AlertType.ERROR); alert.setTimeout(Alert.FOREVER); bct.replaceCurrent(alert); } public static void FYI(String s, BreadCrumbTrail bct) { Alert alert = new Alert("FYI", s, null, AlertType.INFO); alert.setTimeout(Alert.FOREVER); bct.replaceCurrent(alert); } /** * "javax.microedition.rms.RecordStoreException: Bla" * -> * "RecordStoreException: Bla" */ public static String friendlyException(Throwable t) { if (t instanceof MediaException && t.getMessage().indexOf(" ")>5) { return t.getMessage(); } String s = t.toString(); while (true) { int dot = s.indexOf("."); int space = s.indexOf(" "); if (space<0) space = s.length(); int colon = s.indexOf(":"); if (colon<0) colon = s.length(); if (dot >= 0 && dot < space && dot < colon) { s = s.substring(dot+1); } else { break; } } return s; } /** * Prompts the user to enter a string.<p> * <b>Caution</b>: this must be called in * a different Thread than the lcdui event dispatcher. Unfortunately ! * * @param title - title of the query window * @param def - a default value that appears in the input field * @param maxSize - max number of characters * @return the entered text, or <code>null</code> if the user cancelled */ public static void query(String title, String def, int maxSize, QueryListener listener, BreadCrumbTrail bct) { query(title, def, maxSize, TextField.ANY, listener, bct); } /** * Prompts the user to enter a string. <p> * When the user finished entering the text, * the <code>listener</code>'s methods are called. * If the user pressed the OK button, the * <code>listener</code>'s <code>queryOK</code> method * is called with the entered text as parameter. * * The <code>listener</code> need not care about hiding the displayable. * * @param title - title of the query window * @param def - a default value that appears in the input field * @param maxSize - max number of characters * @param constraints - see javax.microedition.lcdui.TextBox * @param listener - the QueryListener which receives the events */ public static void query(String title, String def, int maxSize, int constraints, QueryListener listener, BreadCrumbTrail bct) { TextBox tb = new TextBox(title, def, maxSize, constraints); tb.addCommand(QueryTask.cancelCommand); tb.addCommand(QueryTask.OKCommand); QueryTask qt = new QueryTask(listener, bct); tb.setCommandListener(qt); bct.go(tb); } /** * splits the URL in the parts * E.g: http://www.12fb.com:80/Media/MIDI/fb.mid#1 * * 0: protocol (e.g. http) * 1: host (e.g. www.12fb.com) * 2: port (e.g. 80) * 3: path (e.g. /Media/MIDI) * 4: file (e.g. fb.mid) * 5: anchor (e.g. 1) * * LIMITATION: URL must end with a slash if it is a directory */ public static String[] splitURL(String url) throws Exception { StringBuffer u=new StringBuffer(url); String[] result=new String[6]; for (int i=0; i<=5; i++) { result[i]=""; } // get protocol boolean protFound=false; int index=url.indexOf(":"); if (index>0) { result[0]=url.substring(0, index); u.delete(0, index+1); protFound=true; } else if (index==0) { throw new Exception("url format error - protocol"); } // check for host/port if (u.length()>2 && u.charAt(0)=='/' && u.charAt(1)=='/') { // found domain part u.delete(0, 2); int slash=u.toString().indexOf('/'); if (slash<0) { slash=u.length(); } int colon=u.toString().indexOf(':'); int endIndex=slash; if (colon>=0) { if (colon>slash) { throw new Exception("url format error - port"); } endIndex=colon; result[2]=u.toString().substring(colon+1, slash); } result[1]=u.toString().substring(0, endIndex); u.delete(0, slash); } // get filename if (u.length()>0) { url=u.toString(); int slash=url.lastIndexOf('/'); if (slash>0) { result[3]=url.substring(0, slash); } if (slash<url.length()-1) { String fn = url.substring(slash+1, url.length()); int anchorIndex = fn.indexOf("#"); if (anchorIndex>=0) { result[4] = fn.substring(0, anchorIndex); result[5] = fn.substring(anchorIndex+1); } else { result[4] = fn; } } } return result; } public static String mergeURL(String[] url) { return ((url[0]=="")?"":url[0]+":/") +((url[1]=="")?"":"/"+url[1]) +((url[2]=="")?"":":"+url[2]) +url[3]+"/"+url[4] +((url[5]=="")?"":"#"+url[5]); } public static String guessContentType(String url) throws Exception { // guess content type String[] sURL = splitURL(url); String ext = ""; String ct = ""; int lastDot = sURL[4].lastIndexOf('.'); if (lastDot>=0) { ext = sURL[4].substring(lastDot+1).toLowerCase(); } if (ext.equals("mpg") || url.equals("avi")) { ct = "video/mpeg"; } else if (ext.equals("mid") || ext.equals("kar")) { ct = "audio/midi"; } else if (ext.equals("wav")) { ct = "audio/x-wav"; } else if (ext.equals("jts")) { ct = "audio/x-tone-seq"; } else if (ext.equals("txt")) { ct = "audio/x-txt"; } else if (ext.equals("amr")) { ct = "audio/amr"; } else if (ext.equals("awb")) { ct = "audio/amr-wb"; } else if (ext.equals("gif")) { ct = "image/gif"; } return ct; } /** * From SortDemo - modified to take Strings * * This is a generic version of C.A.R Hoare's Quick Sort * algorithm. This will handle arrays that are already * sorted, and arrays with duplicate keys.<BR> * * If you think of a one dimensional array as going from * the lowest index on the left to the highest index on the right * then the parameters to this function are lowest index or * left and highest index or right. The first time you call * this function it will be with the parameters 0, a.length - 1. * * @param s a String array * @param lo0 left boundary of array partition * @param hi0 right boundary of array partition */ private static void quickSort(String[] s, int lo0, int hi0) { int lo = lo0; int hi = hi0; String mid; if (hi0 > lo0) { /* Arbitrarily establishing partition element as the midpoint of * the array. */ mid = s[(lo0 + hi0) / 2 ].toUpperCase(); // loop through the array until indices cross while(lo <= hi) { /* find the first element that is greater than or equal to * the partition element starting from the left Index. */ while((lo < hi0) && (s[lo].toUpperCase().compareTo(mid) < 0)) { ++lo; } /* find an element that is smaller than or equal to * the partition element starting from the right Index. */ while((hi > lo0) && (s[hi].toUpperCase().compareTo(mid) > 0)) { --hi; } // if the indexes have not crossed, swap if(lo <= hi) { String temp; temp = s[lo]; s[lo] = s[hi]; s[hi] = temp; ++lo; --hi; } } /* If the right index has not reached the left side of array * must now sort the left partition. */ if (lo0 < hi) { quickSort(s, lo0, hi); } /* If the left index has not reached the right side of array * must now sort the right partition. */ if (lo < hi0) { quickSort(s, lo, hi0); } } } public static void sort(String[] elements) { quickSort(elements, 0, elements.length - 1); } /** * A class to handle the query */ private static class QueryTask implements CommandListener, Runnable { private static Command cancelCommand = new Command("Cancel", Command.CANCEL, 1); private static Command OKCommand = new Command("OK", Command.OK, 1); // "parameters" passed to commandAction method private QueryListener queryListener; private BreadCrumbTrail queryBCT; private static String queryText = ""; private QueryTask(QueryListener listener, BreadCrumbTrail bct) { this.queryListener = listener; this.queryBCT = bct; } /** * Respond to commands */ public void commandAction(Command c, Displayable s) { if (queryBCT != null) { Utils.debugOut("Utils.commandAction: goBack()"); queryBCT.goBack(); } if (c == cancelCommand) { Utils.debugOut("Command: cancel"); if (queryListener!=null) { queryListener.queryCancelled(); } } else if (c == OKCommand) { Utils.debugOut("Command: OK"); if (queryListener!=null) { queryText = ""; if (s instanceof TextBox) { queryText = ((TextBox) s).getString(); } // for some reasons, MIDP may have a deadlock // if some lengthy operation (i.e. http i/o) // is initiated from the command listener // thread. Therefore, issue the event // from another thread... (new Thread(this)).start(); } } } /** * Runnable implementation -- sends * the event to the listener. * It is executed in a separate thread * to not block the VM's command dispatch * thread. */ public void run() { sendListenerEvent(); } /** * Send the text to the query listener */ private void sendListenerEvent() { if (queryListener != null) { queryListener.queryOK(queryText); } }} /** * Interface to be implemented by classes * that provide <i>Back</i> functionality. */ interface BreadCrumbTrail { public Displayable go(Displayable d); public Displayable goBack(); public void handle(String name, String url); public Displayable replaceCurrent(Displayable d); public Displayable getCurrentDisplayable(); } /** * Interface implemented by classes that * can handle (playback, display, etc.) url's. */ interface ContentHandler { public void close(); public boolean canHandle(String url); public void handle(String name, String url); } /** * Interface that is implemented by classes * that use the query() functions. */ interface QueryListener { public void queryOK(String text); public void queryCancelled(); } /** * Interface implemented by Displayable's that * want to respond to the MIDlet's startApp() * and pauseApp() calls. */ interface Interruptable { /** * Called in response to a request to pause the MIDlet. */ public void pauseApp(); /** * Called when a MIDlet is asked to resume operations * after a call to pauseApp(). This method is only * called after pauseApp(), so it is different from * MIDlet's startApp(). */ public void resumeApp(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -