Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
New Contributor
xander0528
Posts: 6
Registered: ‎02-07-2011
My Device: Not Specified

Re: Simple HTMLTextField implementation...

Okay thanks. Good to know.

New Developer
maverickfastern
Posts: 8
Registered: ‎11-16-2009
My Device: Not Specified

Re: Simple HTMLTextField implementation...

Nice Share.....Really need this for my knowledge

Developer
donturner
Posts: 135
Registered: ‎11-14-2010
My Device: BlackBerry Z10 (White)

Re: Simple HTMLTextField implementation...

Really appreciate the code, it has helped me out a lot. Thanks :smileyhappy:

Trusted Contributor
jaff
Posts: 115
Registered: ‎11-16-2011
My Device: Smartphone Storm 9900

Re: Simple HTMLTextField implementation...

im try code above...but i can't make custom font... with blabla.setFont(font1)

how to create custom font with HTMLTextField?

Developer
peter_strange
Posts: 19,609
Registered: ‎07-14-2008
My Device: Not Specified

Re: Simple HTMLTextField implementation...

Since this Thread is all about simple html fields, talking about fonts is off topic.  You should start your own Thread. 

 

Are you sure you want to create a custom Font?

Developer
donturner
Posts: 135
Registered: ‎11-14-2010
My Device: BlackBerry Z10 (White)

Re: Simple HTMLTextField implementation...

I found myself needing to change the colour of the text which is outputted so have updated this class to allow you to specify a text colour in the getInstance method. I have also removed the redundant constructor for HTMLTextField so that getInstance returns a RichTextField since HTMLTextField is just a factory to create a RichTextField object.
import java.util.Stack;
import java.util.Vector;

import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.component.RichTextField;

/** Class that implements very basic formatting of a label 
 *  field using HTML codes. Only the basic XHTML elements
 *  are currently supported:
 *  <ul>
 *   <li>tt: Renders as teletype or monospaced text.</li>
 *   <li>i: Renders as italic text style.</li>
 *   <li>b: Renders as bold text style.</li>
 *   <li>big: Renders text in a "large" font.(1.2 times bigger, as specified in CSS-2)</li>
 *   <li>small: Renders text in a "small" font. (1.2 times smaller, as specified in CSS-2</li>  
 *  </ul>
 *  
 * This field does not support data that contains those
 * embedded items in the string, since they will be considered
 * as xhtml codes.
 * 
 * Validation is strictly limited.
 * 
 * @author Carl Eric Codere
 * @author Don Turner (Added support for font color)
 *
 */
public class HTMLTextField extends RichTextField
{
  
  private static final String[] TAGS = {"i", "b","tt","big","small"};

  //Type
  private static final int TAG_STYLE_ITALICS = 0x01;
  private static final int TAG_STYLE_BOLD = 0x02;
  private static final int TAG_STYLE_TELETYPE = 0x04;
  private static final int TAG_STYLE_NORMAL = 0x00;
  //Size
  //These two last items are exclusive. 
  private static final int TAG_SIZE_NORMAL = 0x80;
  private static final int TAG_SIZE_BIG =  0x82;
  private static final int TAG_SIZE_SMALL = 0x84;

  private static final int[] TAG_TYPES =
  {TAG_STYLE_ITALICS,TAG_STYLE_BOLD,TAG_STYLE_TELETYPE,TAG_SIZE_BIG,TAG_SIZE_SMALL};
  

   private static final class ElementState 
   {
     int startPos;
     int endPos;
     int tagType;

     public ElementState(int currentPos)
     {
       startPos = currentPos;
       tagType = TAG_STYLE_NORMAL | TAG_SIZE_NORMAL;
     }
   }

   private static class ElementStateList extends Vector
   {
     public void add(ElementState o)
     {
       ElementState e;
       int i;
       // We merge this element with another element of this type
       // if it already exists at this offset.
       for (i= 0; i < size(); i++)
       {
         e = (ElementState)elementAt(i);
         // There is a match, then we must merge the data
         if (e.startPos == o.startPos)
         {
            e.tagType = e.tagType | o.tagType;
            e.endPos = o.endPos;
            return;
        }
       }
       super.addElement(o);
     }
   }
     


   private static int getTagType(String s)
   {
     int i;
     for (i = 0; i < TAGS.length; i++)
     {
       if (s.equals(TAGS[i]))
       {
         return (TAG_SIZE_NORMAL | TAG_TYPES[i]);
       }
     }
     return -1;
   }

   /** This method parses a text string containing XHTML markup text which is limited
    *  to only certain elements, and then creates a correct RichTextField field 
    *  already setup correctly with all correct handling of the markup..
    * 
    * @param text The text, optionally containing valid XHTML markup
    * @param style The style
    * @return a new instance of HTMLTextField
    * @throws java.lang.IllegalArgumentException
    */
   public static RichTextField getInstance(String text, long style, final int textColor) throws IllegalArgumentException
   {
     int i = 0;
 
     char c;
     int fontStyle;
     ElementState currentState;
     ElementState e;
     Stack stack;
     String currentTag ="";
     String cleanString = "";
     boolean validTag = false;
     int tagType;
     ElementStateList states = new ElementStateList();
     stack = new Stack();
 
     currentState = new ElementState(0);

     // Push the normal state element
     states.add(currentState);
     i = 0;
     while (i < text.length())
     {
       c = text.charAt(i);
       if (c == '<')
       {
         currentTag = "";
         i++;
         validTag = false;
         while (i < text.length()) 
         {
            c = text.charAt(i);
            if (c == '>')
            {
                  validTag = true;
                  break;
            }
            currentTag = currentTag + c;
            i++;
        }
        // The end of the text string was reached without an end 
        // tag.
        if (validTag == false)
        {
           cleanString = cleanString + "<"+ currentTag; 
           i++;
           continue;
        }
        // Now check if this is an end tag or not
        if (currentTag.charAt(0) == '/')
        {
            currentTag = currentTag.substring(1);
            tagType = getTagType(currentTag);
            if (tagType == -1)
            {
                cleanString = cleanString + "</"+currentTag+">";
                i++;
                continue;
            }
            // Illegal value
            if (stack.empty()==true)
                throw new IllegalArgumentException("Mssing start tag for "+currentTag);
            e = (ElementState)stack.peek();
            // The values are bitmasks
            if ((e.tagType & tagType)==0)
            {
                throw new IllegalArgumentException("Missing start tag for "+currentTag);
            }
            stack.pop();
            e.endPos = cleanString.length();
            states.add(e);
            // Push the normal state element
            currentState = new ElementState(cleanString.length());
            states.add(currentState);
        } else
        {
            // This is the start of the element
            tagType = getTagType(currentTag);
            if (tagType == -1)
            {
                cleanString = cleanString+"<"+currentTag+">";
                i++;
                continue;
            }
            e = new ElementState(cleanString.length());
            currentState.endPos = cleanString.length();
            e.tagType = tagType;
            stack.push(e);
        }
     }
     else
       cleanString = cleanString + c;
     i++;
     }
     currentState.endPos = cleanString.length();
     // Remove this last element if it points to invalid data.
     if (currentState.endPos == currentState.startPos)
     {
         int deleteIdx = states.indexOf(currentState);
         states.removeElementAt(deleteIdx);
     }
 
     // Normally all elements should have been emptied
     if (stack.empty() == false)
     {
       throw new IllegalArgumentException("Missing end tag(s)");
     }
 
     // Now create the tables for the RichTextField...
     int[] off = new int[states.size()+1];
     byte[] attr = new byte[states.size()];
     Font defaultFont = Font.getDefault();
     Font[] fon = new Font[states.size()];
     for (i = 0; i < states.size(); i++)
     {
       e = (ElementState)states.elementAt(i);
       off[i] = e.startPos;
       // Now retrieve the information on the changes in styles we have to do
       fontStyle = Font.PLAIN;
       if ((e.tagType & TAG_STYLE_ITALICS)==TAG_STYLE_ITALICS)
       {
          fontStyle |= Font.ITALIC;   
       }
       if ((e.tagType & TAG_STYLE_BOLD)==TAG_STYLE_BOLD)
       {
          fontStyle |= Font.BOLD;   
       }
       attr[i] = (byte)i;
       //Ui.UNITS_pt
       fon[i] = defaultFont.derive(fontStyle);
     }   
     off[states.size()] = cleanString.length();
     
     return new RichTextField(cleanString,off,attr,fon,style){
    	 
    	 protected void paint(Graphics g){
    		 
    		 g.setColor(textColor);
    		 super.paint(g);
    	 }
     };
     
  }
}