【问题标题】:how to update JTextField from another JtextField如何从另一个 JtextField 更新 JTextField
【发布时间】:2014-12-04 04:07:06
【问题描述】:

我正在制作一个包含两个 jtextfields 的 ui。我想要的是当用户第一次输入时 jtextfield 它应该在第二个 jtextfield 中镜像,增量为 1,如果用户 在第二个 JtextField 中的输入它应该在第一个 jtextfield 中镜像,并减少 的 1.But 我收到类似 IllegalStateException:Attempt to mutate in notification 之类的错误。

示例代码:

public class Sh extends JFrame 
{
 public Sh() 
{
super("SH");
JPanel panel = new JPanel();
getContentPane().add(panel, BorderLayout.NORTH);

final JTextField field = new JTextField(10);
panel.add(field); 

final JTextField field1 = new JTextField(10);
panel.add(field1);

  DocumentListener docListener = new DocumentListener(){

        @Override
        public void changedUpdate(DocumentEvent e) {
            updateLabel(e);
        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            updateLabel(e);
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            updateLabel(e);
        }

        private void updateLabel(DocumentEvent e) {
     String text = field.getText();
                    String text1 = field1.getText();

                    if (!text.isEmpty()) {
                        int p = Integer.parseInt(text);
                        int i = (p + 1);
                        String s = String.valueOf(i);
                        field1.setText(s);
                    } else if (!text1.isEmpty()) {
                        int p = Integer.parseInt(text1);
                        int i = (p - 1);
                        String s = String.valueOf(i);
                        field.setText(s);
                    }

                }
    };
  field.getDocument().addDocumentListener(docListener);
  field1.getDocument().addDocumentListener(docListener); 

       DocumentFilter docFilter = new DocumentFilter(){
        @Override
        public void insertString(FilterBypass fb, int off, String str, AttributeSet attr)
                throws BadLocationException {
            fb.insertString(off, str.replaceAll("\\D++", ""), attr);  // remove non-digits
        }

        @Override
        public void replace(FilterBypass fb, int off, int len, String str, AttributeSet attr)
                throws BadLocationException {
            fb.replace(off, len, str.replaceAll("\\D++", ""), attr);  // remove non-digits
        }
    };   
 ((AbstractDocument) field.getDocument()).setDocumentFilter(docFilter); 
 ((AbstractDocument) field1.getDocument()).setDocumentFilter(docFilter); 

  }
   public static void main(String[] args)
   {
  Sh s = new Sh();
  s.setDefaultCloseOperation(EXIT_ON_CLOSE);
  s.pack();
  s.setVisible(true);
   }
 }

【问题讨论】:

  • 您不能修改已修改的文档。虽然使用单个侦听器的想法是个好主意,但您需要确定该侦听器将更新的字段,并且应该将其附加到另一个

标签: java swing jtextfield documentlistener documentfilter


【解决方案1】:

正如MadProgrammer 所建议的,这里是解决方案:

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.DocumentFilter;

/**
 * <code>Sh</code>.
 *
 * @author SMedvynskyy
 */
public class Sh extends JFrame
{
    public Sh()
    {
        super("SH");
        final JPanel panel = new JPanel();
        getContentPane().add(panel, BorderLayout.NORTH);

        final JTextField field = new JTextField(10);
        panel.add(field);

        final JTextField field1 = new JTextField(10);
        panel.add(field1);

        final DocumentListener docListener = new DocumentListener(){

            private Document originator;

            @Override
            public void changedUpdate(DocumentEvent e) {
                updateLabel(e);
            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                updateLabel(e);
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                updateLabel(e);
            }

            private void updateLabel(DocumentEvent e) {
                if (null == originator) {
                    originator = e.getDocument();
                    String text = "";
                    try {
                        text = originator.getText(0, originator.getLength());
                    } catch (final Exception ex) {
                        ex.printStackTrace();
                    }

                    if (!text.isEmpty()) {
                        final int p = Integer.parseInt(text);
                        if (originator.equals(field.getDocument())) {
                            final int i = (p + 1);
                            final String s = String.valueOf(i);
                            field1.setText(s);
                        } else {
                            final int i = (p - 1);
                            final String s = String.valueOf(i);
                            field.setText(s);
                        }
                    } else {
                      field.setText(text);
                      field1.setText(text);
                    }

                    originator = null;
                }

            }
        };
        field.getDocument().addDocumentListener(docListener);
        field1.getDocument().addDocumentListener(docListener);

        final DocumentFilter docFilter = new DocumentFilter(){
            @Override
            public void insertString(FilterBypass fb, int off, String str, AttributeSet attr)
                    throws BadLocationException {
                fb.insertString(off, str.replaceAll("\\D++", ""), attr);  // remove non-digits
            }

            @Override
            public void replace(FilterBypass fb, int off, int len, String str, AttributeSet attr)
                    throws BadLocationException {
                fb.replace(off, len, str.replaceAll("\\D++", ""), attr);  // remove non-digits
            }
        };
        ((AbstractDocument) field.getDocument()).setDocumentFilter(docFilter);
        ((AbstractDocument) field1.getDocument()).setDocumentFilter(docFilter);

    }
    public static void main(String[] args)
    {
        final Sh s = new Sh();
        s.setDefaultCloseOperation(EXIT_ON_CLOSE);
        s.pack();
        s.setVisible(true);
    }
}

方法 JTextField.setText 会引发 DocumentEvent 被触发,所以如果你不特别避免它 - 你会遇到这个问题(或无限递归)。

【讨论】:

  • 如果我们在文本字段 1 中输入然后擦除所有内容,则会出现小问题,整数值仍然显示在文本字段 2 中,反之亦然
  • @Rudydev 我已经更正了解决方案。因此,如果用户删除了一个字段中的所有文本,它将在另一个字段中自动删除。
  • 非常感谢@Sergiy Medvynskyy,它可以工作,你能帮帮我吗,在这个例子中,我试图从文本文件读取数据到 jtextfield 1,它应该在 jtextfield 2 中自动递增。我已经尝试过了,但是直到我们在 jtextfield 1 中输入一个整数以及从文本文件中读取的数据时,它才会在 jtextfield 2 中增加。
猜你喜欢
  • 1970-01-01
  • 2012-10-11
  • 2015-03-11
  • 1970-01-01
  • 2012-07-23
  • 1970-01-01
  • 1970-01-01
  • 2013-03-19
  • 1970-01-01
相关资源
最近更新 更多