【问题标题】:Undo behavior on textField value based on value verification after focus lost在焦点丢失后基于值验证撤消文本字段值的行为
【发布时间】:2013-01-20 09:08:33
【问题描述】:

我根据之前在此处发布的代码 (Filter users values on TextField input after a BindDirectional strategy betwen a Slider and min/max TextField) 发布新问题

我的目标很简单,在用户失去对我的值的焦点事件后,撤消错误的TextField 值(基于自定义验证)的最佳方法是什么。

唯一的方法是在用户用另一个焦点事件覆盖之前访问 oldValue ?

其实我有这个简单的代码:

val myTextField = new TextField ()

def parseDouble(s: String) = try {
  Some(s.toDouble)
} catch {
  case _ ⇒ None
}

myTextField.focusedProperty().addListener(
  new ChangeListener[java.lang.Boolean]() { 
    override def changed(observable: ObservableValue[_ <: java.lang.Boolean], oldValue: java.lang.Boolean, newValue: java.lang.Boolean) {
      if (!newValue) {
        parseDouble(myTextField.textProperty().get()) match {
          case Some(d: Double) ⇒  // test on the double value entered by user
          case _ ⇒ // code to reset to old value ??
        }
      }
    }
  })

更新 1:

我在这里找到讨论:https://forums.oracle.com/forums/thread.jspa?threadID=2382472 关于 TextField/TextArea 的撤消功能 和其他关于 TextInputControlBehavior 的源代码:https://forums.oracle.com/forums/thread.jspa?threadID=2438759&tstart=45

我在这里http://javafx-jira.kenai.com/browse/RT-7547 找到了 javafx 2.2 中实现的撤消行为的描述,但我找不到示例代码...

更新 2:

我在这里找到了TextInputControl 的公共撤消控制 API(路线图为 2.2.6 固定)的帖子:http://javafx-jira.kenai.com/browse/RT-26575

TextInputBehaviorControl 可以在这里看到:https://bitbucket.org/shemnon/openjfx-rt/src/6696e9cea59c401d2637d82f9cf96a515d210203/javafx-ui-controls/src/com/sun/javafx/scene/control/behavior/TextInputControlBehavior.java

更新 3:

塔达姆!

最后我找到了一个可怕的方法来做到这一点,我希望公共 API 适用于 2.2.6 版本的 javaFX ...

    val myTextField = new TextField ()
    
    def parseDouble(s: String) = try {
      Some(s.toDouble)
    } catch {
      case _ ⇒ None
    }
    

  myTextField.focusedProperty().addListener(
    new ChangeListener[java.lang.Boolean]() { db ⇒
      override def changed(observable: ObservableValue[_ <: java.lang.Boolean], oldValue: java.lang.Boolean, newValue: java.lang.Boolean) {
        if (!newValue) {
          parseDouble(myTextField.textProperty().get()) match {
            case Some(d: Double) ⇒
              if (myTextField.minValue > d || d > myTextField.maxValue) {
                doubleField.getSkin.asInstanceOf[TextInputControlSkin[_, _]].getBehavior.asInstanceOf[TextInputControlBehavior[_]].callAction("Undo")
              } else {
                // Here you change value property of textField
              }
            case _ ⇒ myTextField.getSkin.asInstanceOf[TextInputControlSkin[_, _]].getBehavior.asInstanceOf[TextInputControlBehavior[_]].callAction("Undo")
          }
        }
      }
    })

如果有人找到更好的方法,我会验证答案:)

【问题讨论】:

  • 听起来你已经有了答案。
  • @Andy-till 我不是 javafx 方面的专家,也不是具有事件构建的 ui 专家:/ 我搜索了执行此行为的正确方法,但如果这是唯一的方法,我考虑发布源代码在这里帮助社区。我编辑了一些讨论路径..

标签: scala event-handling javafx-2 textfield undo


【解决方案1】:

由于我目前也在使用 Scala 解决方案开发 JavaFX,因此我想尝试您的示例,但无法编译它。具体doubleFieldvalue.set未知!

我有一些提示—— 第一:有一个明显的代码重复,可以通过向案例添加条件来轻松解决 - 第一种情况仅在满足条件(d in range)时才成立

case Some(d: Double) if (doubleField.minValue <= d && d <= doubleField.maxValue) ⇒
  value.set(d)
case _ ⇒ 
  doubleField.getSkin.asInstanceOf[TextInputControlSkin[_, _]].getBehavior.asInstanceOf[TextInputControlBehavior[_]].callAction("Undo")

第二:为 Java 中的匿名内部类提供一个包装器——例如上面的 ChangeListener 可以这样包装:

implicit def unit2ChangeListener[T](f: (ObservableValue[_ <: T], T, T) => Unit) =
  new ChangeListener[T] {
    override def changed(observable: ObservableValue[_ <: T], oldValue: T, newValue: T) {
      f(observable, oldValue, newValue)
    }
}

这些隐式转换可以隐藏在 util 类中(以及一个不错的 unit2EventHandler)并导入到您的应用程序中。 这将导致一些更具可读性的东西(但仍然有点痛苦):

myTextField.focusedProperty().addListener(
  (observable: ObservableValue[_ <: java.lang.Boolean], 
     oldValue: java.lang.Boolean, newValue: java.lang.Boolean) =>
     if (!newValue) { ... }
)

可能ScalaFx已经提供了类似的东西,但我还没有尝试过。

【讨论】:

  • 嗨@michael_s,感谢您的提示,抱歉复制/粘贴错误,我更新源代码:doubleField = myTextField .. 如果您想查看真正的代码源示例工作,如果您想对其进行一些修改,感谢您以这种艰难的方式提供帮助 scala + javafx :) gist.github.com/reyman/4753927
猜你喜欢
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-19
  • 1970-01-01
  • 2021-02-06
  • 2011-04-01
  • 2011-08-12
相关资源
最近更新 更多