Nhờ gợi ý của Epaga và một vài ví dụ trên mạng (không quá rõ ràng để tìm! Tôi đã sử dụng chủ yếu là Break a Line for text layout), tôi có thể tạo thành phần để hiển thị văn bản được bao bọc. Nó không đầy đủ, nhưng ít nhất nó cho thấy hiệu quả dự định.
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();
}
}
}
Chỉ cần cho vui, tôi đã làm cho nó phù hợp một vòng tròn (than ôi, không thể biện minh, có vẻ như):
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();
}
}
Tôi không quá chắc chắn về tính dx, mặc dù.
Tôi đã nhận được tài khoản đó. Vấn đề của tôi là, tôi không muốn một hình chữ nhật xung quanh văn bản, nhưng văn bản bên trong một hình chữ nhật đã cho. – Burkhard
Lưu ý rằng hàm tạo của TextLayout, không có giấy tờ, ném một ngoại lệ nếu chuỗi bạn vượt qua trống. –
Sử dụng \t Hình dạng labelShape = textLayout1.getOutline (null); và sau đó g2d.fill (labelShape); họ nên loại bỏ biên giới – mk7