1

What's the best way to get a value of a TextArea after a key is typed, including this character?

If I do it in the even listener, textarea.getText() returns the value without the eventual new char.

Basically I see two ways:

  1. postponing processing with something like invokeLater(). I would prefer a solution without threads.

  2. figuring out where to put the char into the text, based on the carret position.

Is there any other, simpler?

Thanks.

Edit: This is what I have:

JTextArea textarea = (JTextArea) evt.getComponent();
String texySource = textarea.getText();
char keyCode = evt.getKeyChar();
//if( Character.isLetterOrDigit( keyCode ) || Character.isSpaceChar( keyCode )  )
if( keyCode >= 0x20 || keyCode == 0x0A || keyCode == 0x0D  ){
    // TODO: The carret doesn't have to be at the end...
    //texySource += Character.toString( evt.getKeyChar() );

    String ch = Character.toString( evt.getKeyChar() );
    texySource = StringUtils.overlay(texySource, ch,
    textarea.getSelectionStart(),
    textarea.getSelectionStart()    );
}
Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277
  • Check http://stackoverflow.com/questions/1252698/how-can-i-know-when-the-text-of-an-editable-jcombobox-has-been-changed for some possible insights. – Lawrence Dol Jan 26 '10 at 02:07
  • 1
    What exactly is it you want to achieve? – objects Jan 26 '10 at 03:07
  • 1
    I want to get the text with the char (which user just typed) included. – Ondra Žižka Jan 26 '10 at 03:46
  • 1
    Do you want to get it only specifically for "key typed" - or do you want to get any text added - for example, copy-pasted into the text area? - if it's the second you can use @shemnon's DocumentListener example without all the "arming/disarming" thread stuff. – Nate Jan 26 '10 at 04:43

3 Answers3

2

Have you considered a document listener? possibly armed by the typing event?

class TheListener implements DocumentListener, KeyListener {
  boolean armed;

  void keyPressed(KeyEvent ignore) { }
  void keyReleased(KeyEvent ignore) { }
  void keyTyped(KeyEvent e) {
    armed = true;
    SwingUtilities.invokeLater(new Runnable() { public void run() {
      armed = false;
    }
  }

  void deleteUpdate(DocumentEvent e) {
    changeUpdate(e);
  }
  void insertUpdate(DocumentEvent e) {
    changeUpdate(e);
  }
  void changedUpdate(DocumentEvent e) {
    if (armed) {
      String s = ((JTextComponent)e.getSource()).getText();
      //.... whatever you want to do now
    }
  }
}

//...
TheListener aListener = new TheListener();
textArea.addKeyListener(aListener);
textArea.getDocument().addDocumentListener(aListener);

The theory is to arm the document change listener on a key typed, then add an EDT event to disarm it. The document changes will occur first before disarmed. Once armed, you can assume that any document changes were caused in some part by the key typing event. (warning, I haven't compiled this code, YMMV).

shemnon
  • 5,318
  • 4
  • 28
  • 37
  • This has two drawbacks - 1) it introduces a thread, so I guess I would have to sync, 2) it's not simpler ;-) But the `getDocument()` is a good point, I will remember that for later... – Ondra Žižka Jan 26 '10 at 03:54
1

You need to use a DocumentListener and wirte your code in one of the xxxupdate() methods.

Suraj Chandran
  • 24,433
  • 12
  • 63
  • 94
0

Have you tried registering a KeyListener with a custom implementation of keyReleased(KeyEvent e) ?

check the api here: KeyListener

sun's tutorial with examples: How to write a Key Listener

fasseg
  • 17,504
  • 8
  • 62
  • 73