2012-08-24 54 views
2

請查看以下3組類。請注意,只顯示相關的代碼,其餘大部分被刪除。DocumentListener在JTextField.setText()中發佈問題

CommonGUI.java

package normal; 

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Collections; 
import java.util.List; 
import javax.swing.*; 
import javax.swing.text.AbstractDocument; 

public class CommonGUI extends JPanel 
{ 
    protected JLabel name, mobileNumber1, mobileNumber2, address, landNumber1, landNumber2, nickName, email, category; 
    protected JTextField nameTxt, mobileNumber1Txt, mobileNumber2Txt, landNumber1Txt, landNumber2Txt, nickNameTxt, emailTxt, categoryTxt; 

    protected JTextArea addressTxt; 
    protected JScrollPane scroll;  


    protected JComboBox categoryCombo;   


    public CommonGUI() 
    { 
     //Intializing the instance variables 
     name = new JLabel("Name: "); 
     mobileNumber1 = new JLabel("Mobile Number 1:"); 
     mobileNumber2 = new JLabel("Mobile Number 2: "); 
     address = new JLabel("Address: "); 
     landNumber1 = new JLabel("Land Number 1: "); 
     landNumber2 = new JLabel("Land Number 2: ");  
     nickName = new JLabel("Nick Name: "); 
     email = new JLabel("Email: ");   
     category = new JLabel("Category: "); 

     nameTxt = new JTextField(10); 
     mobileNumber1Txt = new JTextField(10); 
     mobileNumber2Txt = new JTextField(10); 
     addressTxt = new JTextArea(5,20); 
     landNumber1Txt = new JTextField(10); 
     landNumber2Txt = new JTextField(10); 
     categoryTxt = new JTextField(); 
     nickNameTxt = new JTextField(10); 
     emailTxt = new JTextField(10);  

     categoryCombo = new JComboBox();   



     //Adding document listeners to text fields 

     AbstractDocument[]d = new AbstractDocument[8]; 
     d[0] = (AbstractDocument) nameTxt.getDocument(); 
     d[1] = (AbstractDocument) mobileNumber1Txt.getDocument(); 
     d[2] = (AbstractDocument) mobileNumber2Txt.getDocument(); 
     d[3] = (AbstractDocument) addressTxt.getDocument(); 
     d[4] = (AbstractDocument) landNumber1Txt.getDocument(); 
     d[5] = (AbstractDocument) landNumber2Txt.getDocument(); 
     d[6] = (AbstractDocument) categoryTxt.getDocument(); 
     d[7] = (AbstractDocument) nickNameTxt.getDocument(); 

     d[0].setDocumentFilter(new TextFieldValidator(nameTxt,20)); 
     d[1].setDocumentFilter(new TextFieldValidator(mobileNumber1Txt,10)); 
     d[2].setDocumentFilter(new TextFieldValidator(mobileNumber2Txt,10)); 
     d[3].setDocumentFilter(new TextFieldValidator(addressTxt,100)); 
     d[4].setDocumentFilter(new TextFieldValidator(landNumber1Txt,10)); 
     d[5].setDocumentFilter(new TextFieldValidator(landNumber2Txt,10)); 
     d[6].setDocumentFilter(new TextFieldValidator(categoryTxt,20)); 
     d[7].setDocumentFilter(new TextFieldValidator(nickNameTxt,20)); 
    } 

} 

UpdateDeleteForm.java

//Following class get fired when an "category" is selected from the JComboBox. Rest of the code is ommited 

    private class DetailsLoader implements ItemListener 
     { 
      public void itemStateChanged(ItemEvent ie) 
      { 
       if(ie.getStateChange()==ItemEvent.SELECTED) 
       { 
        List details = new ArrayList(); 


        if(nameTxtCombo.getSelectedItem().toString() != "Select a Name") 
        { 
        details = dateBaseConnector.getDetails(nameTxtCombo.getSelectedItem().toString()); 

        String address = (String)details.get(6); 


        idTxt.setText(String.valueOf(details.get(0))); 
        nameTxt.setText((String)details.get(1));      
        mobileNumber1Txt.setText(String.valueOf(details.get(2))); 
        mobileNumber2Txt.setText(String.valueOf(details.get(3))); 
        landNumber1Txt.setText(String.valueOf(details.get(4))); 
        landNumber2Txt.setText(String.valueOf(details.get(5))); 
        addressTxt.setText(address.trim()); 
        //categoryCombo.setSelectedItem((String)details.get(7)); 
        nickNameTxt.setText((String)details.get(8)); 
        emailTxt.setText((String)details.get(9)); 


        } 

       } 
      } 
     } 

TextFieldValidator.java

package normal; 

import java.awt.event.*; 
import java.awt.*; 
import javax.swing.*; 
import javax.swing.text.AttributeSet; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DocumentFilter; 
import javax.swing.text.JTextComponent; 

public class TextFieldValidator extends DocumentFilter 
{ 
    private JTextComponent textField; 
    private int numberOfLetters; 

    public TextFieldValidator(JTextComponent text, int i) 
    { 
     textField = text; 
     numberOfLetters = i; 
    } 

    @Override 
    public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException 
    { 
     if(fb.getDocument().getLength()+string.length()>numberOfLetters) 
     { 
      return; 
     } 

     super.insertString(fb, offset, string, attr); 
    } 

    @Override 
    public void remove(FilterBypass fb, int offset, int length) throws BadLocationException 
    { 
     fb.remove(offset, length); 
    } 

    @Override 
    public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException 
    { 
     if(fb.getDocument().getLength()+text.length()>numberOfLetters) 
     { 
      return; 
     } 

     super.insertString(fb, offset, text, attrs); 
    } 
} 

現在,當我選擇一個類別,它FIL根據在類別中選擇的項目填寫其他文本字段。但是,當我添加documentListener以添加驗證時,setText()方法表現出意外。這意味着想象一下,

  1. 第一次 - 從類別中選擇「大學」。它填寫nameTxt框爲「Yohan」

  2. 第二次 - 現在你需要查看另一個,從類別中選擇「學院」。現在,它應該在名稱文本中顯示「布賴恩」,但不是那樣,它顯示「Brian Yohan」。嗯..「Yohan」沒有從文本字段中刪除!

當我從驗證中刪除documentListener時,一切正常,沒有錯誤。所以,我相信這是我和documentListener做的事情。請幫忙!!

+4

您的預期事件的詳細describtions「請注意,只有相關的代碼顯示」真的嗎?帶有JComboBox和JTextField的[sscce](http://sscce.org)可能就足夠了。 – gontard

+0

好吧,我編輯它 –

+0

我想你是設置DocumentFilter,而不是添加一個DocumentListener,這是兩個獨立的東西。 –

回答

5

的問題是你的replace方法:

@Override 
    public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException 
    { 
     if(fb.getDocument().getLength()+text.length()>numberOfLetters) 
     { 
      return; 
     } 

     super.insertString(fb, offset, text, attrs); 
    } 

你在這裏呼籲super.insertString而不是調用super.replace的。您的setText呼叫將打電話給這個replace方法,並最終插入文本,而不是替換它。

+2

+1發現,鷹眼:-) – kleopatra

+0

我同意,你用顯微鏡看代碼嗎? :-) +1 –

+0

哇!乾淨的鏡頭!非常感謝Nick的幫助:) –

1

當我從驗證中刪除documentListener時,一切正常,沒有錯誤。所以,我相信這是我得到了與的DocumentListener

  1. 我不能看到任何理由與DocumentFilter使用Documentistener一起做,因爲兩者(一起)可發射不盡相同(similair)事件,和中的一個然後調用第二

  2. 基本的東西:

    • DocumentModelJTextComponent小號

    • DocumentListener被指定用於輸出從JTextComponent

    • DocumentFilter爲被輸入或從System Clipboard插入到JTextComponents的不需要的Char(s)過濾,可以創建從Document到的其餘部分的簡單輸出方法或GUI,之後插入或鍵入Char(s)通過

  3. 爲更好地幫助越早張貼SSCCE個,並與來自JComboBoxJTextField和/或反之亦然