Space 使用 .setText 方法时在 JTextPane 文本下

Space under JTextPane text when using .setText method

我正在使用 MigLayout 3.5.5,因为较新的更新与我的旧代码不兼容。

问题

当在 MigLayout 中将文本设置为 JTextPane 时,JTextPane 将占用 space 的两倍(根据字体大小)IF 我设置的文本 JTextPane 包含 space 个字符。它不会一直发生,但在我制作的特定程序中,它经常发生。

该程序的目标是逐个字母地显示信息,因此有一个按钮可以将文本更新为下一个字母。但是,文本会跳来跳去,因为 JTextPane 有时会比平时占据更多 space。我确定了身高差异的某种模式。

模式

换行表示我添加了一个字母。
“|”表示文本中的 space 个字符。
“Space”表示 JTextPane 是 space 的两倍。
完整字符串:“敏捷的棕色狐狸跳过懒惰的狗。”

T


|
|q (Space)
|qu
|qui (Space)
|quic
|快速 (Space)
|快速|

注意:我在这里停止了模式,因为从这一点开始(从 The|quick|b 开始),每个字母的添加都会导致 JTextPane 占据其高度的两倍。

我已经尝试将逐个字母的文本打印到控制台以查看正在添加的文本中是否有任何换行符,但无济于事。我还认为 JTextPane 的自动换行可能有问题,但我插入的文本不够长,无法换行 JFrame 的大小。

这是一个重现该行为的简短示例:

public class MainFrame extends JFrame {

    int currentLetter = 1;
    final String FULL_TEXT = "The quick brown fox jumps over the lazy dog.";
    
    JTextPane text;
    JButton addLetter;
    
    MainFrame() {
        
        setSize(500, 500);
        setLayout(new MigLayout("align center, ins 0, gap 0"));
        addElements();
        
        setVisible(true);
        
    }
    
    public static void main(String[] args) {
        
        SwingUtilities.invokeLater(new Runnable() {
        
            public void run() {
                
                MainFrame application = new MainFrame();
                
            }
            
        });
        
    }
    
    private void addElements() {
        
        text = new JTextPane();
        text.setEditable(false);
        text.setFont(new Font("Times New Roman", Font.BOLD, 19));
        text.setForeground(Color.WHITE);
        text.setBackground(Color.BLACK);
        add(text, "alignx center, wmax 80%, gapbottom 5%");
        
        addLetter = new JButton("Add Letter");
        
        addLetter.addActionListener(new ActionListener() {
        
            public void actionPerformed(ActionEvent e) {
                
                if (currentLetter != FULL_TEXT.length()) {
                    
                    currentLetter++;
                    updateText();
                    
                }
                
            }
        
        });
        
        add(addLetter, "newline, alignx center");
        
        updateText();
        
    }
    
    private void updateText() {
        
        String partialText = new String();
        
        for (int letter = 0; letter < currentLetter; letter++) {
            
            partialText += FULL_TEXT.toCharArray()[letter];
            
        }
        
        text.setText(partialText);

    }

}

为什么我要使用 JTextPane

我尝试使用 JLabel 完成此任务,效果很好...直到文本足够长可以换行。然后,当我在 JLabel 文本中使用 HTML 来包装它时,每次我更新文本时, HTML 都需要时间来渲染并导致一些非常讨厌的视觉效果.

接下来,我尝试 JTextArea 将其伪装成 JLabel,因为它不仅具有换行功能,而且还具有自动换行功能。这是一个很好的解决方案,直到我发现我无法在 JTextArea.

中使用居中段落对齐方式

所以我选择了 JTextPane,如果我去掉底部多余的 space,它会很好用。

在此先感谢您的帮助!

解决方案是通过在 JTextPane 的 StyledDocument 上使用 insertString() 方法来附加文本,而不是在 JTextPane 本身上使用 setText()。

例如,每次都这样做:

JTextPane panel = new JTextPane();
panel.setText(panel.getText() + "test");

你应该这样做:

JTextPane panel = new JTextPane();
StyledDocument document = panel.getStyledDocument();
document.insertString(document.getLength(), "test", null);

当然你需要捕获 BadLocationException。

然后 space 消失了。这是我找到渲染问题答案的问题:JTextPane appending a new string

这些问题的答案没有解决 space 的问题,但它们确实显示了在 JTextPane 中编辑文本的正确方法。