📄 simulator.java
字号:
} else if(name.equals("u")){ _underline = (state == tag.TAG_OPEN) ? true : false; } else if(name.equals("br")){ flushBuffer(); } } /** * add text to the glyph vector. the text buffer helps * in rendering text to the screen, because rendering * is all based on content spacing, character widths, etc. */ private void bufferText( String s){ int style = _currentfont; _offg.setFont( FONTS[_currentfont]); FontMetrics fm = _offg.getFontMetrics(); Glyph g = null; // note: if the buffer ends with a hard character, // and the next character is a hard character, insert // a space... // BUT: there's a problem -- if underline is currently // on, it'll append a space underline to the front... // only do it, then, if the prior glyph is underlined. int len = s.length(); if( _buffer.size() > 0 && len > 0 && s.charAt(0) != ' '){ g = new Glyph(); g.character = ' '; g.style = style; g.width = fm.charWidth( g.character); g.underline = _underline && ((Glyph)(_buffer.lastElement())).underline; _buffer.addElement(g); } for(int i = 0; i< len; i++){ g = new Glyph(); g.character = s.charAt(i); g.style = style; g.width = fm.charWidth( g.character); g.underline = ( _underline || _currentlinkindex > -1); g.linkindex = _currentlinkindex; _buffer.addElement(g); } } /** * flush the buffer: cut lines into screen width * chunks, and write lines to the screen. then, * empty the buffer. */ private void flushBuffer(){ int width = 0; int len = _buffer.size(); int idx = 0; int idx_start = 0; int space = -1; // create a glyph array from the vector. Glyph buffer[] = new Glyph[len]; for(Enumeration e = _buffer.elements(); e.hasMoreElements(); ){ buffer[idx++] = (Glyph)(e.nextElement()); } idx = 0; while( idx < len){ idx_start = idx; width = 0; space = -1; while( width< ScreenWidth -2 && idx < len){ if( buffer[idx].character == ' ') space = idx; width += buffer[idx++].width; } // out of the loop -- so render the line. // if it's less than screen width, draw it; // otherwise, look for the last space; // or finally, just draw it. (back up one?) if( width < ScreenWidth -2) write( buffer, idx_start, idx); else if( space > -1){ write( buffer, idx_start, space); idx = space + 1; } else{ write( buffer, idx_start, --idx); } } // now wipe the buffer. _buffer = new Vector(); } /** * this method writes a specified substring from the * buffer to the screen. */ private void write(Glyph[] buffer, int start, int end){ Object obj = null; int width = 0; for(int i = start; i< end; i++) width += buffer[i].width; int current_style = FONT_PLAIN; _offg.setFont( FONTS[current_style]); justify( width); for(int i = start; i< end; i++){ if( buffer[i].style != current_style){ current_style = buffer[i].style; _offg.setFont( FONTS[current_style]); } _offg.setColor( Color.black); // if it's a link, I need to know where it is // on the map. if(buffer[i].linkindex > -1){ Tag tag = (Tag)(_links.get( new Integer(buffer[i].linkindex))); //System.out.println("tag is null? " + (null == tag)); if(null == tag.getParm("__top")){ tag.setParm("__top", String.valueOf( _cursor.y - ROWHEIGHT + 4)); tag.setParm("__bottom", String.valueOf( _cursor.y + 4)); } else{ tag.setParm("__bottom", String.valueOf( _cursor.y + 4)); } } // if it's a link, and it's hot... if(buffer[i].linkindex == _highlightlink){ _offg.fillRect( _cursor.x, _cursor.y - ROWHEIGHT + 4, buffer[i].width + 1, ROWHEIGHT); _offg.setColor( Screen_Green); } else{ if(buffer[i].underline) _offg.drawLine( _cursor.x, _cursor.y + 1, _cursor.x + buffer[i].width, _cursor.y + 1); } _offg.drawString( String.valueOf( buffer[i].character), _cursor.x, _cursor.y); _cursor.x += buffer[i].width; } _cursor.y += ROWHEIGHT; } /** * justify the string, by moving the cursor.x position. */ private void justify( int width){ if( _justify == CENTER_JUSTIFY) _cursor.x = 1 + ((ScreenWidth - 2 - width)/2); else if( _justify == RIGHT_JUSTIFY) _cursor.x = 1 + ScreenWidth - 2 - width; else _cursor.x = 1; } /** * glyph is an internal class, because linux netscape (java 1.1.5?) * was throwing an access exception that I couldn't quite track * down. moving it in here cleared up the exception, but it's * still irritating that I couldn't find it. */ private class Glyph{ int width; int style; char character; boolean underline; int linkindex; /** constructor sets default values */ public Glyph(){ width = 0; style = -1; character = ' '; underline = false; linkindex = -1; } } /** check if a specified link is displayed on the screen. */ private boolean linkOnScreen(int link){ int top, bottom; Object obj = _links.get( new Integer(link)); if( null == obj) return false; Tag tag = (Tag)obj; top = Integer.parseInt( tag.getParm("__top")); bottom = Integer.parseInt( tag.getParm("__bottom")); return (!( (bottom + _vertical) < 0 || (top + _vertical) > ScreenHeight)); } /** load content from a specified page. */ private void loadContent(String page){ // flag for successful loading boolean success = false; String idString = "init"; if( null != page && !(page.trim().equals(""))){ // cut out the & s... int idx = -1; while((idx = page.indexOf( "&")) >= 0){ page = page.substring(0, idx + 1) + page.substring( idx + 5); } // if it starts with a ``rel:'', insert the current host... if(page.startsWith("rel:")){ //java.net.URL doc = "";//getDocumentBase(); } else if (page.indexOf("://") < 0 ){ //java.net.URL doc = "";//getDocumentBase(); // debug // System.out.println("document base: " + doc.toString()); //page = doc.getProtocol() + "://" +doc.getHost() + "/" + page; // debug // System.out.println("new page: " + page); } try{ // debug // System.out.println("reading url: " + page); String data = loadDocument(_page); // find 1st card and 1st id int pos = data.indexOf("<card"); int end = data.indexOf(">", pos); String initcard = data.substring(pos, end); pos = initcard.indexOf("id"); pos = initcard.indexOf("\"", pos); end = initcard.indexOf("\"", pos + 1); idString = initcard.substring(pos + 1, end); _contents = _parser.tree( _parser.readString(data)); //_contents = _parser.tree( _parser.readURL(page, _cookiejar)); // if it hasn't thrown an exception, set the success flag. if (data.length() > 0) success = true; // debug // System.out.println("read page " + page); } catch(Exception e){ //System.out.println("page read failed."); e.printStackTrace(System.out); } } // on content load failure, show the default content. if(!success){ try{ _contents = _parser.tree( _parser.readString( defaultContent)); } catch(Exception e){ // debug // System.out.println("this shouldn't happen..."); e.printStackTrace(System.out); } } // if there's a card anchor, set the current card. // otherwise, set to init. if(page.indexOf('#') < 0) _currentcard = idString; else{ _currentcard = page.substring( page.indexOf('#') + 1); // System.out.println("using card: " + _currentcard); } } /** * Loads a file and assigns the file text to the document. * @param String fileName - the name of the file. */ private String loadDocument(String fileName) { String fileData = ""; try { // Read data FileInputStream fis = new FileInputStream (fileName); int size = fis.available(); byte[] bytes = new byte [size]; fis.read (bytes); fileData = new String (bytes); fis.close (); // replace all tabs with spaces String data = ""; StringTokenizer st = new StringTokenizer(fileData, "\t"); while (st.hasMoreTokens()) data = data + st.nextToken(); fileData = data; // replace all \n with spaces data = ""; st = new StringTokenizer(fileData, "\n"); while (st.hasMoreTokens()) data = data + " " + st.nextToken(); fileData = data; // remove all \r (windows uses \n\r combination for newline) data = ""; st = new StringTokenizer(fileData, "\r"); while (st.hasMoreTokens()) data = data + st.nextToken(); // remove start int pos = data.indexOf("<wml"); if (pos > -1) fileData = data.substring(pos); else fileData = ""; } catch (IOException e) {} return fileData; } /** reload content. */ private void reload(){ // System.out.println("reload() called."); _highlightlink = 0; loadContent(_page); drawScreen(_currentcard); _vertical = 0; repaint(); } /** overrides default paint method */ public void paint( Graphics g){ super.paint(g); if( null != _bgimage) { g.drawImage( _bgimage, 0, 0, getContentPane()); } } /** * Slightly modified default phone constructor based mostly on the same * constructor used by the original WAPLET class. */ private void init() { setSize(180, 400); Screen_Green = new Color( 0, 234, 0); // screen values ScreenWidth = 124; ScreenHeight = 83; // get the background image _bgimage = Toolkit.getDefaultToolkit().createImage(Simulator.class.getResource(BACKGROUND_IMAGE)); // read content _parser = new Parser(); loadContent(_page); // set some defaults, and render the page. _cursor = new Point(1, 16); _justify = LEFT_JUSTIFY; _underline = false; _invert = false; _currentfont = FONT_PLAIN; _currentlinkindex = -1; _vertical = 0; _buffer = new Vector(); _links = new Hashtable(); _highlightlink = 0; _doprev = false; _dostring = ""; _donext = false; _donextstring = ""; // draw card drawScreen(_currentcard); // define the panels/layout _p = new Panel(){ public Dimension getMinimumSize(){ return new Dimension(ScreenWidth, ScreenHeight); } public Dimension getPreferredSize(){ return getMinimumSize(); } public void update(Graphics g){ paint(g); } public void paint(Graphics g){ g.drawImage(_offscreen, 0, 0 + _vertical, getContentPane()); } }; _p2 = new Panel(){ public Dimension getMinimumSize(){ return new Dimension(ScreenWidth, BUTTONSCREENHEIGHT); } public Dimension getPreferredSize(){ return getMinimumSize(); } public void update(Graphics g){ paint(g); } public void paint(Graphics g){ g.setColor( Screen_Green); g.fillRect( 0, 0, ScreenWidth, 30); g.setColor( Color.black); if( _donext) { g.setFont( FONTS[FONT_BOLD]); g.drawString(_donexttext, 4, ROWHEIGHT + 2); } // eventually, provide better simulation // by allowing links and do's to be // integrated into a menu that // is overlayed on the screen. Right now, // only one do tag can be displayed, and // it takes preference over a link. else if( linkOnScreen( _highlightlink)) { g.setFont( FONTS[FONT_BOLD]); g.drawString("Link", 4, ROWHEIGHT + 2); } if( _doprev) { g.setFont( FONTS[FONT_BOLD]); g.drawString(_dotext, ScreenWidth - 32, ROWHEIGHT + 2); } } }; // define buttons Button up = new Button("/\\"); up.addActionListener(this); up.setActionCommand("up"); Button down = new Button("\\/"); down.addActionListener(this); down.setActionCommand("down"); Button left = new Button("--"); left.addActionListener(this); left.setActionCommand("left"); Button right = new Button("--"); right.addActionListener(this); right.setActionCommand("right"); // we're now using no absolute positioning, // no layout manager. we need to force some behavior. // this does lead to some complex layout definitions, // though. // Remove any components that may have been added previously. mainPanel.removeAll(); getContentPane().removeAll(); getContentPane().setLayout( null); Insets insets = this.getInsets(); int centerline = 87; int offset_y = 66 + insets.top; getContentPane().add(_p); _p.setBounds( centerline - ( _p.getPreferredSize().width/2), offset_y, _p.getPreferredSize().width, _p.getPreferredSize().height); offset_y += _p.getPreferredSize().height - 1; getContentPane().add(_p2); _p2.setBounds( centerline - ( _p2.getPreferredSize().width/2), offset_y,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -