it-swarm.com.de

wie erstelle ich ein Textfeld, das Zahlen nur in Vaadin unterstützt?

Ich verwende ein Vaadin-Textfeld und möchte es darauf beschränken, nur Zahlen darin zu unterstützen. Ich habe versucht, setValue() zu überschreiben und zurückzukehren, ohne super anzurufen. setValue() wenn der Text keine Zahl ist. Aber es scheint nicht zu funktionieren. Wie kann ich das korrigieren? Ich benutze Vaadin 7. Und ich denke, es unterstützt NumberField auch nicht.

11

Wenn ich verstehe, dass Ihre Frage richtig ist, möchten Sie ein Feld haben, das alle Eingaben ignoriert, die keine Zahl sind, und das Feld nicht nur als ungültig markiert. Die Vaadins-Architektur ist so konzipiert, dass jedes Feld im Browser auf dem Server dargestellt wird. Meiner Meinung nach wäre der sauberste Weg, dies zu erreichen, ein Browserfeld zu haben, in das Buchstaben und andere falsche Zeichen eingegeben werden können. In Vaadin 7 konnte ich ein solches Feld nicht finden. Es scheint ein Add-On für Vaadin 6 zu geben, das Zahlenfeld heißt, aber ich habe es nicht getestet.
Sie haben mehrere Möglichkeiten:

  1. Portieren Sie dieses Add-On auf Vaadin 7 oder bitten Sie den Autor, dies zu tun

  2. Schreibe dein eigenes Feld. Möglicherweise erweitern VTextField und TextFieldConnector

  3. Mach alles auf der Serverseite und akzeptiere die Verzögerungen und den Verkehr (IMHO hässlich)

Da ich denke, dass Option 3 nicht der Weg ist, sollte ich diesen Code wahrscheinlich nicht anzeigen, aber es ist der schnellste Weg, dies zu implementieren.

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);
    }
}
}
18
raffael

Vaadin 7 erlaubt es, die eingebauten Widgets zu erweitern (wenn Sie mehr darüber wissen wollen, empfehle ich dies wirklich post ). Hier ist eine Lösung, die diesen Mechanismus nutzt.

Es besteht aus zwei Klassen: Connector und die Erweiterung

  1. Die Erweiterung

    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);
            }
    }
    
  2. Verbinder:

    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();
    }
    }
    

Um den obigen Code zu verwenden, müssen Sie ihn zu Ihrem aktuellen Widget-Set hinzufügen. Danach ist der Gebrauch davon wie folgt:

TextField field = new TextField();
NumberField.extend(field);
12

In Vaadin 7 können Sie ein TextField verwenden und einen Validator festlegen, um nur Zahlen zuzulassen:

TextField textField;
textField.addValidator(new RegexpValidator("[-]?[0-9]*\\.?,?[0-9]+"), "This is not a number!");

Ändern Sie den regulären Ausdruck entsprechend Ihren Anforderungen. Denken Sie daran, dass immer noch Strings verarbeitet werden und Sie daher den Rückgabewert von TextField noch konvertieren müssen:

Long.parseLong(textField.getValue())
2
King Midas

Dies ist ein Update (2017 mit Vaadin 8) für @raffael Antwort:

public class DoubleField extends TextField implements ValueChangeListener<String>  {

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);
    }

}
2
jdamianb

Eine TextField ist eine Komponente, die immer einen Wert vom Typ String hat. Wenn Sie eine Eigenschaft eines anderen Typs an ein Textfeld binden, wird der Wert automatisch konvertiert, wenn die Konvertierung zwischen den beiden Typen unterstützt wird.

public class MyBean {
    private int value;

    public int getValue() {
        return value;
    }

    public void setValue(int integer) {
        value = integer;
    }
}

Die Eigenschaft mit dem Namen "value" aus einer BeanItem, die aus MyBean erstellt wurde, hat den Typ Integer. Wenn Sie die Eigenschaft an eine TextField binden, schlägt die Überprüfung für Texte, die nicht in eine Ganzzahl konvertiert werden können, automatisch fehl.

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);

Wenn Sie in diesem Beispiel eine Zahl eingeben und die Taste drücken, wird der Wert der TextField zu einer String. Der Eigenschaftswert ist eine Integer, die den gleichen Wert darstellt, und der Wert in der Bean ist der gleiche Int. Wenn z. Wird ein Buchstabe in das Feld eingegeben und die Taste gedrückt, schlägt die Validierung fehl. Dadurch wird ein Hinweis für das Feld angezeigt. Der Feldwert wird weiterhin aktualisiert, aber der Eigenschaftswert und der Bean-Wert werden auf ihren vorherigen Werten gehalten.

2
Ajit

In Vaadin 8 können Sie Binder verwenden:

Binder<YouBean> binder = new Binder<>();
binder.forField(textField)
      .withConverter(new StringToIntegerConverter("Must be Integer"))
      .bind(YouBean::getter, YouBean::setter);
binder.setBean(bean);  //optional
2
Ahmed Ashour

NumberField ist ab sofort für Vaadin 7 und 8 verfügbar.

0
T-Gergely