Ograniczenie wprowadzanych znaków do liczb w JTextField

0

Witam

mój problem wydaję się być banalny ale nie mam pomysłu jak to zrobić

Chciałbym ograniczyć użytkownikowi możliwość wpisywania danych wyłącznie do liczb (i przecinka) w kontrolce JTextField.
Jeżeli użytkownik wpisze niewłaściwy znak to powinien być on ignorowany,jeżeli właściwy to porostu pojawi się on w kontrolce.

Tyle udało mi się do tej pory osiągnąć (wydaje mi się ze jestem na właściwej drodze)

private void testKey(java.awt.event.KeyEvent evt) {
int key=evt.getKeyCode();
if(key!=44 && (key > 57 || key < 47))
//tu powinno być ignorowanie znaków
}

Pomóżcie

ps. takie ograniczenie wydaję mi się lepsze niż tworzenie wyjątku i wyświetlanie miliona komunikatów ;-)

0

Ja jestem zwolennikiem pola typu JTextField z nałożonym filtrem i FocusListenerem. Zapobiega to wklejeniu niewłaściwych znaków ze schowka, pozwala kontrolować zakres wprowadzanych liczb, nie można też zdjąć fokusu jeżeli wprowadzone dane są nieprawidłowe. Napisałem własne komponenty (do wpisywania int i double), które dodatkowo malują czerwoną ramkę wokół pola tekstowego jeżeli jego zawartość jest nieakceptowalna.

0

http://4programmers.net/Java/FAQ/Jak_umo%C5%BCliwi%C4%87_wpisywanie_tylko_cyfr_w_komponenty

A dokładnie użycie metody e.consume();
gdzie e to KeyEvent.

0

@nietoperek, korzystałeś z tego kodu? Nie dość, że można ze schowka wkleić dowolny tekst, to nawet jak wpiszesz same cyfry, to masz piękny nieobsłużony wyjątek (wpisz sobie 777777777777777777777).
Ten kod powinien zostać bezzwłocznie usunięty.

0

Robiłem coś takiego:

import javax.swing.text.*;


public class NumericDocument extends PlainDocument {
	
	private int decimalPrecision;
     
     
	public NumericDocument(int decimalPrecision) {
		super();
		this.decimalPrecision = decimalPrecision;
	}
     
	public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException {
		if (str != null){
			if (str.equals(",")) {
				str = ".";
			}
			if (!this.isNumeric(str) && !str.equals(".")) {
				return;
			} else if (str.equals(".") && super.getText(0, super.getLength()).contains(".")) {
				return;
			} else if (this.isNumeric(str) && super.getText(0, super.getLength()).indexOf(".") != -1 && offset > super.getText(0, super.getLength()).indexOf(".") && super.getLength() - super.getText(0, super.getLength()).indexOf(".") > decimalPrecision && decimalPrecision > 0) {
				return;
			}
			super.insertString(offset, str, attr);
		}
		return;
	}
	
	private boolean isNumeric(String s) {
		return s.matches("\\d*\\.?\\d+");
	}
}

Znaki są ograniczone do cyfr i kropki. W konstruktorze przekazujesz ilość cyfr po przecinku jaką może wprowadzić użytkownik. Dodatkowo przecinki są automatycznie zamieniane na kropkę. Pisałem to dosyć dawno, więc może być brzydko (ale nie musi), ale na pewno zrozumiesz. Plusem jest, że wprowadzanych znaków nie widać w polu tekstowym, bo są one odrzucane wcześniej.
Zmodyfikujesz do swoich potrzeb (przecinek zamiast kropki) bez problemu.

Po utworzeniu JTextFielda daj:

textField.setDocument(new NumericDocument(4));
0

Właśnie przypomniało mi się, że nie pisałem tego, tylko brałem z neta z drobnymi przeróbkami ;-P Żeby nie było, że przywłaszczam kod ;-)

0
bo napisał(a)

@nietoperek, korzystałeś z tego kodu? Nie dość, że można ze schowka wkleić dowolny tekst, to nawet jak wpiszesz same cyfry, to masz piękny nieobsłużony wyjątek (wpisz sobie 777777777777777777777).
Ten kod powinien zostać bezzwłocznie usunięty.

Chodziło mi, że tam jest przykład z consume();..
Jeśli chodzi o to, to miałem sobie napisane całą ulepszoną wersję, w której ani ze schowka itp się nie wklei. Może go potem wstawię, bo mam go u kolegi na dysku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1