Używam pola tekstowego Vaadin i chcę je ograniczyć, aby obsługiwać tylko numery w nim zawarte. Próbowałem zastąpić setValue()
i wrócić bez sprawdzania super. setValue()
jeśli tekst nie jest liczbą. Ale wydaje się, że nie działa. Jak mogę to poprawić? Używam Vaadin 7. I myślę, że to również nie obsługuje NumberField.w jaki sposób utworzyć pole tekstowe obsługujące tylko liczby w vaadinie
Odpowiedz
Jeśli rozumiem, że pytanie jest poprawne, chcesz mieć pole, które ignoruje wszystkie dane wejściowe, które nie są liczbą, i nie tylko oznaczyć pole jako nieprawidłowe. Architektura Vaadins została zaprojektowana tak, aby każde pole w przeglądarce miało swoją reprezentację na serwerze. Moim zdaniem najczystszym sposobem na osiągnięcie tego byłoby posiadanie pola przeglądarki, które pozwala na wprowadzanie liter i innych złych znaków. Nie mogłem znaleźć takiego pola w Vaadin 7. Wydaje się, że jest tam dodatek do vaadin 6 o nazwie Number Field, ale go nie przetestowałem.
Masz kilka opcji:
Port ten dodatek do Vaadin 7 lub zapytać autora to zrobić
Napisz pole. Może rozszerzenie VTextField i TextFieldConnector
Czy wszystko po stronie serwera i zaakceptować opóźnień i ruch (IMHO brzydki)
Ponieważ myślę, że opcja 3 jest nie droga, pewnie nie powinien pokazywać tego kodu, ale jest to najszybszy sposób na jego wdrożenie.
public class IntegerField extends TextField implements TextChangeListener {
String lastValue;
public IntegerField() {
setImmediate(true);
setTextChangeEventMode(TextChangeEventMode.EAGER);
addTextChangeListener(this);
}
@Override
public void textChange(TextChangeEvent event) {
String text = event.getText();
try {
new Integer(text);
lastValue = text;
} catch (NumberFormatException e) {
setValue(lastValue);
}
}
}
A TextField
to komponent, który zawsze ma wartość typu String
. Podczas wiązania właściwości innego typu z polem tekstowym wartość jest automatycznie konwertowana, jeśli konwersja między tymi dwoma typami jest obsługiwana.
public class MyBean {
private int value;
public int getValue() {
return value;
}
public void setValue(int integer) {
value = integer;
}
}
Obiekt o nazwie „wartość” z BeanItem
zbudowanego z MyBean
będzie od rodzaju Integer
. Wiązanie właściwości z TextField
spowoduje automatyczne sprawdzenie poprawności tekstów, których nie można przekonwertować na liczbę całkowitą.
final MyBean myBean = new MyBean();
BeanItem<MyBean> beanItem = new BeanItem<MyBean>(myBean);
final Property<Integer> integerProperty = (Property<Integer>) beanItem
.getItemProperty("value");
final TextField textField = new TextField("Text field", integerProperty);
Button submitButton = new Button("Submit value", new ClickListener() {
public void buttonClick(ClickEvent event) {
String uiValue = textField.getValue();
Integer propertyValue = integerProperty.getValue();
int dataModelValue = myBean.getValue();
Notification.show("UI value (String): " + uiValue
+ "\nProperty value (Integer): " + propertyValue
+ "\nData model value (int): " + dataModelValue);
}
});
addComponent(new Label("Text field type: " + textField.getType()));
addComponent(new Label("Text field type: " + integerProperty.getType()));
addComponent(textField);
addComponent(submitButton);
W tym przykładzie wprowadzanie numeru i naciśnięcie przycisku powoduje, że wartość TextField
być String
wartość właściwość będzie Integer
reprezentujący tę samą wartość, a wartość w ziarnach będzie taka sama int. Jeśli np. do pola zostanie wprowadzona litera, a przycisk zostanie naciśnięty, sprawdzanie poprawności zakończy się niepowodzeniem. Powoduje to wyświetlenie powiadomienia dla pola. Wartość pola jest nadal aktualizowana, ale wartość właściwości i wartość komponentu bean są przechowywane w ich poprzednich wartościach.
Nie chcę aktualizować wartości pola. –
Vaadin 7 pozwala przedłużyć thier wybudowany w widgetach (jeśli chcesz mieć większą wiedzę na ten temat naprawdę polecam ten post) Tutaj jest rozwiązanie, które używa tego mechanizmu.
Składa się on z dwóch klas: Connector oraz rozszerzenie
Extension
package com.infosystem.widgets.vaadin; import com.vaadin.server.AbstractClientConnector; import com.vaadin.server.AbstractExtension; import com.vaadin.ui.TextField; public class NumberField extends AbstractExtension { public static void extend(TextField field) { new NumberField().extend((AbstractClientConnector) field); } }
Złącze:
package com.infosystem.widgets.vaadin.client.numberField; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyPressEvent; import com.google.gwt.event.dom.client.KeyPressHandler; import com.infosystem.widgets.vaadin.NumberField; import com.vaadin.client.ComponentConnector; import com.vaadin.client.ServerConnector; import com.vaadin.client.extensions.AbstractExtensionConnector; import com.vaadin.client.ui.VTextField; import com.vaadin.shared.ui.Connect; @Connect(NumberField.class) public class NumberFieldConnector extends AbstractExtensionConnector { private static final long serialVersionUID = -737765038361894693L; private VTextField textField; private KeyPressHandler keyPressHandler = new KeyPressHandler() { @Override public void onKeyPress(KeyPressEvent event) { if (textField.isReadOnly() || !textField.isEnabled()) { return; } int keyCode = event.getNativeEvent().getKeyCode(); switch (keyCode) { case KeyCodes.KEY_LEFT: case KeyCodes.KEY_RIGHT: case KeyCodes.KEY_BACKSPACE: case KeyCodes.KEY_DELETE: case KeyCodes.KEY_TAB: case KeyCodes.KEY_UP: case KeyCodes.KEY_DOWN: case KeyCodes.KEY_SHIFT: return; } if (!isValueValid(event)) { textField.cancelKey(); } } }; @Override protected void extend(ServerConnector target) { textField = (VTextField) ((ComponentConnector) target).getWidget(); textField.addKeyPressHandler(keyPressHandler); } private boolean isValueValid(KeyPressEvent event) { String newText = getFieldValueAsItWouldBeAfterKeyPress(event.getCharCode()); try { parseValue(newText); return true; } catch (Exception e) { return false; } } protected long parseValue(String value) { return Long.valueOf(value); } private String getFieldValueAsItWouldBeAfterKeyPress(char charCode) { int index = textField.getCursorPos(); String previousText = textField.getText(); StringBuffer buffer = new StringBuffer(); buffer.append(previousText.substring(0, index)); buffer.append(charCode); if (textField.getSelectionLength() > 0) { buffer.append(previousText.substring(index + textField.getSelectionLength(), previousText.length())); } else { buffer.append(previousText.substring(index, previousText.length())); } return buffer.toString(); } }
Aby użyć kodu do A bove musisz dodać go do bieżącego zestawu widgetów. Następnie korzystanie z tego jest następujący:
TextField field = new TextField();
NumberField.extend(field);
Aby dodać go do zestawu widgetów, klasa Connector powinna znajdować się w folderze o nazwie "client" na tym samym poziomie co niestandardowy plik zestawu widgetów (na przykład MyWigetSet.gwt.xml). Aby użyć niestandardowego zestawu widgetów, musi on zostać zadeklarowany jako init-param w serwlecie. – enkara
W Vaadin 7, można użyć TextField i ustawić walidator, aby umożliwić tylko liczby:
TextField textField;
textField.addValidator(new RegexpValidator("[-]?[0-9]*\\.?,?[0-9]+"), "This is not a number!");
Zmień regex do swoich potrzeb. Pamiętaj, że nadal obsługi łańcuchów i dlatego nadal trzeba konwertować wartości Zwrot TextField:
Long.parseLong(textField.getValue())
Jest to aktualizacja (2017 z Vaadin 8) dla @raffael odpowiedź:
public class DoubleField extends TextField implements ValueChangeListener<String> {
/**
*
*/
private static final long serialVersionUID = 1L;
public String lastValue;
public DoubleField() {
setValueChangeMode(ValueChangeMode.EAGER);
addValueChangeListener(this);
lastValue="";
}
@Override
public void valueChange(ValueChangeEvent<String> event) {
String text = (String) event.getValue();
try {
new Double(text);
lastValue = text;
} catch (NumberFormatException e) {
setValue(lastValue);
}
}
Voilà!
NumberField jest już dostępny dla Vaadin 7 i 8.
dzięki stary. To działa dobrze. Dodałem kilka pustych czeków i pustych czeków i załatwiłem je. –
Działa, ale przy szybkim wpisywaniu wielu znaków nadal można wprowadzać niepożądane treści. – Eyal
Jego generalnie uważa się za złą praktykę stosowanie wyjątków do sterowania przepływem. Zobacz http://c2.com/cgi/wiki?DontUseExceptionsForFlowControl, http://programmers.stackexchange.com/questions/189222/are-exceptions-as-control-flow-considered-a-serious-antipattern-if-so -dhy lub http://stackoverflow.com/questions/729379/why-not-use-exceptions-as-regular-flow-of-control. –