使用类属性的多个类似DocumentListeners - 如何将它们压缩到一个侦听器?

时间:2016-01-03 23:02:44

标签: java swing jtextfield documentlistener

我有一个类TestListeners,包含一些JTextFields和其他属性(这里是整数)。我希望在相应的JTextField文本更改时更新属性。因此,我添加了一些DocumentListeners,但这些监听器几乎完全相同,只是目标属性不同。目标是只有一个可以添加到所有三个JTextField的侦听器,并且对于每个JTextField,应该处理相应的类属性。

我发现以下问题帮助我将JTextField动态地引入侦听器而无需在其中进行硬编码:

https://codereview.stackexchange.com/questions/25895/applying-documentlistener-on-multiple-jtextfield

但是我无法在侦听器中找到一种方法来动态引用应该更改的属性。如果有人能帮忙找到方法,我会很高兴。

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);
    }
}

2 个答案:

答案 0 :(得分:3)

您正在使用匿名类来实施DocumentListner

您当然可以创建一个新类

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.
}

您必须将要更改的GUI项目的引用传递给MyDocumentListener的新实例。

请注意,您有没有任何修饰符的成员变量。因此,该成员受数据包保护。只要您的新课程与TestListeners相同,您就可以在没有getter的情况下访问它们。否则为此值实现getter和setter。

您可以通过实现适当的构造函数来实现此目的。

您可以像这样添加DocumentListner

field3.getDocument().addDocumentListener(new MyDocumentListner(this));

我们必须通过"这个"到MyDocumentListner的新实例,以便新的侦听器能够从中访问字段。

或者您可以创建一个由您的匿名类组成的对象:

DocumentListner myListener = new DoucmentListener {
  // implement your methods here
}

然后您可以将DocumentListener传递到您的字段:

field3.getDocument().addDocumentListener(myListener);

答案 1 :(得分:2)

首先关注听众之间的共同点,他们验证JTextField的状态,但它们也保持最后的有效值。

因此,您需要一个可以从JTextField获取文本的侦听器,可以根据当前文本更改它的状态,并且可以保持最后一个有效值,例如......

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);
        }
    }

}

现在,坦率地说,对于已经实施的内容,这似乎有很多工作要做。

例如,您可以使用JSpinnerJFormattedTextField或事件DocumentFilter来阻止用户输入您想要的任何内容。

请参阅:

了解更多详情