Zeichenbegrenzung in JTextArea

MaximaxXx

Mitglied
Hallo,
ich arbeite derzeit an einer Anwendung in Swing die sich ähnlich wie Twitter verhält. Nun muss ich den Bereich in dem man seine neue Nachricht eingibt auf maximal 140 Zeichen begrenz sein. Ich weiß, dass dies bei JTextField möglich ist, diese können jedoch keinen Zeilenumbruch und JTextAreas können keine Zeichenbegrenzung.

Dabei möchte ich dass der User nicht mehr als 140 eingeben kann. Komme jedoch nicht wirklich weiter.

Liebe Grüße Max
 
Moin,

Du brauchst einen KeyListener, um dort nach jedem Tastendruck zu prüfen, ob Dein Textfeld die maximale Länge erreicht hat !

Gruß
KLaus
 
Hallo,

du solltest dem Document der TextArea einen DocumentListener hinzufügen.
Bei dem KeyListener hast du nämlich das Problem, dass auch per Copy und Paste (mit der Maus) was eingefügt werden kann und da reagiert der KeyListener nicht.

Gruß

Sascha
 
Das Document ist das Object was die eigentlichen Eigenschaften des Textes der JTextArea beeinhaltet, sprich es ist die Datenschicht. Standardmäßig enthält eine JTextArea ein PlainDocument, was für einfachen Text auch ausreicht. Um jetzt den Text der reinkommt zu filtern gibt es mehrere Methoden:

Am einfachsten finde ich die insertString eines Documents zu überschreiben, denn die ist die letzte Instanz bevor der String tatsächlich weitergegeben wird, in der Funktion kannst du nochmal filtern wie du willst. Dazu mal ein kleines Beispiel von mir:

Java:
JTextArea jTA = new JTextArea();
jTA.setDocument(new PlainDocument() {  //Eine Anonyme innere Klasse erstellen und instanzieren
  @Override
  public void insertString(int offs, String str, AttributeSet a) {  //die insertString aus PlainDocument ueberschreiben
    int maxAnzahl = 140; //Dein Wert
    if (this.getText().length() + str.length() <= maxAnzahl) 
    {
      super.insertString(offs,str,a); //String zum tatsaechlichen Einfuegen weitergeben
    }
    return;
  }

So würde ich das machen, du könntest dem vorhanden Document auch einen DocumentListener hinzufügen wo du dann in der insertUpdate(DocumentEvent e) den gleichen Filter implementieren könntest. Der Nachteil bei dieser Variante ist, das der Listener erst _nach_ dem einfügen des Textes abgefeuert wird und du dann die Änderung rückgangig machen müsstest, was zwar nicht sehr schwierig ist, aber meiner Meinung nach nicht so elegant wie die andere Lösung.
 
N'Abend

als ich vor einiger Zeit auf das gleiche Problem gestoßen bin, habe ich einfach diesen Beitrag befolgt:
http://geocities.ws/uweplonus/faq/swing.html#zeichenBeschraenken

Das entspricht auch dem Ansatz von Matt.

In unserem Projekt haben wir die dort vorgestellte Klasse "Validation" allerdings noch um die in den FAQs erwähnte Funktionalität ergänzt: mittels einer Regular Expression können bestimmte Zeichen bei der Eingabe ignoriert werden (zum Beispiel wenn nur Zahlen anerkannt werden sollen).
Java:
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

/**
 * this class is a document for text fields to limit the maximum count of
 * inserted characters with the additional ability to ignore a subset of them.
 * <p>
 * to use: <code>JTextfield.setDocument(new Validation(int limit))</code> or
 * <code>JTextfield.setDocument(new Validation(int limit, String regEx))</code>
 * </p>
 * 
 * @author Alexander Elsholz <a
 *         href="http://geocities.ws/uweplonus/faq/swing.html#zeichenBeschraenken">Source</a>
 */
public class Validation extends PlainDocument {

    /**
     * empty string for replacing the characters identified by the regular
     * expression in order to ignore them when displaying the inserted values.
     */
    private static final String EMPTY_STRING = "";
    /**
     * maximum count of characters in the object using this document.
     */
    private final int limit;
    /**
     * regular expression for characters to ignore when inserted in the object
     * using this document.
     */
    private final String regExToIgnore;

    /**
     * constructor for the validation document.
     * 
     * @param maximum
     *        maximum count of characters insertable
     */
    public Validation(final int maximum) {
        this(maximum, null);
    }

    /**
     * constructor for the validation document.
     * 
     * @param maximum
     *        maximum count of characters insertable
     * @param regEx
     *        regular expression to ignore in input
     */
    public Validation(final int maximum, final String regEx) {
        super();
        if (maximum < 0) {
            this.limit = 0;
        } else {
            this.limit = maximum;
        }
        if ((regEx != null) && (regEx.length() > 0)) {
            this.regExToIgnore = regEx;
        } else {
            this.regExToIgnore = null;
        }
    }

    /**
     * overrides insertString() method of PlainDocument regarding the maximum
     * limit and ignoring all parts matching the stored regular expression.
     * 
     * @param offset
     *        position to start the insertion
     * @param str
     *        string to insert
     * @param attr
     *        Attributset of the string
     * @throws BadLocationException
     *         if offset got an invalid value
     */
    @Override
    public final void insertString(final int offset, final String str,
            final AttributeSet attr) throws BadLocationException {
        if (str == null) {
            return;
        }
        String concat;
        if (this.regExToIgnore == null) {
            concat = str;
        } else {
            concat = str.replaceAll(this.regExToIgnore, EMPTY_STRING);
        }
        if ((getLength() + concat.length()) <= this.limit) {
            super.insertString(offset, concat, attr);
        } else {
            super.insertString(offset, concat.substring(0, this.limit
                    - getLength()), attr);
        }
    }
}


Gute Nacht
Carron
 
Zuletzt bearbeitet:
du solltest dem Document der TextArea einen DocumentListener hinzufügen.
Bei dem KeyListener hast du nämlich das Problem, dass auch per Copy und Paste (mit der Maus) was eingefügt werden kann und da reagiert der KeyListener nicht.

Danke, guter Einwand - das habe ich auch noch nie wirklich bedacht :eek::p
LG aus OS
Klaus
 
Zuletzt bearbeitet von einem Moderator:
Zurück