How to make the difference between textField.setText () and adding text to textField manually in java?

I have a textField in my application that will be initiated programmatically (textField.setText ()) when the user clicks on an element in a JList. later, the user will change this value manually. I am stuck with a document-listener to detect changes in this text box. When changes happen programmatically, it should not do anything, but if it happens manually, it should change the background to red.

How to determine if a textField was manually populated or 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 } }); 
+7
source share
2 answers

There are two ways:

  • remove DocumentListener to setText("...") add DocumentListener back if done

code

 public void attachDocumentListener(JComponent compo){ compo.addDocumentListener(someDocumentListener); } //similair void for remove.... 
  • use the boolean value to disable "if necessary", but you need to change the contens of your DocumentListener

eg

  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 } }); 
+8
source

Keep in mind that all event listeners are executed in the Swing event stream. So things may not go exactly as you want. In this situation, any decision will be hack-ish, because you cannot get full control over the swing stream and who posts events on it.

I am trying to say the following: suppose you decide to use some flag so that your listeners know that these are programmatic changes. Here is a possible scenario (I assume that you are following the correct rule to do any UI updates from the swing stream via invokeLater ):

  • set flag to skip events
  • Settext
  • set flag to false

if you do all this in one call, setText will trigger update events sent to the end of the event queue, so the flag will be false by the time they are executed.

So you have to do steps 1 and 2 in one invokeLater call or even invokeAndWait , and then send another event using invokeLater to disable the flag. And pray that your user doesn’t make some changes between these two calls so quickly, otherwise they will also be considered as program changes.

+4
source

All Articles