如何限制JTextArea最大行数和列数?

时间:2009-01-26 09:05:24

标签: java text limit lines jtextarea

我在JScrollPane中使用JTextArea

我想限制可能的最大行数和每行中的最大字符数。

我需要字符串与屏幕上的字符串完全相同,每一行都以'\ n'结尾(如果后面还有另一行),用户将只能在每行中插入X行和Y字符

我试图限制线条,但由于换行,我不确切知道有多少行,换行是在屏幕上直观地开始换行(因为JTextArea的宽度)但是组件的字符串它实际上是相同的行,没有'\ n'来表示新行。我不知道如何在输入时限制每行的最大字符数。

有两个阶段:

  1. 字符串的输入 - 保持用户无法在每行中输入X行和Y字符。 (即使换行只是视觉上或用户输入'/ n')
  2. 在克隆后将字符串插入DB-'OK'将每行以“/ n”结尾的字符串转换为“/ n”,即使用户没有键入它并且该行只是视觉上包裹。
  3. 如果我将计算行中的字符并在行的末尾插入'/ n',那么几乎没有问题,这就是为什么我决定分两个阶段进行。在第一阶段,用户正在键入我宁愿仅限制它,并强制线路打字或类似的东西。只有在第二阶段,当我保存字符串时,我会添加'/ n',即使用户没有在行尾输入它!

    有没有人有想法?


    我知道我必须使用DocumentFilter或StyledDocument。

    以下是仅将行限制为3的示例代码:(但不包括行中的字符到19)

    private JTextArea textArea ;
    textArea  = new JTextArea(3,19);
    textArea  .setLineWrap(true);
    textArea .setDocument(new LimitedStyledDocument(3));
    JScrollPane scrollPane  = new JScrollPane(textArea
    
    public class LimitedStyledDocument extends DefaultStyledDocument
    
        /** Field maxCharacters */
        int maxLines;
    
        public LimitedStyledDocument(int maxLines) {
            maxCharacters = maxLines;
        }
    
    public void insertString(int offs, String str, AttributeSet attribute) throws BadLocationException {
        Element root = this.getDefaultRootElement();
        int lineCount = getLineCount(str);
    
        if (lineCount + root.getElementCount() <= maxLines){
            super.insertString(offs, str, attribute);
        }
        else {
            Toolkit.getDefaultToolkit().beep();
        }
    }
    
     /**
     * get Line Count
     * 
     * @param str
     * @return the count of '\n' in the String
     */
    private int getLineCount(String str){
        String tempStr = new String(str);
        int index;
        int lineCount = 0;
    
        while (tempStr.length() > 0){
            index = tempStr.indexOf("\n");
            if(index != -1){
            lineCount++;
                tempStr = tempStr.substring(index+1);
            }
        else{
            break;
            }
        }
        return lineCount;
       }
    }
    

2 个答案:

答案 0 :(得分:1)

以下对我有用:

public class LimitedLinesDocument extends DefaultStyledDocument 
{    
  private static final String EOL = "\n";

  private int maxLines;

  public LimitedLinesDocument(int maxLines) 
  {    
    this.maxLines = maxLines;
  }

  public void insertString(int offs, String str, AttributeSet attribute) throws BadLocationException 
  {        
    if (!EOL.equals(str) || StringUtils.occurs(getText(0, getLength()), EOL) < maxLines - 1) 
    {    
      super.insertString(offs, str, attribute);
    }
  }
}

StringUtils.occurs方法如下:

public static int occurs(String str, String subStr) 
{    
  int occurrences = 0;
  int fromIndex = 0;

  while (fromIndex > -1) 
  {    
    fromIndex = str.indexOf(subStr, occurrences == 0 ? fromIndex : fromIndex + subStr.length());
    if (fromIndex > -1) 
    {    
      occurrences++;
    }
  }

  return occurrences;
}

答案 1 :(得分:1)

这是我的版本,基于Nick Holt的版本。

只是为了记录,这将用于原型并且没有经过多少测试(如果有的话)。

public class LimitedLinesDocument extends DefaultStyledDocument {
    private static final long serialVersionUID = 1L;

    private static final String EOL = "\n";

    private final int maxLines;
    private final int maxChars;

    public LimitedLinesDocument(int maxLines, int maxChars) {
        this.maxLines = maxLines;
        this.maxChars = maxChars;
    }

    @Override
    public void insertString(int offs, String str, AttributeSet attribute) throws BadLocationException {
        boolean ok = true;

        String currentText = getText(0, getLength());

        // check max lines
        if (str.contains(EOL)) {
            if (occurs(currentText, EOL) >= maxLines - 1) {
                ok = false;
            }
        } else {
            // check max chars
            String[] lines = currentText.split("\n");
            int lineBeginPos = 0;
            for (int lineNum = 0; lineNum < lines.length; lineNum++) {
                int lineLength = lines[lineNum].length();
                int lineEndPos = lineBeginPos + lineLength;

                System.out.println(lineBeginPos + "    " + lineEndPos + "    " + lineLength + "    " + offs);

                if (lineBeginPos <= offs && offs <= lineEndPos) {
                    System.out.println("Found line");
                    if (lineLength + 1 > maxChars) {
                        ok = false;
                        break;
                    }
                }
                lineBeginPos = lineEndPos;
                lineBeginPos++; // for \n
            }
        }

        if (ok)
            super.insertString(offs, str, attribute);
    }

    public int occurs(String str, String subStr) {
        int occurrences = 0;
        int fromIndex = 0;

        while (fromIndex > -1) {
            fromIndex = str.indexOf(subStr, occurrences == 0 ? fromIndex : fromIndex + subStr.length());
            if (fromIndex > -1) {
                occurrences++;
            }
        }

        return occurrences;
    }
}