繁体   English   中英

如何限制JTextArea中的行数?

[英]How to Limit number of lines in JTextArea?

我正在尝试为服务创建一个GUI,它具有一个JTextArea来查看消息,每条消息都写在一行上,并在需要时进行wordwrapped。

消息通过套接字到达,所以它只是我用来更新JTextArea的.append(消息),我需要将这些行限制为50或100,我不需要限制每行的字符数。

如果有一种方法来限制JTextArea中的数字行,或者有另一种方法可以做到这一点?

我真的可以在这件事上使用援助。

编辑

问题是每个客户端都可以发送无限行,所有这些行都必须是可读的,所以这不是对JTextArea中行数的简单检查。 我需要删除旧行才能查看更新的行。

使用来获取行和列

添加一个DocumentFilter来检查行数(传递doc.getLength()偏移量)并阻止添加更多文本。

或者您可以创建一个虚拟的不可见JTextArea并在那里添加所有文本。 然后测量最后允许的行并剪切文本。

下面是一个原始的DocumentFilter似乎工作。 它的基本方法是让插入/追加发生,查询事后的行数,如果越多,则从适当的开始删除行。

注意:使用textArea方法计算的行(很可能是等待来自@Stani的确认)line-between-cr,而不是实际行的布局。 根据您的具体要求,他们可能会或可能不会为您提供服务(如果没有,请使用Stan的实用方法)

我很惊讶,并不完全确定它是否安全

  • 惊讶:没有调用insert方法,需要实现替换方法(在生产就绪代码中可能两者都有)
  • 不确定textArea是否保证在过滤器方法中返回最新值(可能不是,那么长度检查可以包装在invokeLater中)

一些代码:

public class MyDocumentFilter extends DocumentFilter {

    private JTextArea area;
    private int max;

    public MyDocumentFilter(JTextArea area, int max) {
        this.area = area;
        this.max = max;
    }

    @Override
    public void replace(FilterBypass fb, int offset, int length,
            String text, AttributeSet attrs) throws BadLocationException {
        super.replace(fb, offset, length, text, attrs);
        int lines = area.getLineCount();
        if (lines > max) {
            int linesToRemove = lines - max -1;
            int lengthToRemove = area.getLineStartOffset(linesToRemove);
            remove(fb, 0, lengthToRemove);
        }
    }
}

// usage
JTextArea area = new JTextArea(10, 10);
((AbstractDocument) area.getDocument()).setDocumentFilter(new MyDocumentFilter(area, 3));

这会更有效吗?

final int SCROLL_BUFFER_SIZE = 100;
public void trunkTextArea(JTextArea txtWin)
{
    int numLinesToTrunk = txtWin.getLineCount() - SCROLL_BUFFER_SIZE;
    if(numLinesToTrunk > 0)
    {
        try
        {
            int posOfLastLineToTrunk = txtWin.getLineEndOffset(numLinesToTrunk - 1);
            txtWin.replaceRange("",0,posOfLastLineToTrunk);
        }
        catch (BadLocationException ex) {
            ex.printStackTrace();
        }
    }
}

我的方法使用JTextPane的内容作为文档。 它假定您的程序一直在文档的末尾附加文本,因此当您调用doc.getCharacterElement(1)时,您将基本上获得表示最早代码行的叶元素。 这是我们想要删除的内容,因此我们得到该元素的开始和结束偏移量,并调用remove方法来删除最早的文本。

这可以通过检查字符总数是否大于一百万(如下所述)或基于您已添加的行数来有选择地执行。

如果您希望将其基于已添加的行数,则每次打印到JTextPane时都需要一个递增的字段,以便每次打印新的文本行时该代码都会运行一次并且计数超过您的最大值。

        JTextPane pane = ...
        StyledDocument doc = pane.getStyledDocument();
        int size = doc.getLength();
        if (size > 1000000) {
            out.println("Size: " + size);
            out.println(":" + 1);
            int i = 0;
            Element e = doc.getCharacterElement(i + 1);
            int start = e.getStartOffset();
            int end = e.getEndOffset();

            try {
                doc.remove(start, end);
            } catch (BadLocationException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }

干杯!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM