如何为其模型中文本的不同代码点自定义 Java 9+ JTextField 的视图?

How to customize the View of Java 9+ JTextField for different code-point of the text in its Model?

所有 Java Swing 组件都使用 MVC,每个组件都有一个 ControllerModel查看。特别是,JTextField 使用 PlainDocument 作为其模型来获取数据,并使用 TextUI 作为其视图来呈现数据。 Java文档中的 link:JavaDoc JTextComponents MVC .
通常 JTextField 的数据是 text 并且对于文本的每个字符,Java 使用 code-point 和名为 GlyphView 的东西将呈现它们以查看 JtextField 的文本。有一些字符被称为 non-printable(如 Unicode 中的 \u0000)并且 JTextField 不会呈现他们。
我尝试使用 PlainDocument 更改模型,使用 StringreplaceAll() 方法将文本字符串中的不可打印字符替换为可打印字符:

protected class TextModel extends PlainDocument
{

    TextModel()
    {}

    @Override
    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException
    {
        str = str.replaceAll("\u0000", "\ufffd");
        super.insertString(offs, str, a);
    }

}

但我不想对字符串进行任何处理或对模型进行任何更改。如何更改 JTextField 的视图以呈现不可打印的字符?

如我所说,我尝试使用 PlainDocument 更改模型,使用 StringreplaceAll() 方法将文本字符串中的 non-printable 字符替换为可打印字符.这种方法的第一部分是正确的,我们必须扩展 PlainDocument 但我没有覆盖 insertString() 方法,而是使用 getText(int offset, int length, Segment txt) 方法来覆盖它。
此方法获取文档给定部分中包含的文本,该部分从 offset 开始并具有指定的 lengthSegment 有一个数组,起着重要的作用。所需的更改必须应用于 Segment。使用共享双缓冲区,我可以将任何不可打印字符映射到 JTextField 中的可打印字符而不更改其数据,如下所示:

@Override
    public void getText(int offset, int length, Segment txt) throws BadLocationException
    {
        super.getText(offset, length, txt);

        System.arraycopy(txt.array, txt.offset, sharedDoubleBuffer.array, sharedDoubleBuffer.offset, sharedDoubleBuffer.count);
         // map nonprintable characters 
        charMappingLogic(sharedDoubleBuffer);
        // set contents of the supplied buffer to that of our modified shared double-buffer
        txt.array = sharedDoubleBuffer.array;
    }