1

虽然有相当多的空闲时间可以使用,但我遇到了一个关于作为 JTextPane 一部分的 StyledDocument 的问题。当文档的总大小达到 x 值(在我的情况下为 10.000)时,我想删除文本的第一部分。但是由于保留布局很重要,让我先向您展示图像中发生的情况,然后我将发布源代码。

在图 1 中:当尚未达到最大长度时,我没有水平滚动条

在图 2 中:当达到 10.000 个字符的最大长度时,使用 styleddoc.getDocument().remove(0, maxsize) 裁剪 StyledDocument;

http://i.stack.imgur.com/i10KZ.png [图 1]

http://i.stack.imgur.com/dUZ0K.png [图 2]

(非常抱歉,因为这是我在这里的第一个问题,所以我不允许发布图片作为垃圾邮件拒绝措施)

如您所见,horizo​​ntar 滚动条突然出现,我的布局完全混乱,并且在任何情况下,文本不适合时会整齐地分成几行,就像它在删除之前所做的那样。

现在,这是我的来源。请帮助我找到解决此问题的天才解决方案。

public void publicTextPaneOutput(String sender, String receiver, int type, String message) {
    int messagesize = 0;
    StyledDocument styledDocument = (StyledDocument) publicText.getDocument();
    Style defaultStyle = styledDocument.addStyle("Default Text", null);
    Style nicknameStyle = styledDocument.addStyle("Personal Nickname", null);
    StyleConstants.setBold(nicknameStyle, true);
    StyleConstants.setForeground(nicknameStyle, Color.decode("#006400"));
    Style chatterStyle = styledDocument.addStyle("Other Nickname", null);
    StyleConstants.setBold(chatterStyle, true);
    StyleConstants.setForeground(chatterStyle, Color.blue);

    switch (type) {
        case 1: {
            messagesize += sender.length() + message.length() + 3;
            publicTextPaneOverflowProtection(styledDocument, messagesize);
            try {
                if (sender.equals(nickname)) {
                    styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(sender).toString(), nicknameStyle);
                } else {
                    styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(sender).toString(), chatterStyle);
                }
                styledDocument.insertString(styledDocument.getLength(), ": ", chatterStyle);
                styledDocument.insertString(styledDocument.getLength(), message, defaultStyle);
                styledDocument.insertString(styledDocument.getLength(), "\n", defaultStyle);
            } catch (BadLocationException e) {
                e.printStackTrace();
            }
            break;
        }
        case 2: {
            messagesize += sender.length() + receiver.length() + message.length() + 7;
            publicTextPaneOverflowProtection(styledDocument, messagesize);
            try {
                if (sender.equals(nickname)) {
                    styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(sender).toString(), nicknameStyle);
                } else {
                    styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(sender).toString(), chatterStyle);
                }
                styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(" -> ").toString(), chatterStyle);
                if (receiver.equals(nickname)) {
                    styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(receiver).toString(), nicknameStyle);
                } else {
                    styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(receiver).toString(), chatterStyle);
                }
                styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(": ").toString(), chatterStyle);
                styledDocument.insertString(styledDocument.getLength(), message, defaultStyle);
                styledDocument.insertString(styledDocument.getLength(), "\n", defaultStyle);

            } catch (BadLocationException e) {
                e.printStackTrace();
            }
            break;
        }
    }
    scroll();
}

private void publicTextPaneOverflowProtection (StyledDocument styledDocument, int messagesize)
{
    if(styledDocument.getLength() + messagesize > 10000) {
        try {
            styledDocument.remove(0, messagesize);
        } catch (BadLocationException e) {

        }
    }

}

public void scroll() {
    StyledDocument styleddocument = (StyledDocument) publicText.getDocument();
    publicText.setCaretPosition(styleddocument.getLength());
}

// this part is coded in the class itself

private JTextPane publicText;
private JScrollPane publicTextScrollPane;

//this is coded in the constructor of the class
publicText = new JTextPane();
publicTextScrollPane = new JScrollPane();

publicText.setEditable(false);
publicTextScrollPane.setViewportView(publicText);

如果有人需要我项目某个部分的附加代码,请尽快告诉我

我想要的解决方案应该在 StyledDocument 的开头实现这种文本的删除,并将放置的 \n 字符保留在帐户中,即使是部分被删除。我已经尝试了几件事,甚至只使用普通的“文档”而不是样式化的,但这不是选择,因为我计划在我的聊天小程序中实现颜色和表情符号的使用。

事先感谢每一个人对此进行调查!我会尽可能跟进。

亲切的问候, 史蒂文库斯特斯

PS.:为什么我要删除 StyledDocument 的一部分?内存管理,因为这是一个聊天小程序的一部分,最多可以同时供 200 人使用,当每个人每 10 秒说一句话时,一分钟后你有 1200 条消息,这将占用大量内存这持续了 10 个小时:估计最大负载为 720.000 条消息。(最坏情况(或最好情况,取决于观点))

4

1 回答 1

1

您的问题有很多不同的部分,但其中一部分可能很容易解决。听起来您主要关心的是如何从文档中删除行。有人已经实现了一个 DocumentListener 来为您处理这方面的问题。查看LimitLinesDocumentListener。该页面链接到该类的源代码,其中还包含有关如何从文档中删除行的示例。

于 2013-09-26T18:00:34.390 回答