Вывод многострочного текста на Canvas. Перенос слов в J2ME

    Класс MultiLineText включает в себя шесть методов
  • void SetTextPar(…) – используется для задания параметров отображаемого текста;
  • void DrawMultStr()– вывести текст на экран;
  • void MoveDown(), void MoveUp() – построчная прокрутка текста;
  • void PageDown(), void PageUp() – постраничная прокрутка текста.

Для использования класса поместите файл MultiLineText.java в папку src своего проекта. После этого создайте объект и с помощью метода SetTextPar задайте параметры текста. Методу SetTextPar необходимо передать шесть параметров:

public void SetTextPar(
        int x,
        int y,
        int width,
        int height,
        int dy,
        int FontSize,
        int FontStyle,

        int FontType,
        Graphics graph,
        String LongString
        )

где x, y – координаты верхнего левого угла текста; width и height – ширина и высота прямоугольной области, куда будет выводиться текст; dy – шаг в пикселях при прокрутке строк (фактически это скорость прокрутки текста); FontSize – размер шрифта (Font.SIZE_LARGE, Font.SIZE_MEDIUM, Font.SIZE_SMALL); FontStyle – стиль шрифта (Font.STYLE_BOLD, Font.STYLE_PLAIN, Font.STYLE_ITALIC); FontType – тип шрифта (Font.FACE_MONOSPACE, Font.FACE_PROPORTIONAL, Font.FACE_SYSTEM), graph – Graphics объект; LongString – строка текста.

После того, как параметры текста заданы, можно использовать метод DrawMultStr() для вывода текста на экран.

Ниже приведен пример использования класса MultiLineText.

import javax.microedition.lcdui.*;

public class MyCanvas extends Canvas
{
    private boolean isFirstRun=true; Флаг первого запуска.

    private MultiLineText MLT;

    public void paint(Graphics g)
    {
       int GrH=getHeight(); //Высота экрана

       int GrW=getWidth(); //Ширина экрана

       if (isFirstRun==true)
        {
            //При первом запуске программы создаем объект MultiLineText

            //и задаем параметры текста.

            MLT = new MultiLineText();
            MLT.SetTextPar(30, 30, GrW-60,GrH-60,5,Font.SIZE_LARGE,Font.STYLE_BOLD,Font.FACE_PROPORTIONAL,g, "Длинная строка текста");
            isFirstRun=false;

        }
       g.setColor(255,255,255);
       g.fillRect(0,0,GrW,GrH);
       g.setColor(0,0,0);
       g.drawRect(28, 28, GrW-56,GrH-56);
       g.setColor(0xff0000);
       MLT.DrawMultStr(); //Выводим текст на экран.

    }

    
    protected void keyPressed( int keyCode ){
    //Организуем прокрутку текста.

       if (keyCode == getKeyCode(UP))
       {
           MLT.MoveUp();
       }else if (keyCode == getKeyCode(DOWN))
       {
           MLT.MoveDown();

       }else if (keyCode == getKeyCode(LEFT))
       {
           MLT.PageUp();
       }else if (keyCode == getKeyCode(RIGHT))
       {
           MLT.PageDown();
       }
       repaint();
    }

}

Перенос строк

Собственно перенос строк реализован в методе SetTextPar. Переданная строка LongString разбивается на массив строк, который заносится в Vector StringLines. Если слово полностью не помещается в строке, оно разбивается на несколько строк. Таким образом, текст разбивается на строки на этапе задания параметров, а при вызове метода DrawMultStr происходит отображение уже разбитого на строки текста.

import java.util.Vector;
import javax.microedition.lcdui.*;

public class MultiLineText {
    private int x,y,w,h,fsz,fst,fty; //Размер ограничивающего прямоугольника

    private int hStr; //Высота строки

    private int y0; //Положение верхнего края текста

    private int dy; //Шаг при прокрутке текста

    private int textheight; //Общая высота текста

    private Vector StringLines;
    private Graphics g;
    private int gx,gy,gw,gh; //Исходная область

    private String str1;
            
    public void SetTextPar(
            int x,
            int y,
  
          int width,
            int height,
            int dy,
            int FontSize,

            int FontStyle,
            int FontType,
            Graphics graph,
            String LongString
            )
    {
        //Присваиваем значения внутренним переменным.

        this.x=x;
        this.y=y;

        this.w=width;
        this.h=height;
        this.dy=dy;
        this.fsz=FontSize;
        this.fst=FontStyle;
        this.fty=FontType;
        this.g=graph;
        //Запоминаем размеры текущей области для рисования

        gx=g.getClipX();

        gy=g.getClipY();
        gw=g.getClipWidth();
        gh=g.getClipHeight();
        //Устанавливаем параметры шрифта

        g.setFont(Font.getFont(fty, fst, fsz));
        hStr=g.getFont().getHeight(); //Высота строки в пикселях

        //*******************************************

        //* Разбиваем строку и создаем вектор строк *

        //*******************************************

        SringLines=null;
        StringLines =new Vector(1);
        int i0=0, //Номер прошлого найденного в строке пробела

        int i=0, //Номер последнего найденного в строке пробела

        int in=0; //Номер символа, соответствующего началу строки

        int j=0; //Ширина слова в пикселях

        int jw=0; //Ширина строки в пикселях

        int imax=LongString.length(); //Длина строки в символах

        boolean isexit=true; //Флаг выхода

        y0=0;
        while (isexit)
        {
            i=LongString.indexOf(" ", i0+1);

            if (i<=i0)
            {
                i=imax;
                isexit=false;
            }
            j=g.getFont().stringWidth(LongString.substring(i0,i));
            if (jw+j<w)
            {//Слово умещается в текущей строке

                jw=jw+j;
                i0=i;
            } else
            {//Слово не умещается в текущей строке

                StringLines.addElement(LongString.substring(in,i0));
                in=i0+1;
                jw=j;
                if (j>w)

                {//Ширина слова больше чем ширина области вывода

                    i=i0;
                  while (jw>w)
                  {
                    j=0;
                    while (j<w)
                    {

                        i=i+1;
                        j=g.getFont().stringWidth(LongString.substring(in,i));
                    
                    }
                    i=i-1;
                    j=g.getFont().stringWidth(LongString.substring(in,i));
                    StringLines.addElement(LongString.substring(in,i));
                    jw=jw-j;
                 &nb
sp;  i0=i;

                    in=i;
                  }
                  jw=0;
                }else{i0=i;}
            }
        }
        StringLines.addElement(LongString.substring(in,imax));
        textheight=StringLines.size()*hStr;
    }

    
    public void DrawMultStr()
    {
       int y1;
       g.setClip(x, y, w, h); //Ограничиваем область вывода

       y1=y0;
       g.setFont(Font.getFont(fty, fst, fsz));
       for (int i=0;i<StringLines.size();i++)

       {
           if ((y1+hStr)>0){
           g.drawString(StringLines.elementAt(i).toString(), x+1, y+y1, g.LEFT|g.TOP);
           }
           y1=y1+hStr;
           if (y1>h){break;}
       }
       g.setClip(gx, gy, gw, gh);

       
    }
            
...

}

Демонстрационный пример использования MultiLineText


Автор: Александр Ледков (aRix).

Материал предоставлен сайтом www.MobiLab.ru