如何知道啥 JTextField 进入 DocumentListener

Posted

技术标签:

【中文标题】如何知道啥 JTextField 进入 DocumentListener【英文标题】:How to know what JTextField is coming into the DocumentListener如何知道什么 JTextField 进入 DocumentListener 【发布时间】:2016-04-25 14:10:27 【问题描述】:

我正在尝试在多个 JTextField 上使用 DocumentListener。我需要知道哪个 textField 将进入 DocumentEvent,以便我可以执行一些特定的过程。下面是我如何对我的DocumentListener 进行编码并设置其中一个 JTextField [感谢这个示例:How to get JTextField name in which is Document placed?](我的 textField 被声明在更高的范围内)。

我该如何解决这个问题?

    final DocumentListener documentListener = new DocumentListener() 
        @Override
        public void changedUpdate(DocumentEvent documentEvent) 
            printIt(documentEvent);
          
          @Override
        public void insertUpdate(DocumentEvent documentEvent) 
            printIt(documentEvent);
          
          @Override
        public void removeUpdate(DocumentEvent documentEvent) 
            printIt(documentEvent);
          
          private void printIt(DocumentEvent documentEvent) 
            final DocumentEvent.EventType type = documentEvent.getType();
            String typeString = null;
            final JTextField textField = (JTextField) documentEvent.getDocument().getProperty("parent");
            if (type.equals(DocumentEvent.EventType.CHANGE)) 
              typeString = "(parent: " + textField + ") Change";
              else if (type.equals(DocumentEvent.EventType.INSERT)) 
              typeString = "(parent: " + textField + ") Insert";
              else if (type.equals(DocumentEvent.EventType.REMOVE)) 
              typeString = "(parent: " + textField + ") Remove";
            
            System.out.print("Type : " + typeString);
            final Document source = documentEvent.getDocument();
            final int length = source.getLength();
            System.out.println("Length: " + length);
          
        ;

我的 JTextField 编码如下...

    textFieldFencing_LC1 = new JTextField();
    textFieldFencing_LC1.setHorizontalAlignment(SwingConstants.CENTER);
    textFieldFencing_LC1.setFont(new Font("Tahoma", Font.PLAIN, 9));
    textFieldFencing_LC1.setColumns(10);
    textFieldFencing_LC1.setBounds(234, 535, 85, 14);
    panelLC.add(textFieldFencing_LC1);
    textFieldFencing_LC1.getDocument().addDocumentListener(documentListener);
    textFieldFencing_LC1.getDocument().putProperty("parent",textFieldFencing_LC1);

我想要的输出应该是这样的

Type : (parent: textFieldFencing_LC1) InsertLength: 1
Type : (parent: textFieldFencing_LC1) InsertLength: 1

我得到的输出看起来像这样......

Type : (parent: javax.swing.JTextField[,234,535,85x14,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@384cdfdd,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=10,columnWidth=0,command=,horizontalAlignment=CENTER]) InsertLength: 2
Type : (parent: javax.swing.JTextField[,234,535,85x14,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@384cdfdd,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=10,columnWidth=0,command=,horizontalAlignment=CENTER]) InsertLength: 3

【问题讨论】:

想通过将.getName() 放在文本字段上,像这样textFieldFencing_LC1.getDocument().putProperty("parent",textFieldFencing_LC1.getName()); 可能会解决问题。但是,它没有。现在输出读取为Type : (parent: null) InsertLength: 1 【参考方案1】:

在阅读了这个类的文档后,我意识到putProperty(Object,Object) 方法可以让我在其中放入一个String。所以,现在我的 JTextField 上的监听器看起来像这样......

textFieldFencing_LC1.getDocument().addDocumentListener(documentListener);
textFieldFencing_LC1.getDocument().putProperty("parent","LC1");  // String, String

注意,putProperty() 中的第二个参数是一个对我有意义的字符串,所以我可以检查 LC#。虽然 DocumentListener 中的更新看起来像这样......

final DocumentEvent.EventType type = documentEvent.getType();
String typeString = null;

// Cast documentEvent to String
txtField.setText( (String) documentEvent.getDocument().getProperty("parent") );  

          if (type.equals(DocumentEvent.EventType.CHANGE)) 
                 typeString = "(parent: " + txtField.getText() + ") Change";
            else if (type.equals(DocumentEvent.EventType.INSERT)) 
                 typeString = "(parent: " + txtField.getText() + ") Insert";
            else if (type.equals(DocumentEvent.EventType.REMOVE)) 
                 typeString = "(parent: " + txtField.getText() + ") Remove";
       
   System.out.print("Type : " + typeString);
   final Document source = documentEvent.getDocument();
   final int length = source.getLength();
   System.out.println("Length: " + length);

现在的输出看起来像...

Type : (parent: LC1) RemoveLength: 0
Type : (parent: LC1) InsertLength: 1
Type : (parent: LC1) InsertLength: 2
Type : (parent: LC1) InsertLength: 3

底线:一个引用的类和两行代码放在我需要监听的 JTextFields 上,以便发生自动更新,这比在所有这些字段上添加 CaretListener 要好得多。

【讨论】:

以上是关于如何知道啥 JTextField 进入 DocumentListener的主要内容,如果未能解决你的问题,请参考以下文章

JAVA中对JTextField对象的值的获取操作,为啥注释的部分没有效果呢?难道有啥错误么?

如何在 JTextField 中显示淡灰色的“重影文本”?

如何将我的 JTextField 放在垂直对齐上

如何将来自JTextField的输入转换为日期?

批处理文件:如果我知道文件夹名称以啥开头,但不知道全名,如何进入文件夹

如何在 JLabel 和 JTextField 上显示非科学格式的值?