2015-09-27 42 views
0

我創建了一個覆蓋JTextField的外部類。在這個類中,我添加了一個替換的DocumentListener,可以防止輸入某個字符。下面是代碼(它不是確切的代碼,對於這個問題的簡單的目的):在操作textField數據時在textField上重寫getText方法

import javax.swing.JTextField; 
import javax.swing.event.DocumentEvent; 
import javax.swing.event.DocumentListener; 

class test extends JTextField{ 
private String filteredText; 

public void getDefaultText(){ 
super.getText(); 
} 

public String getText(){ 
return filteredText; 
} 

public void remword(){ 
super.getDocument().addDocumentListener(new DocumentListener() { 

      @Override 
      public void changedUpdate(DocumentEvent arg0) { 
      } 

      @Override 
      public void insertUpdate(DocumentEvent arg0) { 
       Runnable ru = new Runnable() { 
        @Override 
        public void run() { 
           String finalText = getDefaultText().replace("xyz", "asd"); 
           setText(finalText); 
           filteredText = finalText; 
         } 
        } 
       }; 
       SwingUtilities.invokeLater(ru);   
} 

      @Override 
      public void removeUpdate(DocumentEvent arg0) { 
      } 
}); 
} 
} 

現在,除非我用getText()方法,它返回錯誤Attempt to mutate in notificaton此代碼工作正常。我試圖用​​和Runnable搞亂無濟於事。

回答

3

DocumentListener

該通知的DocumentEvent基於JavaBeans事件模型。無法保證傳遞給監聽者的順序,並且在對文檔進行進一步突變之前必須通知所有監聽者。 這意味着DocumentListener的實現可能不會改變事件的來源(即關聯的文檔)。

您應該使用DocumentFilter來控制文檔操作。

順便說一句,使用getText()不應該拋出這個異常。你可能意思是setText(String)

你不需要子類JTextField這個用例:

((AbstractDocument) textField.getDocument()).setDocumentFilter(new DocumentFilter() { 
    @Override 
    public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException { 
     super.insertString(fb, offset, sanitize(string), attr); 
    } 

    @Override 
    public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { 
     super.replace(fb, offset, length, sanitize(text), attrs); 
    } 

    private String sanitize(String s) { 
     return s == null ? null : s.replace("xyz", "asd"); 
    } 
}); 

要小心,我的解決方案仍允許「XYZ」如果通過信函或通過刪除例如輸入字母的文件「_」來自「xy_z」。