2014-10-09 80 views
0

我正在製作一個UI,其中有兩個jtextfields。我想要的是,當用戶在第一個 jtextfield中輸入時,它應該在第二個jtextfield中以1爲增量進行鏡像,並且如果用戶 在第二個JtextField中輸入,它應該在第一個jtextfield中鏡像,其減量爲 。但是我獲取像IllegalStateException的錯誤:嘗試在通知中進行變異。如何從另一個JtextField更新JTextField

示例代碼:

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

您無法修改已修改的文檔。雖然使用單個偵聽器的想法是一個好主意,但您需要確定此偵聽器將更新的字段,並且它應該附加到其他 – MadProgrammer 2014-10-09 09:38:50

回答

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,所以如果你不迴避它特別是 - 你會得到這個問題(或無限遞歸)。

+0

如果我們在文本字段1中輸入然後擦除所有內容,則存在小問題,整數值仍然顯示在textfield 2中,反之亦然 – 2014-10-11 14:18:58

+0

@Rudydev我已經糾正瞭解決方案。因此,如果用戶刪除一個字段中的所有文本,它將自動在另一個字段中刪除。 – 2014-10-11 16:54:24

+0

非常感謝你@Sergiy Medvynskyy它的工作原理,可以請你幫我,在這個例子中,我試圖從文本文件中讀取數據 到jtextfield 1,它應該會自動在jtextfield 2中遞增。我試過 但它不會在jtextfield 2中增加,直到我們在jtextfield 1中輸入一個整數以及從文本文件中讀取的數據 。 – 2014-10-13 09:40:59