java-无法从DocumentListener方法内部更改JTextfield的值

java-无法从DocumentListener方法内部更改JTextfield的值,java,swing,textfield,Java,Swing,Textfield,我得到一个“尝试在通知中变异”异常。 1.我怎样才能改变它? 2.如何获取触发侦听器之前文本字段中的值 编辑: 是这样的。在JTextfield中,我有一个侦听器 basePriceTF.getDocument().addDocumentListener(new DocumentListener(){ public void insertUpdate(DocumentEvent e){ if (Integer.getValue(basePriceTF.getText

我得到一个“尝试在通知中变异”异常。 1.我怎样才能改变它? 2.如何获取触发侦听器之前文本字段中的值

编辑:

是这样的。在JTextfield中,我有一个侦听器

basePriceTF.getDocument().addDocumentListener(new DocumentListener(){ 
     public void insertUpdate(DocumentEvent e){ 
        if (Integer.getValue(basePriceTF.getText())<0){
        basePriceTF.setText("0");
        }
     }

     public void removeUpdate(DocumentEvent e){/**my implemntation**/}

     public void changedUpdate(DocumentEvent e){/**my implemntation**/}
}

insertUpdate() will probably cause a loop.
So it doesnt let me change inside basePriceTF.
basePriceTF.getDocument().addDocumentListener(新DocumentListener(){
公共无效插入更新(文档事件e){

如果根据DocumentListener教程和API使用(Integer.getValue(basePriceTF.getText()),DocumentListener不应该修改文档的内容,因此简短的回答是:不要这样做


考虑使用其他方法,例如DocumentFilter或其他验证方法。

这可能不是一个好的做法,但应该可以工作,并且不涉及任何复杂或昂贵的内容

final Document doc = basePriceTF.getDocument();
basePriceTF.getDocument().addDocumentListener(new DocumentListener(){
     public void insertUpdate(DocumentEvent e){
        if (Integer.getValue(basePriceTF.getText())<0){
            new Thread(new Runnable() {
                public void run() {
                    doc.removeDocumentListener(this);
                    basePriceTF.setText("0");        
                    doc.addDocumentListener(this);
                }
            }).start();
        }     
     }
     .......
final Document doc=basePriceTF.getDocument();
basePriceTF.getDocument().addDocumentListener(新DocumentListener()){
公共作废插入更新(文档事件e){

如果(Integer.getValue(basePriceTF.getText())正如之前三次指出的那样, 这正是
DocumentFilter
s的用途。 下面是一个可以满足您需要的:

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.JTextField;
import javax.swing.text.AbstractDocument;
import javax.swing.text.Document;
import javax.swing.text.DocumentFilter;
import javax.swing.text.BadLocationException;
import javax.swing.text.AttributeSet;

public class TestDocumentFilter extends JFrame {
  JTextField basePriceTF;

public TestDocumentFilter() {
    super("TestDocumentFilter");
    basePriceTF = new JTextField();
    AbstractDocument basePriceDocument = (AbstractDocument) basePriceTF.getDocument();
    basePriceDocument.setDocumentFilter(new PositiveIntegerFilter());
    getContentPane().add(basePriceTF);
}

/**
 * Resets the document to "0" for input values that do not constitut a non-negative integer.
 */
private static class PositiveIntegerFilter extends DocumentFilter {

    @Override
    public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String inputTextValue,
            AttributeSet attrs) throws BadLocationException {
        Document oldDoc = fb.getDocument();
        String textValue = oldDoc.getText(0, oldDoc.getLength()) + inputTextValue;
        Integer basePrice = 0;
        try {
            basePrice = Integer.parseInt(textValue);
        } catch (NumberFormatException e) { 
            basePrice = 0;
        }
        if (basePrice < 0) 
            basePrice = 0;
        fb.replace(0, oldDoc.getLength(), basePrice.toString(), attrs);
    }
}

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame frame = new TestDocumentFilter();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);
        }
    });
}
}
import javax.swing.JFrame;
导入javax.swing.SwingUtilities;
导入javax.swing.JTextField;
导入javax.swing.text.AbstractDocument;
导入javax.swing.text.Document;
导入javax.swing.text.DocumentFilter;
导入javax.swing.text.BadLocationException;
导入javax.swing.text.AttributeSet;
公共类TestDocumentFilter扩展了JFrame{
JTextField-basePriceTF;
公共TestDocumentFilter(){
超级(“TestDocumentFilter”);
basePriceTF=新的JTextField();
AbstractDocument basePriceDocument=(AbstractDocument)basePriceTF.getDocument();
basePriceDocument.setDocumentFilter(新的PositiveIntegerFilter());
getContentPane().add(basePriceTF);
}
/**
*对于不构成非负整数的输入值,将文档重置为“0”。
*/
私有静态类PositiveIntegerFilter扩展了DocumentFilter{
@凌驾
public void replace(DocumentFilter.FilterBypass fb,int offset,int length,String inputTextValue,
AttributeSet attrs)引发BadLocationException{
Document oldDoc=fb.getDocument();
字符串textValue=oldDoc.getText(0,oldDoc.getLength())+inputTextValue;
整数基价=0;
试一试{
basePrice=Integer.parseInt(textValue);
}捕获(数字格式){
基准价格=0;
}
如果(基准价格<0)
基准价格=0;
替换(0,oldDoc.getLength(),basePrice.toString(),attrs);
}
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
JFrame=newtestdocumentfilter();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}

不能输入“-1”;当输入“-”时,该字段将重置为“0”是键入的。请注意
FilterBypass
,它可以避免任何递归调用。

也许一些代码会有帮助。您能以一种格式提供它吗?我通常会以不同的方式提供。我在GUI中有另一个线程从其模块刷新GUI。但是:A.代码太多(与GUI一样)。B.刷新时(所有组件都已刷新)每个组件都进入其侦听器以检查有效性。如果每半秒刷新一次-这对我来说太多了。还有其他建议吗?@user450602:同样可以使用DocumentFilter.+1,@user450602-因为您希望此字段包含整数值,所以应该使用DocumentFilter来确保只包含数字字符不管怎样,您是否已经输入了文本字段。现在您只需添加第二个复选框。如果输入“-”,那么您将用“0”替换所有现有文本。在某处…某处…我也考虑过此解决方案。假设这将是我的最后手段…但无论如何,谢谢。