How to output a line on multiple lines using Graphics

My program overrides public void paint(Graphics g, int x, int y); to draw some sting using g.drawString(someString, x+10, y+30);

Now someString can be quite long and therefore may not match a single line.

What is the best way to write text on multiple lines.
For example, in the rectangle (x1, y1, x2, y2)?

+11
java string graphics
Oct 27 '08 at 10:42
source share
5 answers

Thanks to the Epaga hint and a few examples on the Web (not so obvious to find! I used mainly Line Break for text layout ), I could make a component to display wrapped text. It is incomplete, but at least it shows the intended effect.

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

Just for fun, I made it a suitable circle (alas, there is no excuse, it seems):

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

I am not too sure about the calculation of dx.

+9
Oct 27 '08 at 12:44
source share

java.awt.font.TextLayout may be useful. Here is a snippet of their sample code:

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

Otherwise, you can always use the Swing text element to complete the task for you, just go to the Graphics that you want it to be written.

+3
Oct 27 '08 at 10:44
source share

Build your line one word at a time using the Epaga method to find the length of your line. Once the length is longer than your rectangle, delete the last word and print. Repeat until you finish the words.

This sounds like a bad algorithm, but for each line it really is O (screenWidth / averageCharacterWidth) => O (1).

However, use a StringBuffer to create your string!

+1
Oct 27 '08 at 11:26
source share

I had some kind of problem: this is my solution:

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

Hope this helps ... simple, but it works.

+1
May 31 '12 at
source share

You can use JLabel and embed text using html.

 JLabel.setText("<html>"+line1+"<br>"+line2); 
0
Oct 27 '08 at 12:53
source share



All Articles