⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 browser.java

📁 FIRE (Flexible Interface Rendering Engine)是一个J2ME上的灵活的图形界面引擎
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * Fire (Flexible Interface Rendering Engine) is a set of graphics widgets for creating GUIs for j2me applications.  * Copyright (C) 2006-2008 Bluevibe (www.bluevibe.net) * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA *  *//** *  */package gr.fire.browser;import gr.fire.browser.util.HttpClient;import gr.fire.browser.util.Page;import gr.fire.browser.util.PageListener;import gr.fire.browser.util.Request;import gr.fire.core.CommandListener;import gr.fire.core.Component;import gr.fire.core.Container;import gr.fire.core.FireScreen;import gr.fire.core.Panel;import gr.fire.core.Theme;import gr.fire.ui.Alert;import gr.fire.ui.ProgressbarAnimation;import gr.fire.ui.TransitionAnimation;import gr.fire.util.FireConnector;import gr.fire.util.Lang;import gr.fire.util.Log;import gr.fire.util.StringUtil;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.UnsupportedEncodingException;import java.util.Hashtable;import java.util.Vector;import javax.microedition.io.HttpConnection;import javax.microedition.lcdui.Command;import javax.microedition.lcdui.Displayable;import javax.microedition.lcdui.Font;import org.kxml2.io.KXmlParser;/** * The Browser parses XHTML from a given stream and renders it. * It has some basic rendering rules that are choosen to improve the  * readability and usability of a page when rendered for a small screen. <br/> *  * * The default width of the browser is the width of the screen.<br/> *     * * TextPrimitive width is set as the width of the Browser unless noted otherwise  *   by the style of the tag.<br/> *    * * TextPrimitive height is the height of the text calculated using the width  *   (according to the rules above) and the font of the text.  <br/> *    * * ImagePrimitive width is the width of the image unless noted otherwise by the style of the tag. <br/> *  * @author padeler */public class Browser implements CommandListener, PageListener{		/**	 * Flag for the imageLoadingPolicy field. 	 * No images are loaded.	 */	public static final byte NO_IMAGES=0x00; 	/**	 * Flag for the imageLoadingPolicy field. 	 * Load images imediatelly	 */	public static final byte LOAD_IMAGES=0x01; 		/**	 * Flag for the imageLoadingPolicy field. This is the default browser behaivior.	 * Load images in a seperate thread after the full parsing of the page. 	 * The browser will return the Page object and start a thread to load the rest of the images.	 * This will apply only for images that the width and height attributes are set.	 * Images that do not have their width and height attributes set, will be loaded imediatelly.	 */	public static final byte LOAD_IMAGES_ASYNC=0x02;	/**	 * The listener that will receive the events generated by the page rendered by this browser (i.e. link clicks etc) 	 * The listener will also receive the submit events generated by forms in the rendered pages. 	 * If null, then the form handles the submit, with the default way (calls browser.displayPage()) 	 */	CommandListener listener = this; 	PageListener pageListener = this;		/**	 * If this field is set to false, then the browser will not request the images inside each page	 */	byte imageLoadingPolicy = LOAD_IMAGES_ASYNC;  		/**	 * The HttpClient used to request resources.	 */	HttpClient httpClient;		private Hashtable knownTags = new Hashtable();		private int viewportWidth=-1; 		private boolean showLoadingGauge=true;		/* ****** HTML Parsing support variables ******* */  	private Vector tagStack = new Vector();	private ProgressbarAnimation gauge=null;			/**	 * Constructor of a Browser instance with the default HttpClient.	 * The CommandListener and PageListener are set to this new Browser instance.	 * @see HttpClient	 * @see PageListener	 * @see CommandListener	 */	public Browser()	{		this(new HttpClient(new FireConnector()));	}		/**	 * Constructor of a Browser instance with the supplied httpclient. All other parameters are set to the default	 * @see #Browser()	 * @param httpClient	 */	public Browser(HttpClient httpClient)	{		this.httpClient = httpClient; 				{			Class ie = new InlineTag().getClass();						registerTag(InlineTag.TAG_A,ie);			registerTag(InlineTag.TAG_B,ie);			registerTag(InlineTag.TAG_BR,ie);			registerTag(InlineTag.TAG_EM,ie);			registerTag(InlineTag.TAG_I,ie);			registerTag(InlineTag.TAG_IMG,ie);			registerTag(InlineTag.TAG_SPAN,ie);			registerTag(InlineTag.TAG_STRONG,ie);			registerTag(InlineTag.TAG_BIG,ie);			registerTag(InlineTag.TAG_SMALL,ie);			registerTag(InlineTag.TAG_TT,ie);			registerTag(InlineTag.TAG_U,ie);			registerTag(InlineTag.TAG_TD,ie);			registerTag(InlineTag.TAG_INPUT,ie);			registerTag(InlineTag.TAG_BUTTON,ie);			registerTag(InlineTag.TAG_TEXTAREA,ie);			registerTag(InlineTag.TAG_CENTER,ie);			registerTag(InlineTag.TAG_LABEL,ie);			registerTag(InlineTag.TAG_OPTION,ie);			registerTag(InlineTag.TAG_SELECT,ie);		}						{			Class be = new BlockTag().getClass();					registerTag(BlockTag.TAG_P,be);					registerTag(BlockTag.TAG_BODY,be);					registerTag(BlockTag.TAG_TABLE,be);				registerTag(BlockTag.TAG_TR,be);			registerTag(BlockTag.TAG_DIV,be);					registerTag(BlockTag.TAG_TITLE,be);					registerTag(BlockTag.TAG_META,be);					registerTag(BlockTag.TAG_STYLE,be);			registerTag(BlockTag.TAG_SCRIPT,be);			registerTag(BlockTag.TAG_H1,be);					registerTag(BlockTag.TAG_H2,be);					registerTag(BlockTag.TAG_H3,be);					registerTag(BlockTag.TAG_H4,be);					registerTag(BlockTag.TAG_H5,be);					registerTag(BlockTag.TAG_H6,be);			registerTag(BlockTag.TAG_HR,be);			registerTag(BlockTag.TAG_FORM,be);		}						{			Class le = new ListBlockTag().getClass();			registerTag(ListBlockTag.TAG_UL,le);					registerTag(ListBlockTag.TAG_LI,le);					registerTag(ListBlockTag.TAG_OL,le);					registerTag(ListBlockTag.TAG_DL,le);					registerTag(ListBlockTag.TAG_DT,le);					registerTag(ListBlockTag.TAG_DD,le);				}	}		/**	 * Registers an XML tag to be handled by an instance of the given class. The class MUST be a subclass of Tag	 * @see HtmlUtil	 * @param name name of the tag	 * @param cl the class that will handle the action	 */	public void registerTag(String name,Class cl) 	{		if(name!=null && cl!=null)		{			try			{				Tag t = (Tag)cl.newInstance();			} catch (Exception e)			{				Log.logError("Failed to register class for tag "+name+". ",e);				throw new IllegalArgumentException("Class must be an instantiable subclass of Tag. "+e.getMessage());			}			knownTags.put(name,cl);		}		else throw new NullPointerException("Tag name and class cannot be null");	}		private void showGauge(String message)	{		if(!showLoadingGauge) return;				if(gauge!=null) hideGauge();				gauge = new ProgressbarAnimation(message);				Font font = FireScreen.getTheme().getFontProperty("titlebar.font");		FireScreen screen = FireScreen.getScreen();		int sw = screen.getWidth();		int mw = font.stringWidth(message);		gauge.setWidth(sw);		gauge.setHeight(font.getHeight());		screen.addComponent(gauge,6);	}		private void hideGauge()	{		if(gauge!=null){			FireScreen.getScreen().removeComponent(gauge);			gauge=null;		}	}	/**	 * Loads the page from the given URL using the supplied method and reqest parameters and data. 	 * This method will use the supplied HttpClient {@link #httpClient} to make the request and then render the page.<br/> 	 * 	 * The resulting will be added to added to a Page instance and returned to the caller.	 * It will not handle "meta" tag information, but will return them inside the Page instance. <br/>	 * 	 * This method is <b>synchronized</b> on the browser instance.	 * 	 * @param url 	 * @param method The method can be HttpConnection.GET or HttpConnection.POST	 * @param requestParameters params for the http request header 	 * @param data if the method is HttpConnection.POST the post data if any must be in this byte array 	 * @return	 * @throws UnsupportedEncodingException	 * @throws IOException	 * @throws Exception	 */	public synchronized Page loadPage(String url,String method,Hashtable requestParameters,byte []data) throws UnsupportedEncodingException,IOException,Exception	{		if(url.startsWith("ttp://") || url.startsWith("ttps://"))		{			url = "h"+url;			Log.logWarn("Malformed url resolved to: "+url);		}				Page page = new Page(url);		/* ********** Display a gauge *************** */		showGauge(StringUtil.proccessUrl(url,true));				/* ************************** Request the resource **************************** */		Request currentRequest = null;		try{			currentRequest = httpClient.requestResource(url,method,requestParameters,data,true);						if(currentRequest==null) {				Log.logWarn("Failed to get resource from "+url);				return null;			}			page.setAbsolutUrl(currentRequest.getURL());			InputStream in = currentRequest.getInputStream();			if (in == null)			{				Log.logWarn("Failed to read data from "+url);				return null;			}						Log.logDebug("Base URL is: "+currentRequest.getBaseURL());			String encoding= currentRequest.getEncoding();				return loadPageFromStream(page,in,encoding);		}catch(Exception e){			Log.logError("Failed to request page "+url+".",e);			throw e;		}finally{			if(currentRequest!=null){				try{					currentRequest.close();				}catch(IOException ex){					Log.logWarn("Connection not closed!", ex);				}				currentRequest=null;			}						hideGauge();		}	}		/**	 * Loads a page from the given InputStream using the given encoding.	 * 	 * This method is <b>synchronized</b> on the browser instance.	 * 	 * @param in	 * @param encoding	 * @return A Page instance containing the result of the request	 * @throws UnsupportedEncodingException	 * @throws IOException	 * @throws Exception	 */	public synchronized Page loadPage(InputStream in,String encoding) throws UnsupportedEncodingException,IOException,Exception	{		Page page = new Page();		/* ********** Display a gauge *************** */		showGauge("Loading...");		try{			return loadPageFromStream(page,in,encoding);		}catch(Exception e){			Log.logError("Failed to request page from stream.",e);			throw e;		}finally{			hideGauge();		}	}		/*	 * The main loop of the Browser module. This uses the XmlPullParser to parse the xml from the inputstream and 	 * then iterates through the tags of the document. Each known tag is handled by the class that is registered to handle it	 * using the registerTag method.	 */	private Page loadPageFromStream(Page page,InputStream in,String encoding) throws UnsupportedEncodingException,IOException,Exception	{		/* ******************************** clean old page stuff here **************************** */		tagStack.removeAllElements();				gauge.progress();		InputStreamReader reader=null;		try{			Log.logDebug("Using Encoding: "+encoding);			reader = new InputStreamReader(in, encoding);						KXmlParser parser = new KXmlParser();			parser.setInput(reader);			parser.setFeature(org.xmlpull.v1.XmlPullParser.FEATURE_RELAXED,true);			int type=-1,oldType=-1;					Theme th = FireScreen.getTheme();			Tag rootTag = new InlineTag();			rootTag.setForegroundColor(th.getIntProperty("xhtml.fg.color"));			rootTag.setBackgroundColor(th.getIntProperty("xhtml.bg.color"));			rootTag.setFont(th.getFontProperty("xhtml.font"));						/* ********** Main XML parsing loop **************** */ 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -