1

当由 HTMLEditorKit 支持的 JEditorPane 包含一个<br>标记后跟一个空行时,该行不会正确呈现,并且插入符号也不会正确处理。考虑这个示例代码:

import java.awt.*;
import java.io.*;

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;

public class HTMLEditorTest {

    public static void main(String[] args) throws IOException, BadLocationException {
        JFrame frame = new JFrame();

        Reader stringReader = new StringReader("test<br><p>a");
        HTMLEditorKit htmlKit = new HTMLEditorKit();
        HTMLDocument htmlDoc = (HTMLDocument) htmlKit.createDefaultDocument();
        htmlKit.read(stringReader, htmlDoc, 0);
        JEditorPane editorPane = new JEditorPane();
        editorPane.setEditorKit(htmlKit);
        editorPane.setDocument(htmlDoc);

        frame.getContentPane().add(BorderLayout.CENTER, new JScrollPane(editorPane));
        frame.setBounds(100, 100, 500, 400);
        frame.setVisible(true);
    }
}

<br>标签后的空行不会被渲染。当插入符号位于“a”字符的左侧并按下向上箭头键时,插入符号消失:

在按下“向上”之前:

在此处输入图像描述

按“向上”后:

按“向上”后

请注意,“test”和“a”之间的距离太小,插入符号消失了。

然后,当您输入文本时,丢失的空行变得可见:

按'b'后

问题似乎是空行以 0px 的高度呈现,因此不可见,包括插入符号(如果它位于该行)。一旦该行具有内容,该内容就会强制行高为非零。

您知道此问题的简单解决方法/解决方法吗?我认为在最坏的情况下,我必须编写自己的编辑器工具包(另请参阅此处此处了解 JEditorPane 中的自定义换行)和/或自定义标签(也请参阅此处)。

4

1 回答 1

2

使用自定义编辑器工具包找到了解决方案:

public class MyEditorKit extends HTMLEditorKit {

    private static final int MIN_HEIGHT_VIEWS = 10;

    @Override
    public ViewFactory getViewFactory() {

        return new HTMLFactory() {

            @Override
            public View create(Element e) {
                View v = super.create(e);
                // Test for BRView must use String comparison, as the class is package-visible and not available to us
                if ((v instanceof InlineView) && !v.getClass().getSimpleName().equals("BRView")) {

                    View v2 = new InlineView(e) {

                        @Override
                        public float getMaximumSpan(int axis) {
                            float result = super.getMaximumSpan(axis);
                            if (axis == Y_AXIS) {
                                result = Math.max(result, MIN_HEIGHT_VIEWS);
                            }
                            return result;
                        }

                        @Override
                        public float getMinimumSpan(int axis) {
                            float result = super.getMinimumSpan(axis);
                            if (axis == Y_AXIS) {
                                result = Math.max(result, MIN_HEIGHT_VIEWS);
                            }
                            return result;
                        }

                        @Override
                        public float getPreferredSpan(int axis) {
                            float result = super.getPreferredSpan(axis);
                            if (axis == Y_AXIS) {
                                result= Math.max(result, MIN_HEIGHT_VIEWS);
                            }

                            return result;
                        }
                    };

                    v = v2;
                }

                return v;
            }
        };
    }
}

编辑器工具包返回一个自定义 HTMLFactory。该工厂为叶元素创建自定义 InlineView 对象,其中 InlineView 的高度不能为 0。它总是至少有一个 MIN_HEIGHT_VIEW,我将其设置为 10 像素(在默认字体大小下工作得相当好)。最初的实现在渲染 HTML 以供查看时是有意义的,因为<br>确实应该忽略标记后的空行。但是对于编辑,用户会希望在插入换行符后在下一行看到插入符号。

于 2016-10-19T11:06:49.440 回答