简体   繁体   中英

Why does insertUpdate get called in my DocumentListener when I change focus? (Java Swing)

I have a JTextField with a documentListener on it. I want to change the background color when I add or remove characters to this textfield. I should be using a document listener correct? It works, but it also fires when I gain and lose focus on this JTextfield, which is undesired. I do not add a focus listener on this JTextField. Here is my code, any suggestions on how I can fix my problem?

        numPlotRowsJTextField = BasicComponentFactory.createIntegerField(valueModelNumberPlotRowsJTextField);
        numPlotRowsJTextField.getDocument().addDocumentListener(new DocumentListener() {

        @Override
        public void removeUpdate(DocumentEvent e) 
        {
        }

        @Override
        public void insertUpdate(DocumentEvent e) 
        {
            numPlotRowsJTextField.setBackground(Color.cyan);
        }

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

Also note that I am using JGoodies Binding which I am starting to believe is the root of this problem. Swing w/o JGoodies shouldn't be firing off document listener events by changing focus...

You must have something looking at the focus or you think it is firing and it is not.

I took your code and made a complete example and it does not have the problem you describe.

        JFrame frame = new JFrame();
    final JTextField numPlotRowsJTextField = new JTextField(3);
    numPlotRowsJTextField.getDocument().addDocumentListener(new DocumentListener() {
        @Override
        public void changedUpdate(DocumentEvent e) {
        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            numPlotRowsJTextField.setBackground(Color.cyan);
        }

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

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(100, 100);
    frame.getContentPane().setLayout(new FlowLayout());
    frame.getContentPane().add(new JTextField(2));
    frame.getContentPane().add(numPlotRowsJTextField);
    frame.setVisible(true);

Have you looked at the DocumentEvent to see what information it contains? Does it actually contain a string that has changed. Or is it just an event with a 0 length string. If it is the latter then maybe you can just ignore that case.

I figured it out. It 100% had to do with JGoodies Binding.

This code works:

ValueModel valueModelNumberPlotRowsJTextField = adapter.getBufferedModel("numberOfPlotRows");
    valueModelNumberPlotRowsJTextField.addValueChangeListener(new PropertyChangeListener() {

        @Override
        public void propertyChange(PropertyChangeEvent evt) 
        {
            numPlotRowsJTextField.setBackground(Color.cyan);
        }
    });
    numPlotRowsJTextField = BasicComponentFactory.createIntegerField(valueModelNumberPlotRowsJTextField);

Since I am using JGoodies Binding, I have a ValueModel backing my JTextField. The listener has to be set there and not on the JTextField.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM