如何在java Graphics2d中使用TextLayout对短字符串进行自动换行?

时间:2015-01-09 13:58:54

标签: java bufferedimage graphics2d textwrapping

你如何在Java下用TextLayout对下面的短标签字符串进行自动换行?

我的标签只有两三个字 一些例子: 1.充气温室D10; 2.指挥控制中心A5; 杰森鲍里斯;

我想把这些单词包装成尽可能形状像正方形,而不是一个长矩形。

所以我的问题是:将建筑物名称包裹到第二行而不是一条长线需要什么?见下图:

overlapping names

有没有办法设置一行文本中包含的最大字符数,并将剩余的字符包装到第二行等等(它需要考虑空格)?

例如,我想把名称“Residential Quarter D12”改为三行。

  Residential
   Quarter
     D12

并将“命令和控制D16”包装成四行。

 Command 
   and
 Control
   D16

如果TextLayout可以理解像普通JLabel这样的html代码,那会不会很好!?然后它会让事情变得简单:

       String label = "<html>" + "Inflatable" + "<br>" + "Greenhouse"  + "<br>" + "D10" + "</html>";

注意:每行不必一个字。但我想让它们在每一行“居中”

我所拥有的是以下方法,用于生成建筑物名称标签的BufferedImage或仅仅是人的名字和姓氏。

    private BufferedImage createLabelImage(
    String label, Font font, FontRenderContext fontRenderContext, Color labelColor, 
    Color labelOutlineColor) {

    // Determine bounds.
    TextLayout textLayout1 = new TextLayout(label, font, fontRenderContext);
    Rectangle2D bounds1 = textLayout1.getBounds();

    // Get label shape.
    Shape labelShape = textLayout1.getOutline(null);

    // Create buffered image for label.
    int width = (int) (bounds1.getWidth() + bounds1.getX()) + 4;
    int height = (int) (bounds1.getHeight()) + 4;
    BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

    // Get graphics context from buffered image.
    Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics();
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.translate(2D - bounds1.getX(), 2D - bounds1.getY());

    // Draw label outline.
    Stroke saveStroke = g2d.getStroke();
    g2d.setColor(labelOutlineColor);
    g2d.setStroke(new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    g2d.draw(labelShape);
    g2d.setStroke(saveStroke);

    // Fill label
    g2d.setColor(labelColor);
    g2d.fill(labelShape);

    // Dispose of image graphics context.
    g2d.dispose();

    return bufferedImage;
}

如您所见,此方法只能使用一行文本创建标签的BufferedImage形式。

当我在地图上叠加这些BufferedImage标签时,它们看起来太长而且彼此重叠。

这就是为什么我需要让每个标签尽可能像正方形一样。

1 个答案:

答案 0 :(得分:1)

让我试着提出一个算法。

按空格分割标签以获取单词列表并测量每个单词以获取数组

int[] wordWidths;
int minWidth=max(wordWidths);
int height=the row height const;
int minHeight=height;
int maxHeight=wordWidths.length*height;

int currentWidth=minWidht;
int currentHeight=maxHeight;

while(currentWidth<currentHeight || wordWidths.length>1) {
  int mergedWidth=find minimal sum of neighbour words' widths
  replace the 2 widths with the mergedWidth reducing the wordWidthssize
  currentHeight=wordWidths.length*height;
}

或者您可以尝试依赖组件。我将定义一个JTextArea实例,在那里分配标签并尝试使用包裹减少宽度1乘1并测量宽度的首选高度。 获得最佳尺寸后,您可以致电theWrappedJtextArea.printAll(g)将其绘制在BufferedImage's Graphics上。