Как вывести строку в несколько строк, используя графику - PullRequest
11 голосов
/ 27 октября 2008

Моя программа переопределяет public void paint(Graphics g, int x, int y);, чтобы нарисовать несколько строк, используя g.drawString(someString, x+10, y+30);

Теперь someString может быть довольно длинной и, следовательно, может не помещаться на одной строке.

Как лучше всего написать текст в несколько строк.
Например, в прямоугольнике (x1, y1, x2, y2)?

Ответы [ 5 ]

9 голосов
/ 27 октября 2008

Благодаря подсказке Epaga и паре примеров в сети (не так очевидно, чтобы найти! Я использовал в основном Разрыв строки для размещения текста ), я мог создать компонент для отображения переносимого текста. Он неполный, но, по крайней мере, показывает ожидаемый эффект.

class TextContainer extends JPanel
{
    private int m_width;
    private int m_height;
    private String m_text;
    private AttributedCharacterIterator m_iterator;
    private int m_start;
    private int m_end;

    public TextContainer(String text, int width, int height)
    {
        m_text = text;
        m_width = width;
        m_height = height;

        AttributedString styledText = new AttributedString(text);
        m_iterator = styledText.getIterator();
        m_start = m_iterator.getBeginIndex();
        m_end = m_iterator.getEndIndex();
    }

    public String getText()
    {
        return m_text;
    }

    public Dimension getPreferredSize()
    {
        return new Dimension(m_width, m_height);
    }

    public void paint(Graphics g)
    {
        super.paintComponent(g);

        Graphics2D g2 = (Graphics2D) g;
        FontRenderContext frc = g2.getFontRenderContext();

        LineBreakMeasurer measurer = new LineBreakMeasurer(m_iterator, frc);
        measurer.setPosition(m_start);

        float x = 0, y = 0;
        while (measurer.getPosition() < m_end)
        {
            TextLayout layout = measurer.nextLayout(m_width);

            y += layout.getAscent();
            float dx = layout.isLeftToRight() ?
                    0 : m_width - layout.getAdvance();

            layout.draw(g2, x + dx, y);
            y += layout.getDescent() + layout.getLeading();
        }
    }
}

Просто для забавы, я сделал это в форме круга (увы, нет оправдания, кажется):

public void paint(Graphics g)
{
    super.paintComponent(g);

    Graphics2D g2 = (Graphics2D) g;
    FontRenderContext frc = g2.getFontRenderContext();

    LineBreakMeasurer measurer = new LineBreakMeasurer(m_iterator, frc);
    measurer.setPosition(m_start);

    float y = 0;
    while (measurer.getPosition() < m_end)
    {
        double ix = Math.sqrt((m_width / 2 - y) * y);
        float x = m_width / 2.0F - (float) ix;
        int width = (int) ix * 2;

        TextLayout layout = measurer.nextLayout(width);

        y += layout.getAscent();
        float dx = layout.isLeftToRight() ?
                0 : width - layout.getAdvance();

        layout.draw(g2, x + dx, y);
        y += layout.getDescent() + layout.getLeading();
    }
}

Я не слишком уверен насчет вычисления dx.

3 голосов
/ 27 октября 2008

java.awt.font.TextLayout может быть полезным. Вот фрагмент их примера кода:

   Graphics2D g = ...;
   Point2D loc = ...;
   Font font = Font.getFont("Helvetica-bold-italic");
   FontRenderContext frc = g.getFontRenderContext();
   TextLayout layout = new TextLayout("This is a string", font, frc);
   layout.draw(g, (float)loc.getX(), (float)loc.getY());

   Rectangle2D bounds = layout.getBounds();
   bounds.setRect(bounds.getX()+loc.getX(),
                  bounds.getY()+loc.getY(),
                  bounds.getWidth(),
                  bounds.getHeight());
   g.draw(bounds);

В противном случае вы всегда можете использовать текстовый элемент Swing, чтобы выполнить работу за вас, просто передайте графику, в которую вы хотите его закрасить.

1 голос
/ 31 мая 2012

У меня были проблемы, вот мое решение:

Graphics2D g=....
FontRenderContext frc = g.getFontRenderContext();
TextLayout layout = new TextLayout(text, font, frc);
String[] outputs = text.split("\n");
for(int i=0; i<outputs.length; i++){
    g.drawString(outputs[i], 15,(int) (15+i*layout.getBounds().getHeight()+0.5));

Надеюсь, это поможет .... просто, но это работает.

1 голос
/ 27 октября 2008

Постепенно строите вашу строку, по одному слову за раз, используя метод Epaga, чтобы найти длину вашей строки. Как только длина станет больше вашего прямоугольника, удалите последнее слово и напечатайте. Повторяйте, пока не закончатся слова.

Звучит как плохой алгоритм, но для каждой строки это действительно O (screenWidth / averageCharacterWidth) => O (1).

Тем не менее, используйте StringBuffer для построения вашей строки!

0 голосов
/ 27 октября 2008

Вы можете использовать JLabel и встраивать текст в HTML.

JLabel.setText("<html>"+line1+"<br>"+line2);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...