0

I have a JTextArea called taMessage which displays a message string. This string can be edited by the user at run time.
I have a JLabel lblLength to show the number of characters. I am using lblLength.setText(taMessage.getText().length()+"/ 160"); to display the character count.

What event listener should I use for taMessage so that as I keep typing text in my text area, lblLength keeps on updating itself?

Something like we see in sites like way2sms or 160by2, where it shows the number of characters left.

newbee
  • 409
  • 2
  • 12
  • 34

3 Answers3

4

Swing text fields and text areas are backed by a class called Document that can have a Document Listener attached to it.

The official docs have a decent tutorial on Document Listeners.

You would want to attach the document listener, and since you're interested in character counts then you'd simply want to use the same code you used above to initialize the label in all three of the Document Listener's callback methods.

Doug Stephen
  • 7,181
  • 1
  • 38
  • 46
3

In an MVC like way you can listen to the document's change.

JTextArea ta = ...;
JLabel lblLength = ...;
Document taDoc = ta.getDocument();
taDoc.addDocumentListener(new CharacterCounterDocumentListener(lblLength))


public class CharacterCounterDocumentListener implements DocumentListener {

     private JLabel counterLabel;        

     public CharacterCounterDocumentListener(JLabel counterLabel){
         this.counterLabel = counterLabel;
     }

     public void changedUpdate(DocumentEvent e) {
        Document d = e.getDocument();
        int length = d.getLength();
        counterLabel.setText(Integer.toString(length));
     }
     public void insertUpdate(DocumentEvent e)  {
     }
     public void removeUpdate(DocumentEvent e) {
     }
}
René Link
  • 48,224
  • 13
  • 108
  • 140
0

A DocumentListener is probably your best bet. You don't even need to create a new class, you can just define it inline.

// Listen for changes in the text
taMessage.getDocument().addDocumentListener(new DocumentListener() {
    public void changedUpdate(DocumentEvent e) {
        update();
    }

    public void removeUpdate(DocumentEvent e) {
        update();
    }

    public void insertUpdate(DocumentEvent e) {
        update();
    }

    public void update() {
        lblLength.setText(taMessage.getText().length()+"/ 160");
    }
});
David Freitag
  • 2,252
  • 2
  • 16
  • 18
  • This is not the best way to access the length. There is no need to reference the text area. – camickr Jul 01 '13 at 14:51
  • Styled text panes (like `JTextPane` and `JTextEditor`) will return text lengths greater then what is actually displayed. Reference the `Document#getLength` to get a more accurate indication of the number of displayed characters – MadProgrammer Jul 02 '13 at 00:55
  • @MadProgrammer When I try to implement something similar I get told I can't alter the an non-final variable (lblLength) inside an inner class. How do I get round this? – AncientSwordRage Apr 11 '14 at 12:02
  • 1
    @Pureferret You can't modify the reference of lblLemgth, but you can modify its content, like using setText – MadProgrammer Apr 11 '14 at 21:07