2011-04-04 66 views
0

我们有一个绘制文本的应用程序,但随后显示一个JTextArea供用户在点击文本时编辑文本。但是,这两个文本处理组件之间的包装不同。它们使用相同的宽度,文本字符串和字体。为什么JTextArea和TextLayout以不同的方式包装单词?

对于文本绘图,我使用的是Java教程,我也在其他论坛上看到过其他人在相关问题中使用过的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失去焦点时,会将其转换为绘制的文本,然后可能会用不同的方式包装这些文字。

+0

感谢您的回复。我编写了一个SSCCE,当它最终完成时,JTextArea和TextLayout将文本包装成相同的文本。这导致我再次看看原始代码,并在这样做的过程中发现了JTextArea上setSize()和setBounds()的不必要用法。一旦我清理它,它工作得很好。 – user26270 2011-04-05 18:39:23

回答

0

il字符填充文本区域。抓住用户界面标尺或放大镜,并从最长行最左边的字符到最右边的像素,计算文本区域的大小。对n,m以及其他几个字符进行相同的处理以获得更多的数据点。我怀疑,即使设置为无边框,文本区域也会使用几个像素的不可见边框。如果是这种情况,在TextLayout组件周围添加相同的边框,它们应该看起来相同。

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

相关问题