Q: Multiple similar DocumentListeners using class properties - How to condense them to one listener? I have a class TestListeners, containing some JTextFields and other properties (integers here). I want the properties to update when the corresponding JTextField text changes. Therefore, I added some DocumentListeners, but these listeners do almost exactly the same thing, just the target property is different. The goal is to have only one listener which can be added to all three JTextFields and for each JTextField the corresponding class property should be handled.
I found the following question which helped me get the JTextField dynamically into the listener without having to hardcode them in there:
https://codereview.stackexchange.com/questions/25895/applying-documentlistener-on-multiple-jtextfield
But I can't find a way to dynamically reference the property, which should be changed, in the listener. I'd be glad if somebody could help to find a way.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

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

public class TestListeners extends JFrame {
    Color white = new Color(255, 255, 255);
    Color red = new Color(255, 200, 200);
    JTextField field1 = new JTextField("11111");
    JTextField field2 = new JTextField("22222");
    JTextField field3 = new JTextField("33333");
    int value1 = 0;
    int value2 = 0;
    int value3 = 0;

    public static void main(String[] args) {
        new TestListeners();
    }

    public TestListeners() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(new Dimension(150, 100));
        this.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();

        c.gridx++; this.add(field1, c);
        c.gridx++; this.add(field2, c);
        c.gridx++; this.add(field3, c);

        field1.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void removeUpdate(DocumentEvent e) {
                filterText(field1.getText());
            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                filterText(field1.getText());
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                filterText(field1.getText());
            }

            private void filterText(String text) {
                try {
                    value1 = Integer.parseInt(text);
                    field1.setBackground(white);
                    System.out.println("value1 = " + value1);
                } catch (NumberFormatException ex) {
                    System.out.println("text in field1 is not an integer");
                    field1.setBackground(red);
                }
            }
        });

        field2.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void removeUpdate(DocumentEvent e) {
                filterText(field2.getText());
            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                filterText(field2.getText());
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                filterText(field2.getText());
            }

            private void filterText(String text) {
                try {
                    value2 = Integer.parseInt(text);
                    field2.setBackground(white);
                    System.out.println("value2 = " + value2);
                } catch (NumberFormatException ex) {
                    System.out.println("text in field2 is not an integer");
                    field2.setBackground(red);
                }
            }
        });

        field3.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void removeUpdate(DocumentEvent e) {
                filterText(field3.getText());
            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                filterText(field3.getText());
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                filterText(field3.getText());
            }

            private void filterText(String text) {
                try {
                    value3 = Integer.parseInt(text);
                    field3.setBackground(white);
                    System.out.println("value3 = " + value3);
                } catch (NumberFormatException ex) {
                    System.out.println("text in field3 is not an integer");
                    field3.setBackground(red);
                }
            }
        });

        this.setVisible(true);
    }
}


A: You are using anonymous classes to implement your DocumentListner.
You can of course create a new class
public class MyDocumentListener implements DocumentListner {

  public MyDocumentListener (TestListeners parentFrame) {
     // either via getter or in your example:

     parentFrame.value3 = 123; // value3 is packed protected.
  }
 // copy paste your methods here.
}

You will have to pass a reference to your GUI items you want to change to a new instance of MyDocumentListener. 
Note that you have member variables without any modifier. Thus this member are packet protected. As long as your new class is in the same packed as TestListeners you can access them without a getter. Otherwise implement getter and setter for this values.
You can do this by implementing a proper constructor.
You can add then the DocumentListner like this:
field3.getDocument().addDocumentListener(new MyDocumentListner(this));

We have to pass "this" to the new instance of MyDocumentListner so new listener is able to access fields from it.

Or you can create an object consisting of your anonymous classes:
DocumentListner myListener = new DoucmentListener {
  // implement your methods here
}

Then you can pass the DocumentListener to your fields like this:
field3.getDocument().addDocumentListener(myListener);


A: Start by focusing on what is common between the listeners, they verify the state of JTextField, but they also maintain the last valid value.
So, you need a listener which can get the text from a JTextField, can change it's state, depending on the current text and which can maintain the last valid value, something like...
public class VerifyHandler implements DocumentListener {

    private int value;
    private JTextField field;

    public VerifyHandler(JTextField field) {
        this.field = field;
    }

    public int getValue() {
        return value;
    }

    @Override
    public void insertUpdate(DocumentEvent e) {
        filterText();
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        filterText();
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
        filterText();
    }

    private void filterText() {
        try {
            value = Integer.parseInt(field.getText());
            field.setBackground(white);
        } catch (NumberFormatException ex) {
            field.setBackground(red);
        }
    }

}

Now, frankly, this seems like a lot of work for something that has already been implemented.
For example, you could use a JSpinner or JFormattedTextField or event a DocumentFilter to prevent the user from ever entering anything other then what you want. 
See:


*

*How to Use Spinners

*How to Use Formatted Text Fields

*Implementing a Document Filter and DocumentFilter Examples
for more details
