Results 1 to 6 of 6
  1. #1
    matzahboy is offline Member
    Join Date
    Nov 2008
    Posts
    67
    Rep Power
    0

    Default Listen for changes in a JTextField

    In a program, I need to do stuff every time the user changes the text in the JTextField. I was using a DocumentListener, but that does not allow me to modify the JTextField based on the user input. How could I listen for changes in the text, while still being able to modify the JTextField?

  2. #2
    Eranga's Avatar
    Eranga is offline Moderator
    Join Date
    Jul 2007
    Location
    Colombo, Sri Lanka
    Posts
    11,372
    Blog Entries
    1
    Rep Power
    20

  3. #3
    matzahboy is offline Member
    Join Date
    Nov 2008
    Posts
    67
    Rep Power
    0

    Default

    Java Code:
    //a bunch of imports
    
    @SuppressWarnings("serial")
    public class AutoFill extends JFrame implements ListSelectionListener {
    	
    	public static final int TEXT_FIELD_CHARACTERS=30;
    	public static final int NUMBER_OF_SUGGESTIONS=10;
    	public static final int WIDTH=350;
    	public static final int HEIGHT=240;
    	
    	public AutoFill() {
    		setSize(WIDTH, HEIGHT);
    		WindowDestroyer listener = new WindowDestroyer();
    		addWindowListener(listener);
    		
    		inputWordList(); //can take a second or 2
    		Container contentPane = getContentPane();
    		contentPane.setLayout(new FlowLayout());
    		inputText = new JTextField(TEXT_FIELD_CHARACTERS);
    		contentPane.add(inputText);
    		
    		suggestions = new JList();
    		suggestions.setVisibleRowCount(-1);
    		suggestions.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
    		suggestions.setLayoutOrientation(JList.HORIZONTAL_WRAP);
    		suggestions.addListSelectionListener(this);
    		listScroller = new JScrollPane(suggestions);
    		listScroller.setPreferredSize(new Dimension(WIDTH-20, HEIGHT-70));
    		contentPane.add(listScroller);
    		inputListener = new inputFieldChangeListener();
    		inputText.getDocument().addDocumentListener(inputListener);
    	}
    	
    	private WordList words;
    	private JTextField inputText;
    	private JList suggestions;
    	private JScrollPane listScroller;
    	private String foundWord;
    	private inputFieldChangeListener inputListener;
    	
    	private void inputWordList() {
    		//method used to import the word list. I commented it out for here because it is irrelevant to the GUI
    	}
    	
    	private void setSuggestions(String[] possibleWords) {
    		if (foundWord!=null){
    			String[] theWord = {foundWord};
    			suggestions.clearSelection();
    			suggestions.setListData(theWord);
    		} else if(possibleWords!=null) {
    			suggestions.setListData(possibleWords);
    			//Here lies the source of the problem. How do I update the inputText field? The following commented out code does not work because the document listener cannot modify the source document (throws an error)
    			/*if(possibleWords.length==1) {
    				foundWord=possibleWords[0];
    				inputText.setText(null);
    				inputText.setText(foundWord);
    			}*/
    		}
    	}
    
    	private class inputFieldChangeListener implements DocumentListener {
    		@Override
    		public void changedUpdate(DocumentEvent e) {
    			//no need to do anything
    		}
    
    		@Override
    		public void insertUpdate(DocumentEvent e) {
    			updateInput(e);
    		}
    
    		@Override
    		public void removeUpdate(DocumentEvent e) {
    			updateInput(e);
    		}
    	
    		private void updateInput(DocumentEvent e) {
    			Document doc = (Document)e.getDocument();
    			int length = doc.getLength();
    			try {
    				String input = doc.getText(0, length);
    				if(input.length()>0) {
    					if(input.charAt(0)=='\n')
    						input=input.substring(1);
    					if(!input.equalsIgnoreCase(foundWord)) {
    						foundWord=null;
    						setSuggestions(words.getPossibleWords(input));
    					}
    					else {
    						setSuggestions(null);
    					}
    				}
    			}
    			catch(BadLocationException excep) {
    				System.out.println("error");
    			}
    		}
    	}
    	
    	//should only be 1 changed value (since selection is 1)
    	@Override
    	public void valueChanged(ListSelectionEvent e) {
    		String selected = (String)suggestions.getSelectedValue();
    		if(selected!=null) {
    			foundWord=selected;
    			inputText.setText(null);
    			inputText.setText(foundWord);
    		}
    	}
    	
    	public static void main(String [] args) {
    		AutoFill gui = new AutoFill();
    		gui.setVisible(true);
    	}
    }
    Look at the SetSuggestions method. When there is only 1 possible word left, it needs to change the JTextField to that. The problem is that the documentListener will not let me do so.
    Last edited by matzahboy; 10-13-2009 at 04:46 AM. Reason: clarify

  4. #4
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,236
    Rep Power
    7

    Default

    We are not mind readers. What exactly is the problem? Do you get a compiler error, a runtime error?

  5. #5
    matzahboy is offline Member
    Join Date
    Nov 2008
    Posts
    67
    Rep Power
    0

    Default

    It's a runtime error:

    Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to mutate in notification
    at javax.swing.text.AbstractDocument.writeLock(Unknow n Source)
    at javax.swing.text.AbstractDocument.replace(Unknown Source)
    at javax.swing.text.JTextComponent.setText(Unknown Source)
    at AutoFill.setSuggestions(AutoFill.java:96)
    at AutoFill.access$3(AutoFill.java:86)
    at AutoFill$inputFieldChangeListener.updateInput(Auto Fill.java:128)
    at AutoFill$inputFieldChangeListener.insertUpdate(Aut oFill.java:110)
    at javax.swing.text.AbstractDocument.fireInsertUpdate (Unknown Source)
    at javax.swing.text.AbstractDocument.handleInsertStri ng(Unknown Source)
    at javax.swing.text.AbstractDocument.insertString(Unk nown Source)
    at javax.swing.text.PlainDocument.insertString(Unknow n Source)
    at javax.swing.text.AbstractDocument.replace(Unknown Source)
    at javax.swing.text.JTextComponent.replaceSelection(U nknown Source)
    at javax.swing.text.DefaultEditorKit$DefaultKeyTypedA ction.actionPerformed(Unknown Source)
    at javax.swing.SwingUtilities.notifyAction(Unknown Source)
    at javax.swing.JComponent.processKeyBinding(Unknown Source)
    at javax.swing.JComponent.processKeyBindings(Unknown Source)
    at javax.swing.JComponent.processKeyEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.KeyboardFocusManager.redispatchEvent(Unkn own Source)
    at java.awt.DefaultKeyboardFocusManager.dispatchKeyEv ent(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.preDispatchKe yEvent(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAsse rtions(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent (Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilter s(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(U nknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarch y(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

  6. #6
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,236
    Rep Power
    7

    Default

    You need to wrap your code in the DocumentListener in a SwingUtilities.invokeLater(...). This will add the code to the end of the EDT so that it executes after the Document has been completely updated.

Similar Threads

  1. Replies: 3
    Last Post: 05-22-2011, 03:16 PM
  2. JTextField
    By gancio in forum AWT / Swing
    Replies: 20
    Last Post: 08-26-2009, 03:11 PM
  3. Cannot Listen TAB key
    By sh4dyPT in forum AWT / Swing
    Replies: 5
    Last Post: 07-16-2009, 01:45 PM
  4. Replies: 1
    Last Post: 01-30-2009, 06:44 PM
  5. how to listen for buttons between jpanels?
    By pjr5043 in forum New To Java
    Replies: 17
    Last Post: 09-29-2008, 03:37 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •