使用一些曲线球在Swing JTextArea上强制使用最大字符 [英] Enforce max characters on Swing JTextArea with a few curve balls

查看:84
本文介绍了使用一些曲线球在Swing JTextArea上强制使用最大字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试向Swing JLabel和JTextArea添加功能,以便:

I'm trying to add functionality to a Swing JLabel and JTextArea such that:


  • 用户只能输入500个字符进入textarea(最大)

  • 标签包含一个字符串消息,告诉用户他们剩下多少个字符(每次击键或退格后)

  • 当组件初始化时,标签显示最多500个字符!

  • 对于输入的前500个字符,每次击键(a - z,A - Z,0 - 9和标点符号) )键入,标签显示剩余x个字符,其中 x 是他们在达到最大值500之前剩余的字符数

  • 当输入第500个字符时,标签显示剩余0个字符,并且不能在文本区域中输入其他字符

  • 如果用户键入退格按钮( KeyEvent.VK_BACK_SPACE ),他们释放一个字符,并且计数递增。因此,如果它们剩下400个字符,并且它们键入退格键,则标签现在显示剩余401个字符

  • 如果用户突出显示一组字符并对它们执行批量命令(例如作为退格键,或用单个字符替换突出显示的文本),将正确计算正确的剩余字符数,并更新标签。因此,如果他们剩下50个字符,并且他们突出显示5个字母并点击退格,他们现在有剩下55个字符

  • The user is only allowed to enter 500 characters into the textarea (max)
  • The label contains a string message telling the user how many characters they have left (after every key stroke or backspace)
  • When the components initialize the label reads "500 characters maximum!"
  • For the first 500 characters typed, for every keystroke (a - z, A - Z, 0 - 9, and punctuation) typed, the label reads "x characters remaining", where x is the number of chars they have left before they reach the max of 500
  • When the 500th character is typed, the label reads "0 characters remaining", and no further characters can be typed into the text area
  • If the user types the backspace button (KeyEvent.VK_BACK_SPACE), they "free" up a character, and the count increments. Thus if they had 400 characters remaining, and they type backspace, the label now reads "401 characters remaining"
  • If the user highlights a set of characters and performs a bulk command on them (such as a backspace, or replacing the highlighted text with a single character), the correct # of chars remaining will be calculated correctly and the label will be updated. So if they have 50 chars remaining, and they highlight 5 letters and hit backspace, they now have "55 characters remaining"

我有90%的此功能正常运行,但有一些错误,并且不知道如何实现上面的最后一项(突出显示的文本上的批量命令)。这就是我所拥有的:

I have 90% of this functionality working, but have a few bugs, and have no clue as to how to implement the last item above (bulk commands on highlighted text). Here's what I have:

boolean ignoreInput = false;
int charMax = 500;
JLabel charCntLabel = getLabel();
JTextArea myTextArea = getTextArea();

myTextArea.addKeyListener(new KeyListener() {
    @Override
    public void keyTyped(KeyEvent e) {
        return;
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // If we should be ignoring input then set make sure we
        // enforce max character count and remove the newly typed key.
        if(ignoreInput)
            myTextArea.setText(myTextArea.getText().substring(0,
                myTextArea.getText().length()));
    }

    @Override
    public void keyPressed(KeyEvent e) {
        String charsRemaining = " characters remaining";
        int newLen = 0;

        // The key has just been pressed so Swing hasn't updated
        // the text area with the new KeyEvent.
        int currLen = myTextArea.getText().length();

        // Adjust newLen depending on whether the user just pressed
        // the backspace key or not.
        if(e.getKeyCode() == KeyEvent.VK_BACK_SPACE) {
            newLen = currLen - 1;
            ignoreInput = false;
        }
        else
            newLen = currLen + 1;

        if(newLen < 0)
            newLen = 0;

        if(newLen == 0)
            charCntLabel.setText(charMax + " characters maximum!");
        else if(newLen >= 0 && newLen < charMax)
            charCntLabel.setText((charMax - newLen) + charsRemaining);
        else if(newLen >= charMax) {
            ignoreInput = true;
            charCntLabel.setText("0 " + charsRemaining);
        }
    }
});

以上代码效果很好,但有一些错误:

The above code works pretty well, but has a few bugs:


  • 它不会阻止用户输入> 500个字符。当用户键入第500个字符时,标签显示剩余0个字符。但是你可以继续输入字符,标签保持不变。

  • 如果textarea中有> 500个字符,并且你开始退格,你会看到每个字符从textarea(基础模型)中删除,但标签保持不变。 但是,一旦退格足以获得第500个字符,并且退格,标签将开始正确更改,告诉您剩余1个字符,剩余2个字符等。所以...

  • 此代码似乎可以正常工作,但只是停止工作> 500个字符。一旦你回到500 char最大值,它就会重新开始工作。

  • It doesn't prevent the user from typing in > 500 characters. When the user types in the 500th character, the label reads "0 characters remaining." But you can continue to type in characters after that, and the label stays the same.
  • If you have > 500 characters in the textarea, and you start backspacing, you'll see each character being removed from the textarea (the underlying model), but the label stays the same. But, once you backspace enough to get to the 500th character, and you backspace, the label will start changing properly, telling you that you have "1 characters remaining", "2 characters remaining", etc. So...
  • This code seems to work but just stops working > 500 characters. Once you get back inside that 500 char max, it begins working again.

  1. 有没有更简单的方法来实现这个所需的功能(以及Swing JTextArea)?我觉得我在这里重新发明轮子,并且可能有一种更清洁的方式来强制执行角色最大值并更新各自的标签。

  2. 如果没有,有人可以发现我的> 500 char bug?我整个上午都在看着它,我正在拔头发。

  3. 最重要的是,如何实现我的要求来处理突出显示文本的批量命令?如何在文本区域内处理文本选择,监听突出显示文本的更改(例如,使用退格按钮删除多个突出显示的字符等),并正确计算剩余字符的新值?

  1. Is there a simpler way to implement this desired functionality (and for a Swing JTextArea)? I feel like I'm reinventing the wheel here and that there might be a "cleaner" way of enforcing character maximums and updating their respective labels.
  2. If not, can anybody spot my > 500 char bug? I've been looking at it all morning and am pulling my hair out.
  3. Most importantly, how do I implement my requirement to handle bulk commands to highlighted text? How do I hand text selections inside the textarea, listen for changes to the highlighted text (e.g., deleting multiple highlighted characters with the backspace button, etc.), and correctly calculate the new value for chars remaining?

提前致谢。

推荐答案

你可以限制最大值通过使用 DocumentFilter 来确定大小,请检查文档部分,它有一个工作示例

You can limit the max size by using a DocumentFilter, check this documentation section, it has a working example of what you need.

以此为例,我使用了上面示例文件中的组件:

Take this as an example, I used the component from the example file above:

import java.awt.BorderLayout;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;

import components.DocumentSizeFilter;

public class Test {

    public static void main(String[] args) {
        new TestFrame().setVisible(true);
    }

    private static class TestFrame extends JFrame{
        private JTextField textField;
        private DefaultStyledDocument doc;
        private JLabel remaningLabel = new JLabel();

        public TestFrame() {
            setLayout(new BorderLayout());

            textField = new JTextField();
            doc = new DefaultStyledDocument();
            doc.setDocumentFilter(new DocumentSizeFilter(500));
            doc.addDocumentListener(new DocumentListener(){
                @Override
                public void changedUpdate(DocumentEvent e) { updateCount();}
                @Override
                public void insertUpdate(DocumentEvent e) { updateCount();}
                @Override
                public void removeUpdate(DocumentEvent e) { updateCount();}
            });
            textField.setDocument(doc);

            updateCount();

            add(textField, BorderLayout.CENTER);
            add(remaningLabel, BorderLayout.SOUTH);

            setLocationRelativeTo(null);
            pack();
        }

        private void updateCount()
        {
            remaningLabel.setText((500 -doc.getLength()) + " characters remaining");
        }
    }
}

这篇关于使用一些曲线球在Swing JTextArea上强制使用最大字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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