Java 为什么JTextArea和TextLayout包装单词的方式不同?

Java 为什么JTextArea和TextLayout包装单词的方式不同?,java,swing,text,jtextarea,Java,Swing,Text,Jtextarea,我们有一个应用程序可以绘制文本,但是当用户单击文本时,会显示一个JTextArea供用户编辑文本。但是,这两个文本处理组件之间的换行方式不同。它们使用相同的宽度、文本字符串和字体 对于文本绘制,我使用的是Java教程中的,我也看到其他人在这里和其他论坛的相关问题中使用的。这是代码的一部分: FontRenderContext frc = g2d.getFontRenderContext(); TextLayout layout; AttributedString attrString = new

我们有一个应用程序可以绘制文本,但是当用户单击文本时,会显示一个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();
}
我将边框设置为null,因为在文本区域的边界外绘制了另一个矩形,并用虚线区域显示其位置。现在可能看起来很傻,但是当用户第一次选择要编辑的文本时,我们使用它来显示文本区域的边界。此时,JTextArea尚未创建。他们必须再次点击它才能开始编辑。这样做的原因是,一旦选择了文本区域,他们也可能会拖动并调整文本区域的大小,如果他们在开始拖动和调整大小时有一个活动的JTextArea,那么这会变得混乱和混乱


另外,绘制的TextLayouts和JTextArea似乎都可以很好地包装单词。但是当一起使用时,你可以看到区别。问题是,当用户编辑文本时,JTextArea会自动包装文本。但是,当用户JTextArea失去焦点时,它将转换为绘制的文本,然后单词可能会以不同的方式包装。

i
l
字符填充文本区域。抓取一个UI标尺或放大镜,从最长行的最左侧字符到最右侧,以像素为单位计算文本区域的大小。对
n
m
和其他几个字符执行相同的操作,以获得更多的数据点。我怀疑文本区域有几个像素的不可见边框,即使设置为“无边框”,它也会使用这些像素。如果是这种情况,请在TextLayout组件周围添加相同的边框,它们应该看起来相同


(除了计算像素外,您还可以为文本或组件设置背景色,但我不一定相信它。)

谢谢您的回复。我设计了一个SSCCE,当它最终完成时,JTextArea和TextLayout将文本包装成相同的形式。这使我重新审视了原始代码,在这样做的过程中,我发现在JTextArea上不必要地使用了setSize()和setBounds()。一旦我把它清理干净,它就工作得很好。
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);