2

I have a JTextComponent and I want to invoke a method when user stops editing text in that JTextComponent for a period of time. I was thinking to start a timer every time the model is modified and cancel it if another text edit arrives, but it gives me a feeling that it is not the best desition. Can you share your experience how to implement such behaviour?

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
polis
  • 795
  • 7
  • 23

1 Answers1

4

Yes, that's likely the best decision. You don't even cancel the Timer, but rather just call restart() on the Timer from within your DocumentListener.

e.g., a program that turns the JTextField background red if editing has been inactive for over 2 seconds:

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

@SuppressWarnings("serial")
public class ResetCounter2 extends JPanel {
    private static final int TIMER_DELAY = 2000; // 2 seconds
    public static final Color LATE_BACKGROUND = Color.RED;
    private JTextField textField = new JTextField(10);
    private Timer timer = new Timer(TIMER_DELAY, new TimerListener());

    public ResetCounter2() {
        textField.getDocument().addDocumentListener(new MyDocListener());
        add(textField);

        // make sure timer does not repeat and then start it
        timer.setRepeats(false);
        timer.start();
    }

    private class MyDocListener implements DocumentListener {

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

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

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

        private void docChanged() {
            textField.setBackground(null);
            timer.restart();
        }

    }

    private class TimerListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            textField.setBackground(LATE_BACKGROUND);
        }
    }

    private static void createAndShowGui() {
        ResetCounter2 mainPanel = new ResetCounter2();

        JFrame frame = new JFrame("ResetCounter");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            createAndShowGui();
        });
    }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373