【问题标题】:How can I filter input to a Scala swing TextField如何过滤输入到 Scala swing TextField
【发布时间】:2012-12-05 04:26:47
【问题描述】:

有没有一种方便的方法可以将过滤器添加到 scala.swing.TextComponent 的输入中,以便用户只能输入整数/浮点数/其他?特别是,有没有办法将粘贴过滤到文本字段中?在 Java 中,我使用了 DocumentFilter 来做到这一点。我已经尝试了一些变体:

object inputField extends TextField{

   peer.getDocument.asInstanceOf[AbstractDocument].setDocumentFilter(new DocumentFilter{

      def insertString(fb: FilterBypass, offs: Integer, str: String, a: AttributeSet){
         if(str.forall((c)=>c.isDigit)) super.insertString(fb, offs, str, a)
      }

      def replace(fb: FilterBypass, offs: Integer, l: Integer, str: String, a: AttributeSet){
         if(str.forall((c)=>c.isDigit)) super.replace(fb, offs, l, str, a)
      }
   })
}

这不起作用。我做错了吗,还是 Scala 忽略了文档过滤器?还有另一种方法可以做到这一点吗?如果需要的话,我可能完全可以使用 java.swing GUI。

【问题讨论】:

  • 我不确定您是否可以在构造 TextField 时附加 DocumentFilter(我在 java 中从未见过这样的示例)。您是否尝试过创建一个普通的 TextField 并在创建后将 DocumentFilter 附加到它?

标签: scala


【解决方案1】:

您可以使用反应来实现这一点:

import swing._
import swing.event._

object SwingApp extends SimpleSwingApplication {
  def top = new MainFrame {
    contents = new TextField {
      listenTo(keys)
      reactions += { case e: KeyTyped =>
        if (!e.char.isDigit) e.consume
      }
    }
  }
}

更新: 哦,我同意,这仅适用于相对琐碎的情况。我发现您的原始解决方案存在问题:您在需要 Ints 的地方使用整数,因此您的方法只是新方法,而不是抽象类方法的实现。这对我来说是这样的:

contents = new TextField {
  object IntegralFilter extends DocumentFilter {
    override def insertString(fb: FilterBypass, offs: Int, str: String, a: AttributeSet){
       if(str.forall((c)=>c.isDigit)) super.insertString(fb, offs, str, a)
    }    
    override def replace(fb: FilterBypass, offs: Int, l: Int, str: String, a: AttributeSet){
       if(str.forall((c)=>c.isDigit)) super.replace(fb, offs, l, str, a)
    }
  }

  peer.getDocument().asInstanceOf[AbstractDocument].setDocumentFilter(IntegralFilter)
}

注意“覆盖”的使用。这就是我得到编译器错误和相应 IDE 提示的原因,如果我真的想用这个覆盖某些东西,我必须更改签名。

【讨论】:

  • 不,你不能。例如,如果您键入 Ctrl+V,那不是数字,因此您最终会得到 12garbage34,它不是整数。此外,虽然我的代码是为了过滤整数而编写的,但我真的希望能够过滤浮点数,例如 123.4,但不是 123.4.5.6,或者我想要过滤的任何其他内容。
【解决方案2】:

这个类可以正确处理除指数之外的所有有效数字:

class NumberField(initialValue: Double) extends TextField(initialValue.toString) {
  // Note: exponents are not allowed
  val numberFormatException = new NumberFormatException
  listenTo(keys)
  reactions += {
    case event: KeyTyped => {
      try {
        // Don't allow "d" or "f" in the string even though it parses, e.g. 3.5d
        if (event.char.isLetter)
          throw numberFormatException
        // Don't allow string that doesn't parse to a double
        (text.substring(0, caret.position) +
          event.char +
          text.substring(caret.position)).toDouble
      } catch {
        case exception: NumberFormatException => event.consume()
      }
    }
  }

  def value : Double = text.toDouble
}

【讨论】:

    猜你喜欢
    • 2011-06-08
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 2015-05-10
    • 1970-01-01
    相关资源
    最近更新 更多