Wie von Oracle vorgeschlagen, verwenden Sie formatierte Textfelder
%Vor%Formatierte Textfelder bieten Entwicklern die Möglichkeit, den gültigen Zeichensatz anzugeben, der in ein Textfeld eingegeben werden kann.
Verwenden Sie niemals einen KeyListener dafür. Ihr Code oben hat zwei schwerwiegende Fehler, die beide durch die Verwendung eines KeyListener verursacht werden. Zuerst wird jeder Text fehlen, der eingefügt wird. Immer wenn ich ein Feld finde, das Nicht-Ziffern ausfiltert, versuche ich immer etwas Text einzufügen, nur zum Spaß. In neun von zehn Fällen wird der Text akzeptiert, weil er einen Schlüsselhörer verwendet.
Zweitens haben Sie Modifikatoren nicht herausgefiltert. Wenn der Benutzer versucht, seine Arbeit zu speichern, indem er in diesem Feld Steuerelemente eingibt, wird der Listener das Ereignis konsumieren. Und wenn Ihre Anwendung beispielsweise eine control-5- oder alt-5-Verknüpfung zu einer Aktion zuweist, fügt dieser KeyListener dem Feld eine 5 hinzu, wenn sie es eingeben, obwohl der Benutzer nicht versucht hat, ein Zeichen einzugeben. Sie haben herausgefunden, dass Sie den Rückschrittschlüssel übergeben müssen, aber das ist nicht alles, was Sie passieren müssen. Deine Pfeiltasten funktionieren nicht. Auch Ihre Funktionstasten werden nicht benötigt. Sie können alle diese Probleme beheben, aber es beginnt eine Menge Arbeit.
Es gibt einen dritten Nachteil, aber er wird nur angezeigt, wenn Sie Ihre Anwendung an ein fremdes Alphabet anpassen, insbesondere an ein solches, das mehrere Tastenanschläge benötigt, um ein einzelnes Zeichen wie Chinesisch zu generieren. Diese Alphabete machen KeyListeners nutzlos.
Das Problem ist das. Sie müssen Zeichen filtern, aber bei KeyListeners geht es nicht um Zeichen, sondern um Tastenanschläge, die nicht dasselbe sind: Nicht alle Tastenanschläge erzeugen Zeichen, und nicht alle Zeichen werden durch Tastenanschläge erzeugt. Sie benötigen einen Ansatz, bei dem die Zeichen nach der Generierung überprüft und die geänderten Tastenanschläge bereits herausgefiltert wurden.
Der einfachste Ansatz besteht darin, ein JFormattedTextField zu verwenden, aber ich habe diesen Ansatz nie gemocht, weil er während der Eingabe nicht formatiert oder gefiltert wird. Stattdessen verwende ich einen DocumentFilter. DocumentFilters arbeiten nicht mit Tastenanschlägen, sondern mit den Textzeichenfolgen, wenn sie in das Datenmodell von JTextField eingefügt werden. Alle Control-Tasten, Pfeil- und Funktionstasten erreichen den DocumentFilter nicht. Der gesamte eingefügte Text durchläuft auch den DocumentFilter. Und für Sprachen, die drei Tastenanschläge benötigen, um ein einzelnes Zeichen zu generieren, wird der DocumentFilter nicht aufgerufen, bis das Zeichen generiert wird. So sieht es aus:
%Vor%Die DigitFilter-Klasse sieht so aus:
%Vor%Sie könnten dies als innere Klasse schreiben, aber ich habe eine separate Klasse erstellt, so dass Sie die accept () -Methode überschreiben können, um beliebige Kriterien zu verwenden. Sie können auch feststellen, dass ich nicht auf Ziffern überprüfe, indem ich folgendes schreibe:
%Vor%Stattdessen mache ich das:
%Vor%Dies ist schneller, sauberer und funktioniert mit fremden Nummerierungssystemen. Ich brauche deinen Test auch nicht für das Backspace-Zeichen '\ b'. Ich vermute, dass Ihr erster KeyListener den Backspace-Schlüssel herausgefiltert hat, was Ihr erster Hinweis war, dass es der falsche Ansatz war.
Und zu einem nicht verwandten Hinweis, kodieren Sie nicht Ihre Komponentenpositionen. Erfahren Sie, wie Sie die LayoutManager verwenden. Sie sind einfach zu verwenden und machen Ihren Code viel einfacher zu pflegen.
Ich habe diese Lösung verwendet, sie ist einfach und effizient:
%Vor%