Please have a look at the following 3 set of classes. Please note that only relevant code is shown, while rest of the majority is removed.
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);
}
}
Now, when I select an category, it fills up the other text fields according to the item selected in the category. However, when I add the documentListener to add the validations, the setText() methods behave unexpectedly. Which means imagine this,
First Time - Select "University" from the category. It fills the nameTxt box as "Yohan"
Second Time - Now you need to view another one, select "College" from the category. Now, it should show "Brian" in the nameTxt, but instaed of that, it shows "Brian Yohan". hmm.. The "Yohan" hasn't removed from the text field!!
When I remove the documentListener from validation, everything works fine, no errors. So, I believe this is something I got to do with the documentListener. Please help!!
The problem is your replace
method:
@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);
}
You're calling super.insertString
here instead of calling super.replace
. Your setText
call is going to call this replace
method and end up inserting the text instead of replacing it.