我们有一个绘制文本的应用程序,然后显示一个 JTextArea 供用户在单击文本时编辑文本。但是,这两个文本处理组件之间的包装不同。它们使用相同的宽度、文本字符串和字体。
对于文本绘图,我使用的是 Java 教程中的,我在这里和其他论坛的相关问题中也看到其他人使用过。这是代码的那一部分:
FontRenderContext frc = g2d.getFontRenderContext();
TextLayout layout;
AttributedString attrString = new AttributedString(myText);
AttributedCharacterIterator charIterator;
int paragraphStart;
int paragraphEnd;
LineBreakMeasurer lineMeasurer;
float breakWidth;
float drawPosX;
float drawPosY;
attrString.addAttribute(TextAttribute.FONT, myFont);
charIterator = attrString.getIterator();
paragraphStart = charIterator.getBeginIndex();
paragraphEnd = charIterator.getEndIndex();
lineMeasurer = new LineBreakMeasurer(charIterator, frc);
// Set break width to width of Component.
breakWidth = myTextWidth;
drawPosY = startY
// Set position to the index of the first character in the paragraph.
lineMeasurer.setPosition(paragraphStart);
textBounds = new Rectangle(startX, startY(), 0, 0);
// Get lines from until the entire paragraph has been displayed.
while (lineMeasurer.getPosition() < paragraphEnd) {
layout = lineMeasurer.nextLayout(breakWidth);
// Compute pen x position. If the paragraph is right-to-left we
// will align the TextLayouts to the right edge of the panel.
drawPosX = layout.isLeftToRight()
? startX() : breakWidth - layout.getAdvance();
// Draw the TextLayout at (drawPosX, drawPosY).
layout.draw(g2d, drawPosX, drawPosY);
lineBounds = new Rectangle2D.Float(drawPosX, drawPosY - layout.getAscent(), layout.getAdvance(), (layout.getAscent() + layout.getDescent() + layout.getLeading()));
// Move y-coordinate in preparation for next layout.
drawPosY += layout.getAscent() + layout.getDescent() + layout.getLeading();
}
JTextArea 要简单得多:
JTextArea textArea = new JTextArea(myText);
textArea.setSize(myTextWidth, myTextThing.getHeight());
textArea.setOpaque(true);
textArea.setVisible(true);
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
textArea.setFont(myFont);
textArea.setBorder(null);
我将边框设置为空,因为我在文本区域的边界之外绘制了另一个矩形,并用虚线区域显示它的位置。现在可能看起来很傻,但是当用户第一次选择他们想要编辑的文本时,我们使用它来显示文本区域的边界。此时,尚未创建 JTextArea。他们必须再次单击它才能开始编辑。这样做的原因是,一旦选择了文本区域,他们也可能会拖动文本区域并调整其大小,如果他们在开始拖动和调整大小时有一个活动的 JTextArea,那会变得混乱和更加混乱。
另外,绘制的 TextLayouts 和 JTextArea 似乎都可以很好地换行。但是当一起使用时,您可以看到不同之处。这样做的问题是,当用户编辑文本时,JTextArea 正在做它的事情来包装文本。但是当用户 JTextArea 失去焦点时,它会被转换为绘制的文本,然后单词可能会被不同地换行。