如何过滤Scala swing TextField的输入

时间:2012-12-18 01:20:58

标签: scala

有没有一种方便的方法来添加过滤器来输入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,如果这就是它。

2 个答案:

答案 0 :(得分:2)

您可以使用以下反应来实现此目的:

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所需的Integers,所以你的方法只是新方法,而不是抽象类方法的实现。以下是它对我有用的方法:

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提示,如果我真的想用这个覆盖一些东西,我必须改变签名。

答案 1 :(得分:0)

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

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
}