【问题标题】:JavaFX custom CellFactory with Decimal only input仅输入十进制的 JavaFX 自定义 CellFactory
【发布时间】:2014-03-13 14:45:45
【问题描述】:

我创建了一个自定义 TableCell 单元工厂。我希望它只接受十进制输入(数字和只有一个点(。))。下面是 replaceText 和 replaceSelection 的代码,但它不允许我输入任何内容。

        @Override
        public void replaceText(int start, int end, String text) {
            if (text.matches("/^\\d*\\.?\\d*$/")) {
                super.replaceText(start, end, text);
            }
        }

        @Override
        public void replaceSelection(String text) {
            if (text.matches("/\\d*\\.?\\d*$/")) {
                super.replaceSelection(text);
            }
        }
    };

【问题讨论】:

    标签: regex javafx-2 tablecell


    【解决方案1】:

    Java 正则表达式不被“/”包围。根据您想要的实际行为,您需要类似

    final Pattern pattern = Pattern.compile("^\\d*\\.?\\d*$");
    final TextField tf = new TextField() {
       @Override
       public void replaceText(int start, int end, String text) {
           String newText = getText().substring(0, start)+text+getText().substring(end);
            if (pattern.matcher(newText).matches()) {
                super.replaceText(start, end, text);
            }
        }
    
        @Override
        public void replaceSelection(String text) {
            int start = getSelection().getStart();
            int end = getSelection().getEnd();
            String newText = getText().substring(0, start)+text+getText().substring(end);
            if (pattern.matcher(newText).matches()) {
                super.replaceSelection(text);
            }
        }
    };
    

    【讨论】:

      【解决方案2】:

      您的正则表达式有缺陷。它甚至可以与空字符串匹配,因为您在那里将所有内容设为可选。

      text.matches("/^\\d*\\.?\\d*$/")
      

      所以改成下面这样:

      text.matches("/^\\d+(\\.\\d+)?$/")
      

      这里表示开头的强制数字(^\\d+),然后是可选的点和数字((\\.\\d+)?$)。

      【讨论】:

      • 您不需要针对正则表达式而不是传递给方法的文本来测试替换结果吗?类似String newText = getText().substring(start)+text+getText.substring(end); if (newText.matches("...")) { super.replace(start, end, text);}
      【解决方案3】:

      之后您将替换文本。我想最好不要直接更改文本并在父级(使用 EventFilter)上收听 KeyEvent.KEY_PRESSED。

      然后你得到事件并检查字符是否为数字。如果您不希望它显示在输入中,则使用该事件。

      【讨论】:

      • 这不是一个好方法。您需要查看整个文本,而不是单独查看每个按键。您将如何使用这种方法来防止无效输入,例如“123.456.789”?干扰 ctrl-C 和 ctrl-V 以及其他预定义的组合键怎么办? OP提出的机制无论如何都不会“替换文本”,如果它们无效,它会否决更改。
      • @James_D,您可以在处理程序中获取整个文本,所以我没有看到任何问题。同样,您可以过滤 ctrl + 击键,它在键事件中。我个人更喜欢这种方法,因为它不依赖于 JavaFX 实现:TextField 是一个黑盒子,如果 TextField API 发生变化,它也不会改变。
      • 一般来说,出于同样的原因,我不喜欢子类化,但在这种情况下,您必须复制大量的功能。您将如何处理允许用户将文本粘贴到文本字段中的内置上下文菜单?没有涉及到击键...
      猜你喜欢
      • 2015-09-11
      • 1970-01-01
      • 2020-03-28
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多