我有一个类TestListeners
,包含一些JTextFields和其他属性(这里是整数)。我希望在相应的JTextField文本更改时更新属性。因此,我添加了一些DocumentListeners,但这些监听器几乎完全相同,只是目标属性不同。目标是只有一个可以添加到所有三个JTextField的侦听器,并且对于每个JTextField,应该处理相应的类属性。
我发现以下问题帮助我将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);
}
}
答案 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);
}
}
}
现在,坦率地说,对于已经实施的内容,这似乎有很多工作要做。
例如,您可以使用JSpinner
或JFormattedTextField
或事件DocumentFilter
来阻止用户输入您想要的任何内容。
请参阅:
了解更多详情