【问题标题】:PropertyChangeListener requestFocus issuePropertyChangeListener requestFocus 问题
【发布时间】:2014-04-02 00:10:15
【问题描述】:

全新方向

以下是我的问题的 SSCCE。我正在尝试在输入输入时更新字段,在这种情况下,必须失去焦点才能进行更新。

package test;
import java.awt.EventQueue;
import java.text.NumberFormat;
import javax.swing.JFormattedTextField;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import javax.swing.text.NumberFormatter;

public class Test {

    private JFormattedTextField input, input2;
    private NumberFormatter formatter;
    private DocumentListener listener;

    public Test() {
        formatter = new NumberFormatter(NumberFormat.getNumberInstance());
        input = new JFormattedTextField(formatter);
        input2 = new JFormattedTextField(formatter);

        listener = new DocumentListener() {

            private Document source = null;

            protected void update(Document doc) {
                if (source == null) {
                    System.out.println("Update");
                    source = doc;
                    if (source.equals(input.getDocument())) {
                        double temp;
                        temp = converter(((Number)input.getValue()).doubleValue());
                        input2.setValue(temp);
//                        input2.setText(Double.toString(temp));
                    } else if (source.equals(input2.getDocument())) {                       
                        double temp;
                        temp = converterBack(((Number)input2.getValue()).doubleValue());
                        input.setValue(temp);
//                        input.setText(Double.toString(temp));
                    }
                    source = null;
                }
            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                update(e.getDocument());
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                update(e.getDocument());
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                update(e.getDocument());
            }
        };

        input.getDocument().addDocumentListener(listener);
        input2.getDocument().addDocumentListener(listener);
        input.setColumns(4);
        input2.setColumns(4);
        input.setValue(0.0);
        JPanel panel = new JPanel();
        panel.add(input);
        panel.add(input2);

        JOptionPane.showMessageDialog(null, panel);
    }

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Test();
            }
        });

    }

    private double converter(double value) {
        value = value * 2;

        return value;
    }
    private double converterBack(double value){
        value = value/2;
        
        return value;
    }
}

我需要能够将此代码与“转换器”method 一起使用,因此不能将命令放入 method Update()

我已经让这个与 PropertyChangeListener 一起工作,但显然这不是一个好方法。

【问题讨论】:

  • 还没有真正看过你的代码,但这似乎是DocumentListener而不是PropertyChangeListener的工作
  • @peeskillet 由于某种原因 DocumentListener 在这种情况下对我不起作用。我的意思是说它有效,但前提是我按下回车键。
  • @Eric 那么你没有使用DocumentListener...
  • @eric,您在上一个问题 (stackoverflow.com/questions/22776172/…) 中没有理解使用 DocumentLIstener 的哪一部分?为什么你没有发布一个 SSCCE 来展示你是如何尝试使用 DocumentListener 的?

标签: java swing jformattedtextfield propertychangelistener


【解决方案1】:

PropertyChangeListener 无法解决此问题,因为该字段的 Document 不会引发事件...Document 是该字段的属性,但它的内容不是。

更好的解决方案是使用DocumentListener。这将在基础文档内容发生更改时发出通知。

您需要小心这一点,因为 Document 不喜欢在它已经进行更改时被更改。

在本例中,我使用事件的源 Document 并将其与每个字段 Document 进行比较以确定应该更新的内容...

import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.text.NumberFormat;
import javax.swing.JFormattedTextField;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import javax.swing.text.NumberFormatter;

public class Test {

    private JFormattedTextField input, input2;
    private NumberFormatter formatter;
//    private PropertyChangeListener listener;
    private DocumentListener listener;

    public Test() {
        formatter = new NumberFormatter(NumberFormat.getNumberInstance());
        input = new JFormattedTextField(formatter);
        input2 = new JFormattedTextField(formatter);

        listener = new DocumentListener() {

            private Document source = null;

            protected void update(Document doc) {
                if (source == null) {
                    System.out.println("Update");
                    source = doc;
                    if (source.equals(input.getDocument())) {
                        input2.setText(input.getText());
                    } else if (source.equals(input2.getDocument())) {
                        input.setText(input2.getText());
                    }
                    source = null;
                }
            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                update(e.getDocument());
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                update(e.getDocument());
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                update(e.getDocument());
            }
        };
//        listener = new PropertyChangeListener() {
//            @Override
//            public void propertyChange(PropertyChangeEvent evt) {
//                convert(evt);
//            }
//        };

        input.getDocument().addDocumentListener(listener);
        input2.getDocument().addDocumentListener(listener);

        input.setColumns(4);
        input2.setColumns(4);
//        input.addPropertyChangeListener("value", listener);
//        input2.addPropertyChangeListener("value", listener);
        input.setValue(0.0);
        JPanel panel = new JPanel();
        panel.add(input);
        panel.add(input2);

        JOptionPane.showMessageDialog(null, panel);
    }

    private void convert(PropertyChangeEvent evt) {
        if (evt.getSource() == input) {
            if (evt.getSource() != null) {
                double temp;
                temp = converter((Double) evt.getNewValue());
                input2.setValue(temp);
            }

        }

    }

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Test();
            }
        });

    }

    private double converter(double value) {
        value = value * 2;

        return value;
    }

}

更新

您在转换时遇到的问题是该值尚未“提交”,这意味着它尚未经过验证,value 属性尚未更改。

调用getValue 将返回最后提交的值。

您需要做的是先提交编辑...

if (source.equals(input.getDocument())) {
    try {
        input.commitEdit();
        double temp = ((Number) input.getValue()).doubleValue();
        temp = converter(temp);
        input2.setValue(temp);
    } catch (ParseException ex) {
    }

【讨论】:

  • 我想我当时用错了,因为虽然我可以使用 Document 侦听器更新字段,但它们只有在我故意点击离开时才会更新。感谢您的回答
  • 好吧,从头开始,你的程序没有做我想让它做的事情。是范围问题吗?因为我不是简单地尝试复制该字段,而是将其从一个数字转换为另一个数字。
  • 好的...请参阅update 方法...更改它以执行您想要的操作;) - 它是双向的,并且基于已更新的字段/文档。 .
  • @Eric 检查答案的更新以了解问题所在
  • @Eric 我打电话给get/setText 而不是get/setValue。后者要求在更改属性之前先成功提交编辑。
猜你喜欢
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多