2013-07-03 21 views
2

我是誰從的JavaFX 1.3傳來階新手,這是我在計算器的第一篇文章結合使用條件邏輯函數在Scala中

在JavaFX 1.3,我可以做這樣的事情

property : bind if (condition) value1 else value2 

在斯卡拉,我試圖做這樣的事情:

property <== function1 

def function1() = { 
    if (condition) 
    value1 
    else 
    value2 
} 

但是,它似乎並沒有動態工作。在舞臺出現時,功能條件下的表達式僅評估一次。我很期待這個表達式中的值可以實時評估。

具體而言,我想調整某些限制,並使用綁定來實現它。所以我希望綁定函數能夠繼續評估表達式,並在調整其他東西時給予我合適的寬度。

無論如何,我將粘貼下面的實際代碼:

var stageWidth = DoubleProperty(0) 
var stageHeight = DoubleProperty(0) 

stageWidth <== stage.scene.width 
stageHeight <== stage.scene.height 

var origStageWidth = DoubleProperty(stage.scene.width.toDouble) 
val origStageHeight = DoubleProperty(stage.scene.height.toDouble) 

val origTextClipperWidth = DoubleProperty(textClipper.width.toDouble) 
val origTextClipperHeight = DoubleProperty(textClipper.height.toDouble) 
val minWidth = DoubleProperty(100) 

val origButtonWidth = DoubleProperty(button.prefWidth.toDouble) 

textClipper.width <== resize 

def resize() ={ 
    var boolResult = (stageWidth - origStageWidth) + origTextClipperWidth > minWidth 
    if (boolResult.value) { 
     (stageWidth - origStageWidth) + origTextClipperWidth 
    } else { 
     minWidth 
    } 
} 

textClipper.height <== (stageHeight - origStageHeight) + origTextClipperHeight 

在此先感謝您的幫助。

+1

從[ScalaFx的主頁(http://code.google.com/p/scalafx /):'顏色<==當(懸停)選擇Color.GREEN否則Color.RED' – senia

+0

謝謝senia,我也發現它幾天前,它的工作原理 –

回答

1

標準函數/方法不是scalafx.beans.Observable,因此它沒有所需的「掛鉤」來使其綁定無效。

前一段時間我做了一些簡化綁定創建的方法,就是爲了這個目的。

下面的代碼是用來做功能結合爲一個字符串值

import scalafx.Includes._ 
import scalafx.beans.binding.StringBinding 
import scalafx.beans.Observable 
import scalafx.collections._ 
import javafx.collections.ObservableList 
import javafx.beans.{ binding => jfxbb } 
import jfxbb.ListBinding 

def createStringBinding(dependency: Observable*)(computeFunction: => String): StringBinding = 
    new jfxbb.StringBinding { 
    //invalidated when the passed dependency becomes invalid 
    dependency.foreach(this.bind(_)) 
    //use the function to compute the new value 
    override def computeValue: String = computeFunction 
} 

在你的情況,你應該做一個雙重結合

//THIS CODE IS NOT TESTED, MAYBE IT NEEDS A LITTLE TWEAKING 

def createDoubleBinding(dependency: Observable*)(computeFunction: => Double): DoubleBinding = 
    new jfxbb.DoubleBinding { 
    //invalidated when the passed dependency becomes invalid 
    dependency.foreach(this.bind(_)) 
    //use the function to compute the new value 
    override def computeValue: Double = computeFunction 
} 

//and use it like 
val resize = createDoubleBinding(
    stageWidth, 
    stageHeight, 
    origStageWidth, 
    origStageHeight, 
    minWidth, 
    origButtonWidth) { 
    var boolResult = (stageWidth - origStageWidth) + origTextClipperWidth > minWidth 
    if (boolResult.value) { 
     (stageWidth - origStageWidth) + origTextClipperWidth 
    } else { 
     minWidth 
    } 
} 

textClipper.width <== resize 

我想這是可能的概括createXXXBinding類型參數適用於javafx.beans.binding包的可用類,但我不確定這將是一件容易的事,因爲類層次結構不起作用。 ..

1

JavaFX2 +和ScalaFX允許您根據BooleanPropertyBooleanBinding動態切換兩個綁定屬性。這可以使用when結構來實現。你coode

property : bind if (condition) value1 else value2 

可以ScalaFX可以表示爲:

property <== when (condition) choose value1 otherwise value2 

在你的具體的例子假定我們創建了一個width屬性根據條件boolResult

val width = DoubleProperty(0) 
是包含動態計算寬度

width屬性綁定到條件表達式使用when構造

width <== when(boolResult) choose ((stageWidth - origStageWidth) + origTextClipperWidth) otherwise minWidth 

boolResult值是true的第一部分(選後)被分配給width當它是falseotherwise之後的部分被分配。這裏是顯示這個動作一個完整的例子:

import scalafx.Includes._ 
import scalafx.beans.property.DoubleProperty 

object ConditionalBindigDemo extends App { 

    val stageWidth = DoubleProperty(200) 
    val origStageWidth = DoubleProperty(100) 

    val origTextClipperWidth = DoubleProperty(20) 
    val minWidth = DoubleProperty(50) 

    val boolResult = (stageWidth - origStageWidth) + origTextClipperWidth > minWidth 
    val width = DoubleProperty(0) 
    width <== when(boolResult) choose ((stageWidth - origStageWidth) + origTextClipperWidth) otherwise minWidth 

    // Simple test 
    printState() 
    stageWidth() = 150 
    printState() 
    stageWidth() = 100 
    printState() 
    stageWidth() = 50 
    printState() 

    def printState() { 
    println("stageWidth: " + stageWidth() + ", origStageWidth: " + origStageWidth() + ", width: " + width()) 
    } 
} 

當你運行它,你會得到輸出:

stageWidth: 200.0, origStageWidth: 100.0, resizeWidth: 120.0 
stageWidth: 150.0, origStageWidth: 100.0, resizeWidth: 70.0 
stageWidth: 100.0, origStageWidth: 100.0, resizeWidth: 50.0 
stageWidth: 50.0, origStageWidth: 100.0, resizeWidth: 50.0