如何创建仅支持vaadin中的数字的文本字段
我正在使用Vaadin文本字段,并且我想将其限制为仅支持其中的数字。我试图覆盖并返回而不调用超级。 如果文本不是数字。但它似乎不起作用。我该如何更正此问题?我正在使用Vaadin 7。我认为它也不支持NumberField。setValue()
setValue()
我正在使用Vaadin文本字段,并且我想将其限制为仅支持其中的数字。我试图覆盖并返回而不调用超级。 如果文本不是数字。但它似乎不起作用。我该如何更正此问题?我正在使用Vaadin 7。我认为它也不支持NumberField。setValue()
setValue()
如果我理解你的问题是正确的,你想要一个字段,忽略所有不是数字的输入,而不仅仅是将字段标记为无效。Vaadins架构的设计使得浏览器中的每个字段在服务器上都有其表示形式。在我看来,实现这一点的最干净方法是有一个浏览器字段,允许输入字母和其他错误字符。我在Vaadin 7中找不到这样的领域。Vaadin 6似乎有一个名为Number Field的附加组件,但我没有测试它。
您有多种选择:
将此附加组件移植到vaadin 7或要求作者执行此操作
编写自己的字段。也许扩展VTextField和TextFieldConnector
在服务器端做所有事情,接受延迟和流量(恕我直言,丑陋)
由于我认为选项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);
}
}
}
Vaadin 7允许扩展他们的内置小部件(如果你想在这方面有更多的知识,我真的推荐这篇文章),这是一个使用该机制的解决方案。
它由两个类组成:连接器和扩展
扩展
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);
}
}
连接器:
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();
}
}
要使用上面的代码,您需要将其添加到当前的小部件集中。之后的用法如下:
TextField field = new TextField();
NumberField.extend(field);