FontMetrics não funciona direito

3 respostas
Luan_Potter

Olá, estou tendo um pequeno problema com um código, eu fiz uma classe que desenha uma caixa e escreve coisas dentro; para saber até quando vai escrever e depois pular de linha (para caber na caixa), eu uso o FontMetrics. Acontece que para usa o FontMetrics, precisa do Graphics2D, e para criar (e instanciar) o Graphics2D, precisa do BufferedImage que vou usar. Mas para criar o BufferedImage, eu preciso das dimensões, e, embora eu saiba a largura, que é definida, eu preciso saber também a altura; mas para descobrir a altura, eu preciso usar o FontMetrics para ver quantas linhas vai ter. Eu tentei resolver esse problema de dois jeitos, os dois dão certo mas geram outro problema. Primeiro eu tentei criar uma BufferedImage nova, de dimensões 1x1, e outro Graphics2D, somente para criar o FontMetrics; deu certo, só que, no final, a conta não dava muito certo, as vezes ficava uma ou duas palavras "a mais" e passava do limite da borda. Eu pensei que o problema fosse outra coisa, mas eu chequei várias vezes e estava tudo certo, só tinha essa gambiarra de estranho. Aí eu pensei, se para criar o FontMetrics precisa de um Graphics2D (eu tentei criar só com a fonte e não deu), deve ser por que o tamanho da fonte muda ligeiramente dependendo do Graphics2D, e isso estaria causando a distorção. Aí eu tentei um segundo método, na verdade há uma altura máxima para o box, se passar dessa altura eu coloco barra de rolagem, então nesse método eu criava a BufferedImage antes com a altura máxima, se ele fosse menor, fica um espaço transparente embaixo (acho que essa não deve ser a solução certa também, pois gasta espaço a toa), também dá certo mas continua passando da borda. Na verdade eu tinha conseguido tirar esse erro simplesmente diminuindo a largura quando eu vou checar se cabe na linha (por exemplo, se eu checava if text.length() <= width - 10 (<-- esse 10 é das bordas), eu colocava if text.length() <= width - 50 mudando 10 por um número que eu fui tentando até caber tudo). Porém, eu descobri depois que isso também não dava certo, pois conforme eu aumentava o tamanho do box (até então estava tentando com boxes todos do mesmo comprimento), esse valor que precisava por (50) aumentava de uma maneira estranha e imprevisível. E, além disso, esse método também é uma gambiarra, não tem nenhuma razão para diminuir além dos 10 que eu já tirei das bordas (sim, dos dois lados). Então, não sei se o erro é no Graphics2D ou no que, mas eu não consigo achar e gostaria de saber se alguém poderia me ajudar, vou passar a classe que cria esses Boxes com texto dentro.

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

public final class Hint extends gameObject {
  Box box;
  String text;
  ArrayList palavras, linhas, linhasVisiveis, coloredLines, specialLines, imgs;
  Font font;
  FontMetrics metrics;
  boolean scroll;
  static final int maxHeight = 250;
  int primLinha, ultimaLinha, actualHeight, linhasFinais;

  public Hint(String txt, int pw, ArrayList images) {
    coloredLines = new ArrayList(); 
    specialLines = new ArrayList();  //specialLines.get(0): int[LINHA] = NOVO TAMANHO
    imgs = images;
    text = txt;
    width = pw;
    palavras = linhas = new ArrayList();
    font = new Font("Domestic Manners",Font.PLAIN,10);
    palavras = separar(text);
//Até aqui eu só separei as palavras do texto, agora começa a parte em que eu acho que há um problema
    BufferedImage newBuff = new BufferedImage(1,1,BufferedImage.TYPE_INT_ARGB); //aqui eu crio outro BufferedImage e Graphic2D como falei
    Graphics2D g = newBuff.createGraphics();
    g.dispose();
    metrics = g.getFontMetrics(font);
    int i = 0;
//aqui é o código para separar as palavras em linhas (ele adiciona as palavras numa linha até o tamanho de acordo com o FontMetrics der maior que a largura)
    while (i < palavras.size()) {
    String linha = "";
    boolean end = false;
    while (!end)
      if (i < palavras.size()) {  //aqui tem uns códigos que criei, esse pula a linha
        if (((String) palavras.get(i)).equals("</n>")) {
            linhas.add(linha);
            linha = "";
            i++;
        } else if (((String) palavras.get(i)).equals("</c")) { //para mudar a cor da linha, você usa </c 3, por exemplo, sendo 3 o número da cor
            int[] cL = new int[2];
            cL[0] = linhas.size();
            cL[1] = Integer.parseInt((String) palavras.get(i+1));
            coloredLines.add(cL);
            i += 2;
        } else if (((String) palavras.get(i)).equals("</i")) {  //aqui para acrescentar uma imagem. o problema não está aí eu acho, pois o erro ocorre mesmo nas linhas sem cor especial ou imagem.
            int[] sL = new int[5];
            sL[2] = metrics.stringWidth(linha) + 5;
            for (int j = -2; metrics.stringWidth(" ")*j <= ((BufferedImage)imgs.get(Integer.parseInt((String) palavras.get(i+1)))).getWidth(); j++)
              linha = linha + " ";
            i += 2;
            if (((BufferedImage)imgs.get(Integer.parseInt((String) palavras.get(i+1)))).getHeight() > metrics.getHeight())
            sL[1] = ((BufferedImage) imgs.get(sL[4])).getHeight()+1;
            else
            sL[1] = metrics.getHeight();
            sL[0] = linhas.size()-1;
            sL[4] = Integer.parseInt((String) palavras.get(i+1));
            specialLines.add(sL);
//aqui é onde acho que está o problema, como falei estou comparando a linha atual mais o que vou adicionar com a largura -10 das margens
        } else if (metrics.stringWidth(linha + " " + ((String) palavras.get(i))) < width - 10) {
          linha = linha + " " + ((String) palavras.get(i));
          i++;
        } else  //se couber eu adiciono, senão eu acabo a linha e vai para a próxima
          end = true;
        } else
          end = true;
    linhas.add(linha);
    }
   //aqui acho que não é mais o problema
    linhasFinais = 0; int alturaTotal = 0, essaLinha;
      boolean end = false;
      while (!end) {
          essaLinha = metrics.getHeight();
          for (int j = 0; j < specialLines.size(); j++)
            if (((int[]) specialLines.get(j))[0] == linhas.size()-1 - linhasFinais) {
              essaLinha = ((int[]) specialLines.get(j))[1];
              break;
            } else if (((int[]) specialLines.get(j))[0] > linhas.size()-1 - linhasFinais)
              break;
          if (alturaTotal + essaLinha <= maxHeight) {
              alturaTotal += essaLinha;
              linhasFinais++;
          } else
              end = true;
      }
    height = getHeight(0);
    actualHeight = height;
    rolar(0);
  }
  public int getHeight(int linhaInicial) {
    int h = metrics.getHeight() * (linhas.size() - linhaInicial) + 10;
    for (int j = linhaInicial; j < specialLines.size(); j++)
        h += ((int[]) specialLines.get(j))[1] - metrics.getHeight();
    return h;
  }
  public void move(int pox, int poy, int tex, int tey) {
      if (pox > tex/2)
      x = pox - width;
      else
      x = pox;
      if (poy > tey/2)
      y = poy - height;
      else
      y = poy;
  }
  public Color getColor(int num) {
     if (num == 0)
         return Color.YELLOW;
     else if (num == 1)
         return Color.GREEN;
     else if (num == 2)
         return Color.BLUE;
     else if (num == 3)
         return Color.RED;
     else if (num == 4)
         return Color.PINK;
     else
         return Color.GRAY;
  }
  public ArrayList separar(String text) {
    ArrayList ar = new ArrayList();
    int preI = -1;
    for(int i = 0; i < text.length(); i++)
        if (text.charAt(i) == ' ') {
            ar.add(text.substring(preI+1, i));
            preI = i;
        }
    ar.add(text.substring(preI+1, text.length()));
    return ar;
  }
  public ArrayList pegarLinhas(int linhaInicial){
      ArrayList linVis = new ArrayList();
      int qtasLinhas = 0, alturaTotal = 0, essaLinha;
      boolean end = false;
      while (!end) {
          essaLinha = metrics.getHeight();
          for (int j = 0; j < specialLines.size(); j++)
            if (((int[]) specialLines.get(j))[0] == linhaInicial + qtasLinhas) {
              essaLinha = ((int[]) specialLines.get(j))[1];
              break;
            } else if (((int[]) specialLines.get(j))[0] > linhaInicial + qtasLinhas)
              break;
          if (alturaTotal + essaLinha <= maxHeight) {
              alturaTotal += essaLinha;
              qtasLinhas++;
          } else
              end = true;
      }
      for(int i = linhaInicial; i < linhaInicial + qtasLinhas; i++)
          linVis.add(linhas.get(i));
      return linVis;
  }
  public void rolar (int quanto) {
      if (actualHeight <= maxHeight) {
        linhasVisiveis = linhas;
        scroll = false;
        primLinha = 0;
        ultimaLinha = linhas.size()-1;
    } else {
        height = maxHeight;
        scroll = true;
        if (quanto != 0)
          primLinha += quanto;
        else primLinha = 0;
        if (primLinha < 0)
            primLinha = 0;
        if (primLinha > linhas.size() - linhasFinais)
            primLinha = linhas.size() - linhasFinais;
        linhasVisiveis = pegarLinhas(primLinha);
        ultimaLinha = primLinha + linhasVisiveis.size();
    }
   if (scroll) {
      objBuffer = new BufferedImage(width+10,height,BufferedImage.TYPE_INT_ARGB);
      box = new Box(0,0,width+10,height,actualHeight,primLinha,linhas.size()-1);
    } else {
        objBuffer = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
        box = new Box(0,0,width,height);
    }
    Graphics2D b = objBuffer.createGraphics();
    int py = 5;
    b.drawImage(box.objBuffer,box.x,box.y,null);
    for (int j = 0; j < linhasVisiveis.size(); j++) {
        b.setColor(Color.white);
        for (int l = 0; l < coloredLines.size(); l++)
            if (((int[])coloredLines.get(l))[0] == j + primLinha) {
                b.setColor(getColor(((int[])coloredLines.get(l))[1]));
                break;
            } else if (((int[])coloredLines.get(l))[0] > j + primLinha)
                break;
        b.drawString((String) linhasVisiveis.get(j), 5, py+metrics.getHeight()/2);
        py += metrics.getHeight();
        for (int k = 0; k < specialLines.size(); k++)
            if (((int[]) specialLines.get(k))[0] == j + primLinha) {
                ((int[]) specialLines.get(k))[3] = py - 5;
                py += ((int[]) specialLines.get(k))[1] - metrics.getHeight();
                break;
            } else if (((int[]) specialLines.get(k))[0] > j + primLinha)
                break;
      }
    for (int k = 0; k < specialLines.size(); k++)
        if ((((int[]) specialLines.get(k))[0] > primLinha) && (((int[]) specialLines.get(k))[0] < ultimaLinha)) {
        BufferedImage aBuffer = (BufferedImage)imgs.get(((int[]) specialLines.get(k))[4]);
        int psx = ((int[]) specialLines.get(k))[2];
        int psy = ((int[]) specialLines.get(k))[3];
        b.drawImage(aBuffer, psx, psy, null);
      }
    b.dispose();
  }
}
Além disso, caso alguém queira testar, está aí o código da classe Box que eu uso aí, ela gera somente uma imagem de fundo do tamanho definido. Tem dois construtores, o que tem os atributos a mais seria para fazer a barra de rolagem, por enquanto não funciona a imagem (ele desce e sobe certinho mas não dá para ver o carrinho descendo e subindo, só tem um caminho para ele passar mas nenhum carrinho).
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;

public class Box extends gameObject {
    String bul, bur, bdl, bdr, bu, bl, br, bd, bc;
public Box(int px, int py, int pw, int ph){
    x = px;
    y = py;
    width = pw;
    height = ph;
    path = System.getProperty("user.dir") + "\src\images\box\";
    bul = path + "bul.png";
    bur = path + "bur.png";
    bdl = path + "bdl.png";
    bdr = path + "bdr.png";
    bu = path + "bu.png";
    bl = path + "bl.png";
    br = path + "br.png";
    bd = path + "bd.png";
    bc = path + "bc.png";
    objBuffer = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
    Graphics2D b = objBuffer.createGraphics();
    b.drawImage(new ImageIcon(bul).getImage(),0,0,null);
    b.drawImage(new ImageIcon(bur).getImage(),width-4,0,null);
    for(int i = 4; i < width-4; i += 4)
        b.drawImage(new ImageIcon(bu).getImage(),i,0,null);
    BufferedImage buf = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);;
    Graphics2D gbuf = buf.createGraphics();
    gbuf.drawImage(new ImageIcon(bl).getImage(),0,0,null);
    gbuf.drawImage(new ImageIcon(br).getImage(),width-4,0,null);
    for(int i = 4; i < width-4; i += 4)
        gbuf.drawImage(new ImageIcon(bc).getImage(),i,0,null);
    gbuf.dispose();
    for(int i = 4; i < height-4; i += 4)
        b.drawImage(buf, 0, i, null);
    b.drawImage(new ImageIcon(bdl).getImage(),0,height-4,null);
    b.drawImage(new ImageIcon(bdr).getImage(),width-4,height-4,null);
    for(int i = 4; i < width-4; i += 4)
        b.drawImage(new ImageIcon(bd).getImage(),i,height-4,null);
    b.dispose();
}
public Box(int px, int py, int pw, int ph, int ah, int lA, int qL){
    x = px;
    y = py;
    width = pw;
    height = ph;
    path = System.getProperty("user.dir") + "\src\images\box\";
    bul = path + "bul.png";
    bur = path + "bur.png";
    bdl = path + "bdl.png";
    bdr = path + "bdr.png";
    bu = path + "bu.png";
    bl = path + "bl.png";
    br = path + "br.png";
    bd = path + "bd.png";
    bc = path + "bc.png";
    String cup = path + "cup.png";
    String c = path + "c.png";
    String cd = path + "cd.png";
    objBuffer = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
    Graphics2D b = objBuffer.createGraphics();
    b.drawImage(new ImageIcon(bul).getImage(),0,0,null);
    b.drawImage(new ImageIcon(bur).getImage(),width-4,0,null);
    for(int i = 4; i < width-4; i += 4)
        b.drawImage(new ImageIcon(bu).getImage(),i,0,null);
    b.drawImage(new ImageIcon(cup).getImage(),width-14,0,null);
    BufferedImage buf = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);;
    Graphics2D gbuf = buf.createGraphics();
    gbuf.drawImage(new ImageIcon(bl).getImage(),0,0,null);
    gbuf.drawImage(new ImageIcon(br).getImage(),width-4,0,null);
    for(int i = 4; i < width-4; i += 4)
        gbuf.drawImage(new ImageIcon(bc).getImage(),i,0,null);
    gbuf.drawImage(new ImageIcon(c).getImage(),width-14,0,null);
    gbuf.dispose();
    for(int i = 4; i < height-4; i += 4)
        b.drawImage(buf, 0, i, null);
    b.drawImage(new ImageIcon(bdl).getImage(),0,height-4,null);
    b.drawImage(new ImageIcon(bdr).getImage(),width-4,height-4,null);
    for(int i = 4; i < width-4; i += 4)
        b.drawImage(new ImageIcon(bd).getImage(),i,height-4,null);
    b.drawImage(new ImageIcon(cd).getImage(),width-14,height-4,null);
    b.dispose();
}
}
E, quase esqueci, o gameObject, essas classes são derivadas dessa:
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

public class gameObject {
int x, y, width, height, maxheight;
double speed, speedx, speedy, ang;
BufferedImage objBuffer;
AffineTransform angulo;
String path;
Hint hint; boolean temHint, mostrarHint;
public void draw(Graphics2D g) {
        g.drawImage(objBuffer,x,y,null);
    }
public void addHint(String txt, int pw) {
      hint  =  new Hint(txt, pw);
      temHint = true;
}
public void addHint(String txt, int pw, ArrayList imgs) {
      hint  =  new Hint(txt, pw, imgs);
      temHint = true;
}
public void moveHint(int px, int py, int tx, int ty) {
    if (temHint)
    hint.move(px, py, tx, ty);
}
public void mostrarHint(boolean b) {
    if (temHint) {
    if (!mostrarHint && b)
        hint.rolar(0);
    }
    mostrarHint = b;
}
}
Eu sei que é bastante coisa, mas se alguém puder ver se acha o erro ficaria apreciado. Vou colocar uma imagem de como fica também, vai ver o problema é só aqui: [img]http://img163.imageshack.us/img163/310/imglw.png[/img] EDIT: Esqueci de uma coisa, para criar uma Hint (Box com o texto), basta usar o código, vai colocar o mesmo texto que o do print; falta só as imagens, pode usar qualquer uma. Depois é só usar o hint.objBuffer para desenhar na tela.
String desc = "</c 0 Anão </n> DESCRIÇÃO </n> Habilidades: </n> </i 0 </c 0 Visão no escuro </n> Permite enchegar por 18m em lugares sem qualquer iluminação. </n> </i 1 </c 0 Resistência a Magia </n> Você é mais resistente a magia do que o normal. Recebe mais dois de bônus de Vigor em qualquer teste de resistência a magia. </n> </i 2 </c 0 Resistência a Veneno </n> Você tem mais resistência contra veneno do que o normal. Receba +2 de Vigor em testes de resistência contra veneno. </n> </i 3 </c 0 Bom em avaliação </n> Você possui um talento inato que leh permite melhor decidir o valor de mercadorias. Receba +2 de bônus em testes de avaliação. </n> </i 4 </c 0 Esquiva contra Gigantes </n> Depois de muito batalhar contra inimigos do tipo gigante, você adquiriu +4 de Bônus de Desvio contra essas criaturas. </n> </i 5 </c 0 Ataque contra Orcs e Globinóides </n> Depois de muito batalhar contra Orcs e Globinóides, você adquiriu +1 de Bônus de Atauqe contra essas criaturas. </n> </n> </n> </n> </n> </n> Teste!";
ArrayList imgs = new ArrayList();
//aí adicione as BufferedImage necessárias, na ordem (primeiro a que vai onde tem </i 0, depois a </i 1, etc)
Hint hint = new Hint(desc, 500, imgs);

3 Respostas

E

Confesso que nunca mexi com isso, mas tem algumas classes prontas na JDK, provavelmente para evitar esses problemas que você está tendo.

http://download.oracle.com/javase/6/docs/api/java/awt/font/LineBreakMeasurer.html
http://download.oracle.com/javase/6/docs/api/java/awt/font/TextLayout.html

ViniGodoy

Os tutoriais básicos da sun também indicam o uso das duas classes que o Entanglement citou:
http://download.oracle.com/javase/tutorial/2d/text/drawmulstring.html
http://java.sun.com/developer/onlineTraining/Media/2DText/style.html#multiple

Luan_Potter

Olá! Muito obrigado pelas dicas. Eu estou alterando meu código para usar essas classes, vai ficar bem mais simples, qualquer dúvida eu posto aqui.

EDIT: Consegui refazer o código, o problema da largura desapareceu, deu tudo certo, o único problema é que as vezes ele não mostra todas as linhas que deveria, mas é raro de acontecer, vou arrumar isso mais para frente no projeto. Para quem quiser, vou postar o código completo:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.ImageGraphicAttribute;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextAttribute;
import java.awt.font.TextLayout;
import java.awt.image.BufferedImage;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
import java.util.ArrayList;

public final class Hint extends gameObject {
    Box box;
    ArrayList paragraphs, specialLines, coloredLines, linhasVisiveis, images;
    AttributedString text;
    Font font;
    int paragrafosFinais, qtasLinhas, linhasFinais, paragraphStart, paragraphEnd, paragraphAtual, primLinha, ultimaLinha;
    float actualHeight;
    boolean scroll;
    LineBreakMeasurer lineMeasurer;
    FontRenderContext frc;
    static final int maxHeight = 250;

    public Hint(String txt, int pw, ArrayList imgs) {
      int preI = 0;
      paragraphAtual = 0;
      paragraphs = new ArrayList();
      coloredLines = new ArrayList();
      specialLines = new ArrayList();
      images = imgs;
      width = pw;
      frc = new FontRenderContext(null, true, true);
      font = new Font("Domestic Manners",Font.PLAIN,10);
      actualHeight = 0;
      
      for(int i = 0; i < txt.length(); i++)
          if (txt.charAt(i) == '<')
              if (txt.charAt(i+2) == 'n') {
                  int inc = 4;
                  if (i != 0)
                  paragraphs.add(txt.substring(preI, i-1));
                  if (txt.charAt(i+3) != '>') {
                    inc+=2;
                    int[] cL = new int[2];
                    cL[0] = paragraphAtual;
                    cL[1] = Integer.parseInt(String.valueOf(txt.charAt(i+4)));
                    coloredLines.add(cL);
                  }
                  preI = i + inc;
                  paragraphAtual++;
              }
      paragraphs.add(txt.substring(preI, txt.length()));

      int k = paragraphs.size()-1;
      int h = 0;
      paragrafosFinais = 0;
      boolean vaiAcabar = false;
      while(( k >= 0 ) && (!vaiAcabar)) {
      text = new AttributedString((String) paragraphs.get(k));
      AttributedCharacterIterator paragraph = text.getIterator();
      paragraphStart = paragraph.getBeginIndex();
      paragraphEnd = paragraph.getEndIndex();
      lineMeasurer = new LineBreakMeasurer(paragraph, frc);
      lineMeasurer.setPosition(paragraphStart);
      paragrafosFinais++;

      linhasFinais = 0;
      while ((lineMeasurer.getPosition() < paragraphEnd) && (!vaiAcabar)) {
        TextLayout layout = lineMeasurer.nextLayout(width-10);
        if (h + layout.getAscent() + layout.getDescent() + layout.getLeading() <= maxHeight-10) {
            linhasFinais++;
          h += layout.getAscent() + layout.getDescent() + layout.getLeading(); }
        else
          vaiAcabar = true;
      }
      k--;
      }

      rolar(0);
    }
    
    public void move(int pox, int poy, int tex, int tey) {
      if (pox > tex/2)
      x = pox - width;
      else
      x = pox;
      if (poy > tey/2)
      y = poy - height;
      else
      y = poy;
    }

    public Color getColor(int num) {
     if (num == 0)
         return Color.YELLOW;
     else if (num == 1)
         return Color.GREEN;
     else if (num == 2)
         return Color.BLUE;
     else if (num == 3)
         return Color.RED;
     else if (num == 4)
         return Color.PINK;
     else
         return Color.GRAY;
    }
    
    public void rolar (int quanto) {

      for(int l = 0; l < paragraphs.size(); l++) {
      text = new AttributedString((String) paragraphs.get(l));
      AttributedCharacterIterator paragraph = text.getIterator();
      paragraphStart = paragraph.getBeginIndex();
      paragraphEnd = paragraph.getEndIndex();
      lineMeasurer = new LineBreakMeasurer(paragraph, frc);
      lineMeasurer.setPosition(paragraphStart);

      while (lineMeasurer.getPosition() < paragraphEnd) {
        TextLayout layout = lineMeasurer.nextLayout(width-10);
          actualHeight += layout.getAscent() + layout.getDescent() + layout.getLeading();
      }
      }

      if (actualHeight <= maxHeight) {
        linhasVisiveis = paragraphs;
        scroll = false;
        primLinha = 0;
        height = (int) actualHeight;
        ultimaLinha = linhasVisiveis.size()-1;
    } else {
        height = maxHeight;
        scroll = true;
        if (quanto != 0)
          primLinha += quanto;
        else primLinha = 0;
        if (primLinha < 0)
            primLinha = 0;
        if (primLinha > paragraphs.size() - paragrafosFinais + linhasFinais)
            primLinha = paragraphs.size() - paragrafosFinais + linhasFinais;
        linhasVisiveis = pegarLinhas(primLinha);
        ultimaLinha = primLinha + linhasVisiveis.size();
    }

      objBuffer = new BufferedImage(width, height+10, BufferedImage.TYPE_INT_ARGB);
      Graphics2D b = objBuffer.createGraphics();
      b.setFont(font);
      box = new Box(0,0,width,height+10);
      b.drawImage(box.objBuffer, box.x, box.y, null);

      float drawPosY = 5;

      for (int j = 0; j < linhasVisiveis.size(); j++) {
      text = new AttributedString((String) linhasVisiveis.get(j));
      for(int i = 0; i < ((String) linhasVisiveis.get(j)).length(); i++)
          if (((String) linhasVisiveis.get(j)).charAt(i) == '<') {
          ImageGraphicAttribute iga = new ImageGraphicAttribute(((BufferedImage) images.get(Integer.parseInt(String.valueOf(((String) linhasVisiveis.get(j)).charAt(i+4))))),(int) ImageGraphicAttribute.BOTTOM_ALIGNMENT);
          text = new AttributedString(((String) linhasVisiveis.get(j)).substring(0, i) + "i" + ((String) linhasVisiveis.get(j)).substring(i+5, ((String) linhasVisiveis.get(j)).length()));
          text.addAttribute(TextAttribute.CHAR_REPLACEMENT, iga, i, i+1);
          }
      AttributedCharacterIterator paragraph = text.getIterator();
      paragraphStart = paragraph.getBeginIndex();
      paragraphEnd = paragraph.getEndIndex();
      lineMeasurer = new LineBreakMeasurer(paragraph, frc);

      lineMeasurer.setPosition(paragraphStart);

      b.setColor(Color.white);
        for (int i = 0; i < coloredLines.size(); i++)
            if (((int [])coloredLines.get(i))[0] == j + primLinha) {
                b.setColor(getColor(((int [])coloredLines.get(i))[1]));
                break;
            } else if (((int [])coloredLines.get(i))[0] > j + primLinha)
                break;
      int linhaAtual = 0;
      while (lineMeasurer.getPosition() < paragraphEnd) {
        if (j == linhasVisiveis.size()-1)
            if (linhaAtual >= qtasLinhas)
                break;
        TextLayout layout = lineMeasurer.nextLayout(width-10);
        drawPosY +=  layout.getAscent();
        float drawPosX;
        if (layout.isLeftToRight()) {
          drawPosX = 5;
        } else {
          drawPosX = width - layout.getAdvance() - 5; }
        layout.draw(b, drawPosX, drawPosY);
        drawPosY += layout.getDescent() + layout.getLeading();
        linhaAtual++;
      }
      }

      b.dispose();
    }

    public ArrayList pegarLinhas(int linhaInicial){
      ArrayList linVis = new ArrayList();
      int qtosParagrphs = 0, alturaTotal = 0;
      qtasLinhas = 0;
      int k = linhaInicial;
      boolean vaiAcabar = false;
      while(( k < paragraphs.size()) && (!vaiAcabar)) {
      text = new AttributedString((String) paragraphs.get(k));
      AttributedCharacterIterator paragraph = text.getIterator();
      paragraphStart = paragraph.getBeginIndex();
      paragraphEnd = paragraph.getEndIndex();
      lineMeasurer = new LineBreakMeasurer(paragraph, frc);
      lineMeasurer.setPosition(paragraphStart);
      qtosParagrphs++;

      while ((lineMeasurer.getPosition() < paragraphEnd) && (!vaiAcabar)) {
        TextLayout layout = lineMeasurer.nextLayout(width-10);
        if (alturaTotal + layout.getAscent() + layout.getDescent() + layout.getLeading() <= height-10) {
          alturaTotal += layout.getAscent() + layout.getDescent() + layout.getLeading();
          qtasLinhas++; }
        else
          vaiAcabar = true;
      }
      k++;
      }
      for(int i = linhaInicial; i < linhaInicial + qtosParagrphs; i++)
          linVis.add(paragraphs.get(i));
      return linVis;
  }

    public int getHeight (int quanto) {
      int k = quanto;
      int h = 0;
      boolean vaiAcabar = false;
      while(( k < paragraphs.size()) && (!vaiAcabar)) {
      text = new AttributedString((String) paragraphs.get(k));
      AttributedCharacterIterator paragraph = text.getIterator();
      paragraphStart = paragraph.getBeginIndex();
      paragraphEnd = paragraph.getEndIndex();
      lineMeasurer = new LineBreakMeasurer(paragraph, frc);
      lineMeasurer.setPosition(paragraphStart);

      while ((lineMeasurer.getPosition() < paragraphEnd) && (!vaiAcabar)) {
        TextLayout layout = lineMeasurer.nextLayout(width-10);
        if (h + layout.getAscent() + layout.getDescent() + layout.getLeading() <= maxHeight)
          h += layout.getAscent() + layout.getDescent() + layout.getLeading();
        else
          vaiAcabar = true;
      }
      k++;
      }
      return h;
    }
}
Criado 27 de julho de 2011
Ultima resposta 28 de jul. de 2011
Respostas 3
Participantes 3