有没有办法在不触发 DocumentListener 的 removeupdate() 的情况下调用 JTextField.setText()?

Posted

技术标签:

【中文标题】有没有办法在不触发 DocumentListener 的 removeupdate() 的情况下调用 JTextField.setText()?【英文标题】:Is there a way to call JTextField.setText() without fired DocumentListener's removeupdate()? 【发布时间】:2021-10-25 18:52:57 【问题描述】:

我实际上是在通过这个小项目学习 Java Swing API。

这是代码:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import com.userView.Utilities;

public class MobileNumberValidation extends JFrame 

    private JButton clearButton ;
    private JTextField mobileNumberField ;
    private JLabel mobileNumberLabel ;
    private JLabel errorMessage ;


    MobileNumberValidation()

        //Intializing the instance variables
        clearButton       = new JButton("clear");
        mobileNumberField = new JTextField();
        mobileNumberLabel = new JLabel("TEL");
        errorMessage      = new JLabel("Tel is empty");

        setSize(500, 500);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(null);

        //add components to Jframe
        add(mobileNumberField);
        add(clearButton);
        add(mobileNumberLabel);
        add(errorMessage);


        //set components location
        mobileNumberField.setBounds(200, 170, 230, 20);
        clearButton.setBounds(200, 220, 100, 20);
        mobileNumberLabel.setBounds(160, 170, 100, 20);
        errorMessage.setBounds(210, 190, 300,20);


        //components style
        errorMessage.setForeground(Color.decode("#CD5C5C"));

        //add listener and handle event
        mobileNumberField.getDocument().addDocumentListener(new DocumentListener()
            
            @Override
            public void changedUpdate(DocumentEvent arg0)                 
            

            @Override
            public void insertUpdate(DocumentEvent arg0) 
                processTelValidation();
            

            @Override
            public void removeUpdate(DocumentEvent event) 
                System.out.println("removeUpdate");
                processTelValidation();
            

            public void processTelValidation() 
                if (Utilities.isRegExPatternMatching("^0[0-9]6$", mobileNumberField.getText())) 
                    errorMessage.setVisible(false);
                else
                    errorMessage.setVisible(true);
                    errorMessage.setText("enter a valid Tel number");
                
            
        );

        clearButton.addActionListener(new ActionListener()
            @Override
            public void actionPerformed(ActionEvent arg0) 
                //clear mobileNumberField
                mobileNumberField.setText("");
            
        );
    

    public static void main(String[] args) 
        
       new MobileNumberValidation();
        
    


app screen shot

每次我按下clearButton 清除字段时,mobileNumber.setText("") 都会被调用,它会从DocumentListener 触发removeUpdate(),我不希望这样。

您是否知道任何其他方法来清理 JTextField 组件的字段或使用 JTextField.setTextField() 但不触发 DocumentListener 方法?

【问题讨论】:

考虑使用InputVerifier 来验证输入的电话号码。请参阅如何使用焦点子系统网页上的Validating Input。或者只是在针对正则表达式进行测试之前检查mobileNumberField 的内容是否为空。 【参考方案1】:

您可以简单地将侦听器保存在局部变量中。然后,从Document 中移除监听器,清除文本,最后将监听器放回Document

(记住我删除了你的一行:if (Utilities.isRegExPatternMatching("^0[0-9]6$", mobileNumberField.getText()))

public class MobileNumberValidation extends JFrame 

    private JButton clearButton;
    private JTextField mobileNumberField;
    private JLabel mobileNumberLabel;
    private JLabel errorMessage;

    MobileNumberValidation() 

        // Intializing the instance variables
        clearButton = new JButton("clear");
        mobileNumberField = new JTextField();
        mobileNumberLabel = new JLabel("TEL");
        errorMessage = new JLabel("Tel is empty");

        setSize(500, 500);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(null);

        // add components to Jframe
        add(mobileNumberField);
        add(clearButton);
        add(mobileNumberLabel);
        add(errorMessage);

        // set components location
        mobileNumberField.setBounds(200, 170, 230, 20);
        clearButton.setBounds(200, 220, 100, 20);
        mobileNumberLabel.setBounds(160, 170, 100, 20);
        errorMessage.setBounds(210, 190, 300, 20);

        // components style
        errorMessage.setForeground(Color.decode("#CD5C5C"));

        // add listener and handle event
        DocumentListener validatePhoneListener = new DocumentListener() 

            @Override
            public void changedUpdate(DocumentEvent arg0) 
            

            @Override
            public void insertUpdate(DocumentEvent arg0) 
                processTelValidation();
            

            @Override
            public void removeUpdate(DocumentEvent event) 
                System.out.println("removeUpdate");
                processTelValidation();
            

            public void processTelValidation() 
                if (Math.random() > 0.5d) 
                    errorMessage.setVisible(false);
                 else 
                    errorMessage.setVisible(true);
                    errorMessage.setText("enter a valid Tel number");
                
            
        ;
        mobileNumberField.getDocument().addDocumentListener(validatePhoneListener);

        clearButton.addActionListener(new ActionListener() 
            @Override
            public void actionPerformed(ActionEvent arg0) 
                mobileNumberField.getDocument().removeDocumentListener(validatePhoneListener);
                mobileNumberField.setText("");
                mobileNumberField.getDocument().addDocumentListener(validatePhoneListener);
            
        );
    

    public static void main(String[] args) 

        new MobileNumberValidation();

    


另外,请确保您已阅读:

    Why null layouts and absolute positions are bad practice in Swing? SwingUtilities.invokeLater() why is it needed?

【讨论】:

以上是关于有没有办法在不触发 DocumentListener 的 removeupdate() 的情况下调用 JTextField.setText()?的主要内容,如果未能解决你的问题,请参考以下文章

在不触发发射的情况下插入 Android Room 表?

如何在不丢失触摸事件的情况下冻结 UIScrollView 滚动

如何在不加载空页面的情况下清理 UIWebView 的内容?

为啥这个命令在不应该触发的时候触发?

有没有办法在不安装的情况下引用 ghostscript DLL?

Google Sheet Script:有没有办法在不停止脚本的情况下显示消息?