java - LineBreakMeasurer 生成的结果与 MS Word/LibreOffice 不同

标签 java swing line-breaks word-wrap libreoffice

在 swing 应用程序中,我需要预见字符串的文本换行,就像将其放入 MS Word 或 LibreOffice 等文字处理程序中一样。提供相同的显示区域宽度、相同的字体(字体和大小)和相同的字符串,如下所示:

  • 可显示区域宽度:179毫米(在.doc文件中,设置A4纵向页面 - 宽度= 210毫米,左边距= 20毫米,右= 11毫米;段落格式为零边距)
  • 字体 Times New Roman,尺寸 14
  • 测试字符串:Tadf fdas fdas daebjnbvx dasf opqwe dsa: dfa fdsa ewqnbcmv caqw vstrt vsip d asfd eacc

结果:

  • 在 MS Word 和 LibreOffice 上,该测试字符串都显示在单行上,不会发生文本换行。
  • 我的以下程序报告发生文本换行,2 行

    第 1 行:Tadf fdas fdas daebjnbvx dasf opqwe dsa: dfa fdsa ewqnbcmv caqw vstrt vsip d asfd

    第 2 行:eacc

是否可以在swing中实现像MS Word一样的文字换行效果?代码中可能有什么问题?

下面是我的程序

public static List<String> wrapText(String text, float maxWidth,
        Graphics2D g, Font displayFont) {
    // Normalize the graphics context so that 1 point is exactly
    // 1/72 inch and thus fonts will display at the correct sizes:
    GraphicsConfiguration gc = g.getDeviceConfiguration();
    g.transform(gc.getNormalizingTransform());

    AttributedCharacterIterator paragraph = new AttributedString(text).getIterator();
    Font backupFont = g.getFont();
    g.setFont(displayFont);
    LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(
            paragraph, BreakIterator.getWordInstance(), g.getFontRenderContext());
    // Set position to the index of the first character in the paragraph.
    lineMeasurer.setPosition(paragraph.getBeginIndex());

    List<String> lines = new ArrayList<String>();
    int beginIndex = 0;
    // Get lines until the entire paragraph has been displayed.
    while (lineMeasurer.getPosition() < paragraph.getEndIndex()) {
        lineMeasurer.nextLayout(maxWidth);
        lines.add(text.substring(beginIndex, lineMeasurer.getPosition()));
        beginIndex = lineMeasurer.getPosition();
    }

    g.setFont(backupFont);
    return lines;
}

public static void main(String[] args) throws Exception {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JTextPane txtp = new JTextPane();
    frame.add(txtp);
    frame.setSize(200,200);
    frame.setVisible(true);
    Font displayFont = new Font("Times New Roman", Font.PLAIN, 14);

    float textWith = (179 * 0.0393701f) // from Millimeter to Inch
                        * 72f;           // From Inch to Pixel (User space)
    List<String> lines = wrapText(
            "Tadf fdas fdas daebjnbvx dasf opqwe dsa: dfa fdsa ewqnbcmv caqw vstrt vsip d asfd eacc",
            textWith,
            (Graphics2D) txtp.getGraphics(),
            displayFont);
    for (int i = 0; i < lines.size(); i++) {
        System.out.print("Line " + (i + 1) + ": ");
        System.out.println(lines.get(i));
    }
    frame.dispose();
}

最佳答案

问题+1

根据我使用文本编辑器的经验,不可能实现完全相同的测量。

您可以尝试使用 DPI,Windows 上默认 DPI=72 和 96。

您还可以尝试使用图形的所有渲染提示 - 文本抗锯齿等。

关于java - LineBreakMeasurer 生成的结果与 MS Word/LibreOffice 不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15698821/

相关文章:

java - 为什么我的下载进度条会多次触发同一个事件?

java - 在用户按下 [x] 后窗口关闭之前做一些事情

Javascript - 在变量中添加换行符

mysql - 在 HTML 中显示 mysql 换行符

java - 从 JTextArea 中删除边框

java - Android 是否支持短路?

java - Amazon CLI 并行部署

java - 如何计算一组字符串的最短唯一前缀?

css - IE 中页脚后的换行符或其他内容

java - 如何将枚举值转换为int?