如何限制JTextArea最大行数和列数? [英] How to limit JTextArea max Rows and Columns?

查看:367
本文介绍了如何限制JTextArea最大行数和列数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在JScrollPane中使用JTextArea

I am using JTextArea in JScrollPane

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

I want to limit the maximum number of lines possible and the maximum chars in each line.

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

I need that the string will be exactly like on the screen, each line will end with '\n' (if there another line after it) and the user will be able to insert only X lines and Y chars in each line.

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

I tried to limit the lines but I don't know exactly how many lines do I have because of the line wrapping, The line wrapping is starting new line visually on the screen(because of the width of the JTextArea) but in the string of the component it is really the same line with no '\n' to indicate new line. I do not have an idea how to limit the max chars in each line while typing.

有两个阶段:


  1. 字符串的输入 - 保持用户不能在每行中输入X行和Y字符。 (即使换行仅为visualy或用户键入'/ n')

  2. 在克隆'OK'之后将字符串插入DB-转换每行将结束的字符串 / n即使用户没有键入它,并且该行仅被视觉包裹。

如果我算数,几乎没有问题行中的字符,并在行的末尾插入'/ n',这就是为什么我决定分两个阶段进行。在第一阶段,用户正在键入我宁愿仅限制它,并强制线路打字或类似的东西。只有在第二阶段,当我保存字符串时,我会添加'/ n',即使用户没有在行尾输入它!

There are few problems if i will count the chars in the line and insert '/n' in the end of the line, thats why i decided to do it in two stages. In the first stage ehile the user is typing i would rather only limit it visualy and force line wrpping or something similar. Only in the second stage when i save string i will add the '/n' even if the user did not typed it in the end of the lines!

有没有人有想法?

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

I know that i will have to use DocumentFilter OR StyledDocument.

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

Here is sample code that limit only the lines to 3:(but not the chars in row to 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;
   }
}


推荐答案

这里是我的版本,基于尼克霍尔特的版本。

Here's my version, based on Nick Holt's version.

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

Just for the records, this will be used in a prototype and has not been tested much (if at all).

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;
    }
}

这篇关于如何限制JTextArea最大行数和列数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆