更改文本字段的值,因为另一个文本字段已更改且相同但颠倒导致错误

changing the value of a text field as another is changed and the same but reversed causing an error

我正在制作一个简单的英里-公里转换器,它会在您键入时自动更新。问题是某处抛出错误。我相信这是因为当我更改其中一个字段时,它会处理事件并更改另一个字段,但是因为它也有一个事件处理程序,当它被更改时它会尝试更改另一个字段本身并且它们会继续触发事件并且直到某处发生爆炸。知道我该如何解决这个问题或者是否存在完全不同的问题?

这是我的代码:

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;


public class Book extends JFrame{
    private JTextField jtfKilometers = new JTextField(10);
    private JTextField jtfMiles = new JTextField(10);

    public Book(){
        setLayout(new BorderLayout(10, 0));

        JPanel jlblPanel = new JPanel(new GridLayout(2, 0, 50, 5));
        jlblPanel.add(new JLabel("Kilometers"));
        jlblPanel.add(new JLabel("Miles"));
        add(jlblPanel, "West");

        JPanel jtfPanel = new JPanel(new GridLayout(2, 0, 5, 5));
        jtfPanel.add(jtfKilometers);
        jtfPanel.add(jtfMiles);
        add(jtfPanel, "Center");

        jtfKilometers.getDocument().addDocumentListener(new DocumentListener(){

            @Override
            public void insertUpdate(DocumentEvent e) {
                if(jtfKilometers.getText().equals("")){
                    jtfMiles.setText("");
                }else{
                    jtfMiles.setText(Double.parseDouble(jtfKilometers.getText()) * 0.621371 + "");
                }
            }

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

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

        jtfMiles.getDocument().addDocumentListener(new DocumentListener(){

            @Override
            public void insertUpdate(DocumentEvent e) {
                if(jtfMiles.getText().equals("")){
                    jtfKilometers.setText("");
                }else{
                    jtfKilometers.setText(Double.parseDouble(jtfMiles.getText()) * 1.60934 + "");
                }
            }

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

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

    }

    public static void main(String[] args){
        Book f = new Book();
        f.setDefaultCloseOperation(MyFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

您需要在文本字段的焦点上添加额外的保护,这样您将只修改另一个文本字段,而不是递归地修改它们。

jtfKilometers.getDocument().addDocumentListener(new DocumentListener() {

@Override
public void insertUpdate(DocumentEvent e) {
    if (jtfKilometers.hasFocus()) { // ADD THIS LINE
        if (jtfKilometers.getText().equals("")) {
            jtfMiles.setText("");
        } else {
            jtfMiles.setText(Double.parseDouble(jtfKilometers.getText()) * 0.621371 + "");
        }
    }
}

同样

jtfMiles.getDocument().addDocumentListener(new DocumentListener() {

    @Override
    public void insertUpdate(DocumentEvent e) {
        if (jtfMiles.hasFocus()) { // ADD THIS LINE
            if (jtfMiles.getText().equals("")) {
                jtfKilometers.setText("");
            } else {
                jtfKilometers.setText(Double.parseDouble(jtfMiles.getText()) * 1.60934 + "");
            }
        }
    }

一个简单的解决方法是在触发事件时检查框架是否有焦点。这将防止事件像现在发生在你身上那样来回触发。

请参阅下面示例中调整后的代码片段...

           public void insertUpdate(DocumentEvent e) {
            if(jtfMiles.hasFocus()){//Check for focus here....repeat same check on your other "insertUpdate" method for your other frame.
                if(jtfMiles.getText().equals("")){
                    jtfKilometers.setText("");
                }else{
                    jtfKilometers.setText(Double.parseDouble(jtfMiles.getText()) * 1.60934 + "");
                }
            }
        }

希望对您有所帮助!