当前位置: 首页 > 面试题库 >

通过几个曲线球在Swing JTextArea上强制使用最大字符

汪才英
2023-03-14
问题内容

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

  • 仅允许用户在文本区域中输入500个字符(最大)
  • 标签包含一个字符串消息,告诉用户他们还剩下多少个字符(在每次按键或退格后)
  • 组件初始化时,标签显示为“最多500个字符!”
  • 对于键入的前500个字符,对于键入的每个键击(a-z,A-Z,0-9和标点符号),标签都会读取“剩余x个字符”,这x是它们到达字符前剩余的字符数最多500
  • 键入第500个字符时,标签将读取“剩余0个字符”,并且无法在文本区域中键入其他字符
  • 如果用户键入退格按钮(KeyEvent.VK_BACK_SPACE),他们将“释放”一个字符,并且计数增加。因此,如果他们剩余400个字符,并键入退格键,则标签现在显示为“剩余401个字符”
  • 如果用户突出显示一组字符并对其执行批量命令(例如,退格键,或将突出显示的文本替换为单个字符),则将正确计算剩余的正确字符数,并更新标签。因此,如果他们剩下50个字符,并且突出显示5个字母并按退格键,那么现在他们剩下“ 55个字符”

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

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

上面的代码运行良好,但是有一些错误:

  • 这不会阻止用户输入> 500个字符。当用户键入第500个字符时,标签将显示“剩余0个字符”。但是之后您可以继续输入字符,并且标签保持不变。
  • 如果您在文本区域中有> 500个字符,并开始退格,您会看到每个字符都已从文本区域(基础模型)中删除,但标签保持不变。 但是 ,一旦退格足够达到第500个字符,并且退格,标签就会开始正确更改,告诉您“剩余1个字符”,“剩余2个字符”等。所以…
  • 该代码似乎可以正常工作,但是停止工作> 500个字符。一旦恢复到最大500个字符以内,它将重新开始工作。

问题

  1. 有没有更简单的方法来实现此所需功能(以及用于Swing JTextArea)?我觉得我在这里重新发明轮子,可能会有一种“更清洁”的方法来强制字符最大值并更新它们各自的标签。
  2. 如果没有,是否有人可以发现我的> 500个字符错误?我整个上午都在看,正在拔头发。
  3. 最重要的是 ,我该如何实现处理批量命令以突出显示文本的要求?如何在文本区域内进行文本选择,如何侦听突出显示的文本的更改(例如,使用退格按钮删除多个突出显示的字符等),以及如何正确计算剩余字符的新值?

提前致谢。


问题答案:

您可以使用DocumentFilter来限制最大大小,请参阅本文档部分,其中提供了您需要的有效示例。

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

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 JLabel和JTextArea添加功能,以便: null null null 提前道谢。

  • 问题内容: 我正在编写一个使用大量CPU的Java程序,因为它的工作性质。但是,许多程序可以并行运行,并且我使程序成为多线程的。当我运行它时,似乎只使用一个CPU直到需要更多的CPU,然后再使用另一个CPU- 我可以用Java强制其他操作在不同的内核/ CPU上运行吗? 问题答案: 当我运行它时,它似乎只使用一个CPU直到需要更多的CPU,然后再使用另一个CPU-我可以用Java强制其他操作以在不

  • 问题内容: 我试图强迫MySQL使用两个索引。我正在加入一个表,我想利用两个索引之间的交叉。具体术语是“使用相交”,这是指向MySQL文档的链接: http://dev.mysql.com/doc/refman/5.0/zh-CN/index-merge- optimization.html 有什么办法可以强制实施吗?我的查询正在使用它(并且它加快了速度),但是现在无论出于何种原因它都停止了。 这

  • 问题内容: 这是我声明曲线的代码行: 现在我可以使用什么代码来绘制曲线?我尝试了类似的东西: 但显然那没有用。有什么建议? 问题答案: 我已经做了一个最小的测试用例,以证明您在这里的描述。该程序可以运行,但是除非能看到您正在使用的代码,否则我无法真正为您提供帮助。

  • 如何连接多点与流动曲线,使用PyQt5?例如,我试图使用quitTo()对8个点执行此操作,使用交替点作为控制点,但弧不接触控制点(见下面的代码和图表)。我也尝试使用cubicTo(),但这也导致了一个奇怪的曲线。use是否有任何其他函数调用,我应该使用,或自定义的方式来做到这一点?

  • 截图显示了相同数据的三次贝塞尔模式和不三次贝塞尔模式的图表。如你所见,当立方贝塞尔模式是启用,线ECXEED的最小和最大值,我需要显示在图表作为限制线,它看起来非常糟糕。 有什么办法可以解决这个问题吗??