如何创建仅在vaadin中支持数字的文本字段

San*_*age 12 java textfield vaadin

我正在使用Vaadin文本字段,我想限制它仅支持数字.我试图覆盖setValue()并返回而不调用super.setValue() 如果文本不是数字.但它似乎没有起作用.我怎么能纠正这个?我正在使用Vaadin 7.我认为它也不支持NumberField.

raf*_*ael 18

如果我理解你的问题是正确的,你想要一个忽略所有非数字输入的字段,而不仅仅是将该字段标记为无效.Vaadins体系结构的设计是浏览器中的每个字段都在服务器上表示.在我看来,实现这一目标的最简洁方法是拥有一个允许输入字母和其他错误字符的浏览器字段.我在Vaadin 7中找不到这样的字段.似乎有一个名为Number Field的 vaadin 6的附加组件,但我没有测试它.
您有多种选择:

  1. 将此附加组件移植到vaadin 7或要求作者执行此操作

  2. 写你自己的领域.也许扩展VTextField和TextFieldConnector

  3. 在服务器端执行所有操作并接受延迟和流量(恕我直言)

因为我认为选项3 不是要走的路,所以我可能不应该显示这段代码,但这是实现它的最快方法.

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);
    }
}
}
Run Code Online (Sandbox Code Playgroud)


小智 12

Vaadin 7允许扩展他们内置的小部件(如果你想对此有更多的了解我真的推荐这篇文章)这里是一个使用该机制的解决方案.

它由两个类组成:Connector和Extension

  1. 扩展

    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);
            }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 连接器:

    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();
    }
    }
    
    Run Code Online (Sandbox Code Playgroud)

要使用上面的代码,您需要将其添加到当前的窗口小部件集.之后使用如下:

TextField field = new TextField();
NumberField.extend(field);
Run Code Online (Sandbox Code Playgroud)