我的计划会覆盖public void paint(Graphics g, int x, int y);
,以便使用g.drawString(someString, x+10, y+30);
现在someString可能很长,因此,它可能不适合一行。
在多行上写文本的最佳方法是什么。
例如,在一个矩形(x1,y1,x2,y2)中?
答案 0 :(得分:9)
感谢Epaga的提示以及网上的几个例子(不是那么明显!我主要使用Break a Line for text layout),我可以创建一个组件来显示包装文本。它不完整,但至少它显示了预期的效果。
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计算不太了解。
答案 1 :(得分:3)
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文本元素为您完成工作,只需传入您想要绘制的图形。
答案 2 :(得分:1)
使用Epaga的方法逐步增加字符串,一次一个字,以查找字符串的长度。一旦长度超过矩形,删除最后一个单词并打印。重复,直到你用完了。
这听起来像一个糟糕的算法,但对于每一行,它实际上是O(screenWidth / averageCharacterWidth)=&gt; O(1)。
仍然,使用StringBuffer来构建你的字符串!
答案 3 :(得分:1)
自己有些麻烦这是我的解决方案:
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));
希望有所帮助......简单但有效。
答案 4 :(得分:0)
您可以使用JLabel并使用html嵌入文本。
JLabel.setText("<html>"+line1+"<br>"+line2);