1

嗨我有我的documentlistener問題。 將值插入文本字段後程序停止工作。該計劃應XOR運算文本框的第二行文本框的第一行,並把結果到文本框Java documentlistener - 輸入後程序停止工作

package opa.beta1; 

import java.awt.BorderLayout; 
import java.math.BigInteger; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 
import javax.swing.event.DocumentEvent; 
import javax.swing.event.DocumentListener; 

public class TextFieldEvent { 

    JTextField arrayIV[] = new JTextField[8]; 
    JTextField plaintextArray[] = new JTextField[8]; 
    JTextField ciphertextArray[] = new JTextField[8]; 
    JFrame frame = new JFrame("OPA"); 
    JPanel panel1 = new JPanel(); 
    JPanel panel2 = new JPanel(); 
    JPanel panel3 = new JPanel(); 

    public void setJPanel(JTextField array[], JPanel container, String s) { 
     for (int i = 0; i < 8; i++) { 
      array[i] = new JTextField(s, 4); 
      array[i].getDocument().addDocumentListener(new DocumentListener() { 
       @Override 
       public void insertUpdate(DocumentEvent de) { 
        setCiphertext(); 
       } 

       @Override 
       public void removeUpdate(DocumentEvent de) { 
        setCiphertext(); 
       } 

       @Override 
       public void changedUpdate(DocumentEvent de) { 
        setCiphertext(); 
       } 
      }); 
      container.add(array[i]); 
     } 
    } 

    public String setXORText(JTextField textfield1, JTextField textfield2) { 
     String okno1, okno2; 
     okno1 = textfield1.getText(); 
     okno2 = textfield2.getText(); 
     if (okno1.equals("")) { 
      return okno2; 
     } 
     BigInteger pom1 = new BigInteger(okno1, 16); 
     if (okno2.equals("")) { 
      return okno1; 
     } 
     BigInteger pom2 = new BigInteger(okno2, 16); 
     BigInteger res = pom1.xor(pom2); 
     String s = res.toString(16); 
     return s; 
    } 

    public String setXORText(JTextField pole1[], JTextField pole2[], int i) { 

     String okno1 = pole1[i].getText(); 
     String okno2 = pole2[i].getText(); 
     if (okno1.equals("")) { 
      return pole2[i].getText(); 
     } 
     BigInteger pom1 = new BigInteger(okno1, 16); 
     if (okno2.equals("")) { 
      return pole1[i].getText(); 
     } 
     BigInteger pom2 = new BigInteger(okno2, 16); 
     BigInteger res = pom1.xor(pom2); 
     String s = res.toString(16); 
     return s; 
    } 

    public void setCiphertext() { 
     //textfield3.setText(setXORText(textfield1, textfield2)); 
     for (int i = 0; i < 8; i++) { 
      ciphertextArray[i].setText(setXORText(arrayIV, plaintextArray, i)); 
     } 
    } 

    public TextFieldEvent() { 
     setJPanel(arrayIV, panel1, "1a"); 
     setJPanel(plaintextArray, panel2, "1b"); 
     setJPanel(ciphertextArray, panel3, "1"); 

     frame.add(panel1, BorderLayout.NORTH); 
     frame.add(panel2, BorderLayout.CENTER); 
     frame.add(panel3, BorderLayout.SOUTH); 

     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 
     frame.setSize(675, 275); 
     frame.setResizable(false); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new TextFieldEvent(); 
      } 
     }); 

    } 
} 

的第三排堆棧跟蹤

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to mutate in notification at javax.swing.text.AbstractDocument.writeLock(AbstractDocument.java:1338) at javax.swing.text.AbstractDocument.replace(AbstractDocument.java:659) at javax.swing.text.JTextComponent.setText(JTextComponent.java:1718) at opa.beta1.TextFieldEvent.setCiphertext(TextFieldEvent.java:82) at opa.beta1.TextFieldEvent$1.removeUpdate(TextFieldEvent.java:33) 
+0

「程序停止工作」:

解決方案可以實現如下? 「停止工作」是什麼意思? – Crozin

+0

線程「AWT-EventQueue-0」中的異常java.lang.IllegalStateException:嘗試在通知中突變 \t at javax.swing.text.AbstractDocument.writeLock(AbstractDocument.java:1338) \t at javax.swing.text。 AbstractDocument.replace(AbstractDocument.java:659) \t在javax.swing.text.JTextComponent.setText(JTextComponent.java:1718) \t在opa.beta1.TextFieldEvent.setCiphertext(TextFieldEvent.java:82) \t在OPA .beta1.TextFieldEvent $ 1.removeUpdate(TextFieldEvent.java:33) – DahakkaSVK

回答

1

此行

setJPanel(ciphertextArray, panel3, "1"); 

還爲ciphertextArrayTextField的每個元素添加了DocumentListener。因此,每當您的一個密碼文本TextField s的值發生變化時,方法setCipherText()被調用。

這導致以下順序:

  1. 您在TextField S的arrayIV的一個或plainTextArray
  2. setCipherText()調用
  3. setCipherText()輸入一個新值改變密文TextField的價值
  4. setCipherText()再次被調用(上面的解釋)。回到2.

這就是爲什麼你得到IllegalStateException

因此,解決方案是不要將DocumentListener添加到您的ciphertextArray中的TextFields。沒有它拋出任何異常 -

public void setJPanel(JTextField array[], JPanel container, String s, boolean docListener) { 
    for (int i = 0; i < 8; i++) { 
     array[i] = new JTextField(s, 4); 
     if (docListener) { 
      array[i].getDocument().addDocumentListener(new DocumentListener() { 
       @Override 
       public void insertUpdate(DocumentEvent de) { 
        setCiphertext(); 
       } 

       @Override 
       public void removeUpdate(DocumentEvent de) { 
        setCiphertext(); 
       } 

       @Override 
       public void changedUpdate(DocumentEvent de) { 
        setCiphertext(); 
       } 
      }); 
     } 
     container.add(array[i]); 
    } 
} 

[...] 

    setJPanel(arrayIV, panel1, "1a", true); 
    setJPanel(plaintextArray, panel2, "1b", true); 
    setJPanel(ciphertextArray, panel3, "1", false); 
+0

非常感謝它 – DahakkaSVK

1

包裹setCiphertext();在你的DocumentListener在SwingUtilities.invokeLater