jtextarea暂时显示字符,但不应该屏蔽字符

问题描述 投票:0回答:1

我有一个要求,我在运行时在JTextarea中输入输入,并且应该屏蔽输入。我可以通过下面的代码片段实现这一点

if(encryptKeystroke == true) {
            jTextArea.addKeyListener(new KeyListener() {
                public void keyTyped(KeyEvent e) {
                }

                public void keyPressed(KeyEvent e) {
                    if (e.getExtendedKeyCode() == KeyEvent.VK_BACK_SPACE) {
                        if(text.length() > 0)
                         text = text.substring(0, text.length() - 1);
                    }
                    else {
                        text += String.valueOf(e.getKeyChar());
                    }
                    jTextArea.setText(text.replaceAll(".", "*"));

                }
                public void keyReleased(KeyEvent e) {
                    jTextArea.setText(text.replaceAll(".", "*"));
                }
            });
        }

问题是,当我运行此命令时,输入的字符会显示一会儿,然后被掩盖(就像在Android中一样)。我正在使用JTextarea,因为无法在Ttextfield中实现可滚动和包装样式。任何建议如何做到这一点?

java swing jtextarea keylistener jpasswordfield
1个回答
0
投票

请勿将KeyListener用于此类内容。如果用户:

  1. 将文本粘贴到文本区域。该代码无法处理多个字符
  2. 将插入号移动到文本区域的开头。该代码假定始终在末尾添加文本。
  3. 使用删除键
  4. 突出显示一段文字,然后输入一个字符

KeyListener无法处理所有这些特殊情况。 Swing使用了更好和更新的API。

相反,您可以使用DocumentFilterDocumentFilter允许您在将文本添加到DocumentJTextArea之前对其进行过滤。

基本示例:

import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;

public class AsteriskFilter extends DocumentFilter
{
    private StringBuilder realText = new StringBuilder();

    @Override
    public void insertString(FilterBypass fb, int offset, String text, AttributeSet attributes)
        throws BadLocationException
    {
        replace(fb, offset, 0, text, attributes);
    }

    @Override
    public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attributes)
        throws BadLocationException
    {
        //  Update the StringBuilder to contain the real text

        Document doc = fb.getDocument();
        realText.replace(offset, offset + length, text);

        //  Update the Document with asterisks

        text = text.replaceAll(".", "*");
        super.replace(fb, offset, length, text, attributes);
    }

    @Override
    public void remove(DocumentFilter.FilterBypass fb, int offset, int length)
        throws BadLocationException
    {
        realText.delete(offset, offset + length);

        super.remove(fb, offset, length);
    }

    public String getRealText()
    {
        return realText.toString();
    }

    private static void createAndShowGUI()
    {
        JTextArea textArea = new JTextArea(3, 20);
        AbstractDocument doc = (AbstractDocument) textArea.getDocument();
        AsteriskFilter filter = new AsteriskFilter();
        doc.setDocumentFilter( filter );

        JButton button = new JButton("Display Text");
        button.addActionListener(e -> JOptionPane.showMessageDialog(textArea, filter.getRealText()));

        JFrame frame = new JFrame("Asterisk Filter");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(textArea, BorderLayout.CENTER);
        frame.add(button, BorderLayout.PAGE_END);
        frame.setSize(220, 200);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args) throws Exception
    {
        EventQueue.invokeLater( () -> createAndShowGUI() );
/*
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
*/
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.