gpt4 book ai didi

java - 当发生文本更改事件时获取父文本组件

转载 作者:行者123 更新时间:2023-12-01 13:53:19 24 4
gpt4 key购买 nike

我查遍了,每个人都说当你想听 JTextField 的文本更改时或其他 swing 文本组件,请使用 DocumentListener在基础文件上。但这对我没有帮助,因为我需要知道正在使用该文档的组件,并且需要对其采取行动。 DocumentEvent知道哪个文档触发了它,但事件或文档都不知道“父”组件是什么。 IIRC,这是因为给定文档可以有多个“父文档”。这是我想要实现的目标的示例。

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

当文本更改事件来自键盘交互时,上面的方法非常有用。但如果我这样做txtTwo.setText("asdfasdf");它不会向该监听器发送任何内容。使用ActionListener更糟糕的是,因为在大多数情况下它仅在按下回车键时才会触发。使用DocumentListener至少会捕获每个文本更改,但似乎也不起作用,除非我错过了一些东西。

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

我需要共享一个监听器,因为最终将有数百个组件可能会使用此监听器及其功能。我不会将其复制数百次并将每个硬编码到特定组件。

最佳答案

您对 DocumentListener 做了错误的事情。每个 TextComponent 都有自己的 Document 作为其数据模型。您不能将 DocumentListener 添加到 TextComponent,而是添加到 Document,并且文档事件源是 Document,而不是文本组件。

((JTextFieldWithLabel) e.getSource()).setEnabled(true); //won't work

是的,因为 DocumentEvent 没有这样的函数。那么您可以使用 jTextFeild.getDocument().putProperty("owner", jTextFeild); 来跟踪文档所有者的文本字段。如果您担心 JTextFeild 的文档更改,请使用 "document" 的实现 PropertyChangeListener ,就像使用 JTextComponent.setDocument() 一样 函数总是会触发属性更改事件,我们需要做的就是监听此事件并将我们的 DocumentListener"owner" 属性重新附加到它:

    class MyDocumentListener implements DocumentListener{

public void updateComponent(DocumentEvent e)
{
boolean valid = checkDataValidity(e.getDocument());
JTextField txtField = (JTextField) e.getDocument().getProperty("owner");

if(!valid)
txtField.setEnabled(false);
else txtField.setEnabled(true);
}

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

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

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

class MyPropChangeListener implements PropertyChangeListener{

DocumentListener documentListenr;

public MyPropChangeListener(DocumentListener documentListener) {
this.documentListenr = documentListener;
}

@Override
public void propertyChange(PropertyChangeEvent evt) {
System.out.println("chaning document!!");
JTextField txtFeild = (JTextField)evt.getSource();
txtFeild.getDocument().putProperty("owner", txtFeild);
txtFeild.getDocument().addDocumentListener(documentListenr);
}
}
//..............

MyPropChangeListener propChangeListener = new MyPropChangeListener(new MyDocumentListener());

jTextField1.addPropertyChangeListener("document", propChangeListener);
jTextField1.setDocument(new PlainDocument());

jTextField2.addPropertyChangeListener("document", propChangeListener);
jTextField2.setDocument(new PlainDocument());

虽然我建议使用 InputVerifierDocumentListener 一起用于文本数据更改时的数据验证。 InputVerifierboolean verify() 用于数据验证检查。它还有另一个函数 shouldYieldFocus:当它注册的组件将失去焦点时调用该函数,并且仅当该方法返回 true 时焦点才会转移。实际上,shouldYieldFocus 使用 verify() 函数返回的 boolean 来决定是否转移焦点。

关于java - 当发生文本更改事件时获取父文本组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19795872/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com