Как сделать разницу между textField.setText () и добавление текста в текстовое поле вручную в java?

У меня есть текстовое поле в моем приложении, которое будет инициировано программно (textField.setText ()), когда пользователь щелкнул элемент в JList. позже пользователь изменит это значение вручную. Я застрял с использованием document-listener для обнаружения изменений в этом текстовом поле. Когда изменения происходят программно, он не должен ничего делать, но если это происходит вручную,он должен изменить фон на красный.

как определить, было ли заполнено текстовое поле вручную или объект TextField.setText ()?

txtMode.getDocument().addDocumentListener(new DocumentListener() {
        public void insertUpdate(DocumentEvent e) {
            if (!mode.equals(e.getDocument()))
            txtMode.setBackground(Color.red);
        }

        public void removeUpdate(DocumentEvent e) {
            if (mode.equals(e.getDocument()))
            txtMode.setBackground(Color.white);              
        }

        public void changedUpdate(DocumentEvent e) {
            //To change body of implemented methods
        }
    });

2 ответов


есть два способа

  • удалить DocumentListener до setText("...") добавить DocumentListener обратно, если сделать

код

public void attachDocumentListener(JComponent compo){
      compo.addDocumentListener(someDocumentListener);
}

//similair void for remove....
  • использовать boolean значение для отключения "при необходимости", но вы должны изменить содержание вашего DocumentListener
 txtMode.getDocument().addDocumentListener(new DocumentListener() {
    public void insertUpdate(DocumentEvent e) {
        if (!mode.equals(e.getDocument()))

        if (!updateFromModel){
           txtMode.setBackground(Color.red);
        }  
    }

    public void removeUpdate(DocumentEvent e) {
        if (mode.equals(e.getDocument()))

        if (!updateFromModel){
           txtMode.setBackground(Color.white);
        }  
    }

    public void changedUpdate(DocumentEvent e) {
        //To change body of implemented methods
    }
});

имейте в виду, что все прослушиватели событий выполняются в потоке событий Swing. Таким образом, все может идти не в том порядке, как вы хотите. В этой ситуации любое решение будет hack-ish, потому что вы не можете получить полный контроль над потоком swing и кто публикует события на нем.

Я пытаюсь сказать следующее: предположим, вы решили использовать какой-то флаг, чтобы ваши слушатели знали, что это программное изменение. Вот возможный сценарий (я предполагаю, что вы после хорошее правило делать любые обновления пользовательского интерфейса из потока swing через invokeLater):

  1. установите флаг для пропуска событий
  2. помощью setText
  3. установите флаг в false

если вы сделаете все это за один вызов, setText вызовет события обновления, размещенные в конце очереди событий, таким образом, к моменту их выполнения флаг уже будет false.

Итак, вы должны сделать Шаг 1 и 2 в одном invokeLater вызова, или даже invokeAndWait, а затем пост еще одно событие с invokeLater снять флаг. И молитесь, чтобы ваш пользователь не так быстро, чтобы внести некоторые изменения между этими двумя вызовами, иначе они также будут считаться программными изменениями.