2013-02-05 74 views
1

我張貼在此基礎上以前的代碼貼在這裏(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撤消文本字段/文本區域和其他源代碼functionnality約TextInputControlBehaviorhttps://forums.oracle.com/forums/thread.jspa?threadID=2438759&tstart=45

我發現在javafx 2.2中實現的撤銷行爲的描述這裏http://javafx-jira.kenai.com/browse/RT-7547但我不能找到示例代碼...

更新2:

我找到公共撤消控制API(路線固定2.2.6)爲TextInputControl的一則訊息: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:

Tadam!

終於讓我找到我驗證答案的可怕的方式做到這一點,我希望公共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") 
      } 
     } 
     } 
    }) 

,如果有人找到一個更好的方法來做到那:) :)

+0

聽起來像你已經有了答案。 –

+0

@ Andy-till我不是javafx的專家,或者具有構建事件的UI:/我搜索正確的方式來執行此行爲,但如果它是唯一的方法,那麼我考慮在此處發佈源代碼以幫助社區。我編輯了一些討論路徑.. – reyman64

回答

1

因爲我目前正在使用Scala解決方案的JavaFX,我想嘗試你的例子,但我不能得到它編譯。特別是doubleFieldvalue.set是未知的!

我有一些提示 - 第一:有一個明顯的重複代碼,能夠通過添加一個條件的情況下很容易地解決 - 如果不滿足條件(d範圍內)被滿足第一種情況下僅保持

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) 
    } 
} 

這些隱式轉換可能會被隱藏在一個實用程序類(連同一個不錯的unit2EventHa ndler)並導入到您的應用程序。 這會導致一些更可讀的(但還是有點痛苦):

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

也許ScalaFx已經提供了這樣的事情,但我還沒有嘗試過呢。

+0

嗨@michael_s,感謝提示,並抱歉我的錯誤複製/粘貼,我更新了源代碼:'doubleField' ='myTextField' ..如果你想看到真正的代碼源示例哪些工作,如果你想對它做一些修改,感謝在這個硬性的方式scala + javafx的幫助:) https://gist.github.com/reyman/4753927 – reyman64