4

我想要的是用户只能在文本上输入十进制数字,我不希望它允许文本输入为:

  1. 你好
  2. ABC.34
  3. 34.嘿
  4. 32.3333.123

我一直在尝试使用VerifyListener,但它只给了我插入的文本部分,所以我最终得到了我想要插入的文本和插入之前的文本,还尝试组合文本,但我遇到了问题当您删除一个键(退格)时,我最终得到了一个像 234[BACKSPACE]455 这样的字符串。

有没有办法在 Text 上设置 Mask 或成功将 VerifyEvent 与当前文本结合以获得“新文本”,然后再将其设置为 Text?

4

4 回答 4

13

您必须ListenerTextusing上添加一个SWT.Verify。在此Listener您可以验证输入是否仅包含十进制数。

以下将只允许在文本字段中插入小数。每次您更改文本中的某些内容并拒绝它时,它都会检查该值,如果它不是小数。这将解决您的问题,因为在VerifyListener插入新文本之前执行。新文本必须通过侦听器才能被接受。

public static void main(String[] args) {
    Display display = Display.getDefault();
    final Shell shell = new Shell(display);
    shell.setLayout(new FillLayout());
    
    final Text textField = new Text(shell, SWT.BORDER);
    
    textField.addVerifyListener(new VerifyListener() {
        
        @Override
        public void verifyText(VerifyEvent e) {
            
            Text text = (Text)e.getSource();
            
            // Get old text and create new text by using the VerifyEvent.text
            final String oldS = text.getText();
            String newS = oldS.substring(0, e.start) + e.text + oldS.substring(e.end);
            
            try
            {
                Float.parseFloat(newS);
            }
            catch(NumberFormatException ex)
            {
                // Prevent the input from happening, as it's not a float
                e.doit = false;
            }
            
            System.out.println(newS);
        }
    });
    
    shell.pack();
    shell.open();
    while (!shell.isDisposed()) {
        if (!display.readAndDispatch())
            display.sleep();
    }
}
于 2012-08-06T16:12:18.313 回答
2

你试过 Nebula 的 FormattedText Widgets 吗?- 它们是实现此类输入字段的简单方法,请参阅http://eclipse.org/nebula/widgets/formattedtext/formattedtext.php

于 2012-08-07T06:19:06.427 回答
2

为了获得我想要的行为,我必须使用几个侦听器:

  • VerifyListner 限制在键入时被接受为部分输入的字符
  • FocusListener 在离开焦点时验证总输入。如果总输入无效,将显示错误装饰。
  • ModifyListener 检查是否可以在键入时隐藏错误装饰。它不显示错误装饰,因为允许像“4e-”这样的无效部分输入最终输入“4e-3”

    valueField.addVerifyListener((event) -> restrictInput(event));
    valueField.addModifyListener((event) -> validateValueOnChange(valueField.getText()));
    
    valueField.addFocusListener(new FocusListener() {
        @Override
        public void focusGained(org.eclipse.swt.events.FocusEvent e) {}
        @Override
        public void focusLost(org.eclipse.swt.events.FocusEvent event) {
            validateValueOnFocusLoss(valueField.getText());
        }
    });
    
    protected void restrictInput(VerifyEvent event) {
        String allowedCharacters = "0123456789.,eE+-";
        String text = event.text;
        for (int index = 0; index < text.length(); index++) {
            char character = text.charAt(index);
            boolean isAllowed = allowedCharacters.indexOf(character) > -1;
            if (!isAllowed) {
                event.doit = false;
                return;
            }
        }
    }
    
    protected void validateValueOnChange(String text) {
        try {
            Double.parseDouble(valueField.getText());
            valueErrorDecorator.hide();
        } catch (NumberFormatException exception) {
            //expressions like "5e-" are allowed while typing
        }
    }
    
    protected void validateValueOnFocusLoss(String value) {
        try {
            Double.parseDouble(valueField.getText());
            valueErrorDecorator.hide();
        } catch (NumberFormatException exception) {
            valueErrorDecorator.show();
        }
    }
    

ModifyListener 可以进一步改进以检查不能最终给出有效总输入的部分输入,例如“4e-....3”。在这种特殊情况下,ModifyListener 应该在键入时激活错误修饰。

于 2016-03-17T18:06:20.337 回答
0

除了@Tom Seidel 的回答:
您可以使用org.eclipse.swt.widgets.Spinner. 这仅允许数字。您可以指定最小值和最大值,返回值是 aint所以不需要强制转换 a String

final Composite composite parent = new Composite(superParent, SWT.NONE);
parent.setLayout(new FillLayout());
final Spinner spinner = new Spinner(parent, SWT.BORDER);
spinner.setvalues(0, 10, Integer.MAX_VALUE, 0, 1, 10);

的值Spinner可以通过调用来检索:

int selectedValue = spinner.getSelection();
于 2017-03-03T11:52:02.820 回答