2010-12-10 22 views
41

g2 es una instancia de la clase Graphics2D. Me gustaría poder dibujar texto de varias líneas, pero eso requiere un carácter de nueva línea. El siguiente código se representa en una línea.Problemas con la línea nueva en Graphics2D.drawString

String newline = System.getProperty("line.separator"); 
g2.drawString("part1\r\n" + newline + "part2", x, y); 

Respuesta

69

El método drawString no maneja las líneas nuevas.

Vas a tener que dividir la cadena de caracteres de nueva línea usted mismo y dibujar las líneas de uno a uno con un desplazamiento vertical apropiada:

void drawString(Graphics g, String text, int x, int y) { 
    for (String line : text.split("\n")) 
     g.drawString(line, x, y += g.getFontMetrics().getHeight()); 
} 

Aquí es un ejemplo completo para darle la idea:

import java.awt.*; 

public class TestComponent extends JPanel { 

    private void drawString(Graphics g, String text, int x, int y) { 
     for (String line : text.split("\n")) 
      g.drawString(line, x, y += g.getFontMetrics().getHeight()); 
    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     drawString(g, "hello\nworld", 20, 20); 
     g.setFont(g.getFont().deriveFont(20f)); 
     drawString(g, "part1\npart2", 120, 120); 
    } 

    public static void main(String s[]) { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new TestComponent()); 
     f.setSize(220, 220); 
     f.setVisible(true); 
    } 
} 

que da el siguiente resultado:

enter image description here

+6

+1 - respuesta exhaustiva –

+0

La pintura personalizada se realiza anulando el método paintComponent() y debe invocar a super.paintComponent (g) primero. – camickr

+0

Buen punto. Actualizado. – aioobe

7

Acabo de hacer un método para dibujar spliting de texto largo automáticamente dando el ancho de la línea.

public static void drawStringMultiLine(Graphics2D g, String text, int lineWidth, int x, int y) { 
    FontMetrics m = g.getFontMetrics(); 
    if(m.stringWidth(text) < lineWidth) { 
     g.drawString(text, x, y); 
    } else { 
     String[] words = text.split(" "); 
     String currentLine = words[0]; 
     for(int i = 1; i < words.length; i++) { 
      if(m.stringWidth(currentLine+words[i]) < lineWidth) { 
       currentLine += " "+words[i]; 
      } else { 
       g.drawString(currentLine, x, y); 
       y += m.getHeight(); 
       currentLine = words[i]; 
      } 
     } 
     if(currentLine.trim().length() > 0) { 
      g.drawString(currentLine, x, y); 
     } 
    } 
} 
+0

¡¡¡Eso funcionó de maravilla !! –

0

He aquí un fragmento solía dibujar texto en una JPanel con el tabulador y múltiples líneas:

import javax.swing.*; 
import java.awt.*; 
import java.awt.geom.Rectangle2D; 

public class Scratch { 
    public static void main(String argv[]) { 
     JFrame frame = new JFrame("FrameDemo"); 

     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     JPanel panel = new JPanel() { 
      @Override 
      public void paint(Graphics graphics) { 
       graphics.drawRect(100, 100, 1, 1); 
       String message = 
         "abc\tdef\n" + 
         "abcx\tdef\tghi\n" + 
         "xxxxxxxxdef\n" + 
         "xxxxxxxxxxxxxxxxghi\n"; 
       int x = 100; 
       int y = 100; 
       FontMetrics fontMetrics = graphics.getFontMetrics(); 
       Rectangle2D tabBounds = fontMetrics.getStringBounds(
         "xxxxxxxx", 
         graphics); 
       int tabWidth = (int)tabBounds.getWidth(); 
       String[] lines = message.split("\n"); 
       for (String line : lines) { 
        int xColumn = x; 
        String[] columns = line.split("\t"); 
        for (String column : columns) { 
         if (xColumn != x) { 
          // Align to tab stop. 
          xColumn += tabWidth - (xColumn-x) % tabWidth; 
         } 
         Rectangle2D columnBounds = fontMetrics.getStringBounds(
           column, 
           graphics); 
         graphics.drawString(
           column, 
           xColumn, 
           y + fontMetrics.getAscent()); 
         xColumn += columnBounds.getWidth(); 
        } 
        y += fontMetrics.getHeight(); 
       } 
      } 

      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(400, 200); 
      } 
     }; 
     frame.getContentPane().add(panel, BorderLayout.CENTER); 

     frame.pack(); 

     frame.setVisible(true); } 
} 

Realmente parecía Utilities.drawTabbedText() era prometedor, pero no pude averiguar lo que necesitaba como entrada.