2010-12-10 18 views
41

g2 jest instancją klasy Graphics2D. Chciałbym móc narysować tekst wielowierszowy, ale wymaga to znaku nowej linii. Poniższy kod renderuje się w jednym wierszu.Problemy z nową linią w Graphics2D.drawString

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

Odpowiedz

69

Metoda drawString nie obsługuje nowych linii.

Musisz podzielić ciąg na new-line znaków siebie i narysować linie, jeden po drugim z odpowiednim przesunięciem pionowym:

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

Powyżej znajduje się pełna przykład aby dać Ci pomysł:

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); 
    } 
} 

co daje następujący wynik:

enter image description here

+6

+1 - wyczerpująca odpowiedź –

+0

Niestandardowe malowanie odbywa się poprzez przesłonięcie metody paintComponent() i powinieneś najpierw wywołać super.paintComponent (g). – camickr

+0

Dobra uwaga. Zaktualizowano. – aioobe

7

Właśnie stworzyłem metodę automatycznego rozciągania długich tekstów, podając szerokość linii.

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

To zadziałało znakomicie !! –

0

Oto fragment kiedyś narysować tekst w JPanel z ekspansji zakładki i wielu wierszach:

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); } 
} 

To naprawdę wydawało się Utilities.drawTabbedText() był obiecujący, ale nie mogłem dowiedzieć się, co to potrzebne jako wejście.

Powiązane problemy