I've looked all over and everyone says that when you want to listen to text changes for a JTextField
, or other swing text component, use a DocumentListener
on the underlying document. This doesn't help me though because I need to know the component that is using the document, and need to act on it. The DocumentEvent
knows what document fired it but the event, nor the document, know what the "parent" component is. IIRC, this is because there can be more than one "parent" for a given document. Here's an example of what I am trying to accomplish.
JTextField txtOne = new JTextField();
JTextField txtTwo = new JTextField();
etc...
KeyListener validator = new KeyListener(){
public void updateComponent(KeyEvent e) {
//The line below CAN be accomplished with a docuement listener
//by grabbing the text of the document.
boolean valid = validationMethod(((JTextField) e.getSource()).getText());
if (valid) {
//This CANNOT be accomplished with a document listener because
//the document doesn't know what component is using it.
((JTextField) e.getSource()).setEnabled(true);
} else {
((JTextField) e.getSource()).setEnabled(false);
}
}
public void keyPressed(KeyEvent e) {updateComponent(e);}
public void keyReleased(KeyEvent e) {updateComponent(e);}
public void keyTyped(KeyEvent e) {updateComponent(e);}
};
txtOne.addKeyListener(validator);
txtTwo.addKeyListener(validator);
etc...
The above works great for when text change events come from keyboard interaction. But if I were to do txtTwo.setText("asdfasdf");
it won't fire anything to that listener. Using an ActionListener
is even worse because it only fires when the enter key is pressed in most cases. Using a DocumentListener
will at least capture every text change, but doesn't seem to work either, unless I'm missing something.
JTextField txtOne = new JTextField();
JTextField txtTwo = new JTextField();
etc...
DocumentListener validator = new DocumentListener() {
public void updateComponent(DocumentEvent e) {
boolean valid = validationMethod(e.getDocument().getText(0,
e.getDocument().getLength()));
if (valid) {
//The event has no getSource, only getDocument. The document likewise
//has no idea what the component is that is using this document.
((JTextFieldWithLabel) e.getSource()).setEnabled(true); //won't work
} else {
//no idea what i could do here....
((JTextFieldWithLabel) e.getSource()).setEnabled(false); //won't work
}
}
public void removeUpdate(DocumentEvent e) {updateComponent(e);}
public void insertUpdate(DocumentEvent e) {updateComponent(e);}
public void changedUpdate(DocumentEvent e) {updateComponent(e);}
};
txtOne.getDocument().addDocumentListener(validator);
txtTwo.getDocument().addDocumentListener(validator);
etc...
I need to share a listener because in the end there will be hundreds of components that could potentially use this listener and its functions. I'm not going to copypasta it hundreds of times and hard code each to a specific component.