Problemen met nieuwe regel in Graphics2D.drawString

g2is een instantie van de klasse Graphics2D. Ik zou graag tekst met meerdere regels kunnen tekenen, maar daarvoor heb ik een teken voor een nieuwe regel nodig. De volgende code wordt in één regel weergegeven.

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

Antwoord 1, autoriteit 100%

De methode drawStringverwerkt geen nieuwe regels.

Je moet de tekenreeks op nieuwe-regeltekens zelf splitsen en de lijnen één voor één tekenen met een juiste verticale offset:

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

Hier is een compleet voorbeeld om u een idee te geven:

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

wat het volgende resultaat geeft:

voer hier de afbeeldingsbeschrijving in


Antwoord 2, autoriteit 14%

Ik heb zojuist een methode gemaakt om automatisch lange tekst te splitsen door de lijndikte op te geven.

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

Antwoord 3

Hier is een fragment dat ik heb gebruikt om tekst te tekenen in een JPanelmet tabuitbreiding en meerdere regels:

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

Het leek echt op Utilities.drawTabbedText()was veelbelovend, maar ik kon er niet achter komen wat het als input nodig had.

Other episodes