我是来自JavaFX 1.3的scala新手,这是我在stackoverflow中的第一篇文章
在JavaFX 1.3中我可以做这样的事情
property : bind if (condition) value1 else value2
在Scala中,我尝试过这样的事情:
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
提前感谢您的帮助。
答案 0 :(得分: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
我认为可以通过适应javafx.beans.binding
包的可用类的类型参数来概括createXXXBinding,但我不确定这是一项简单的任务,因为类层次结构没有帮助。
答案 1 :(得分:1)
JavaFX2 +和ScalaFX允许您根据BooleanProperty
或BooleanBinding
动态切换两个绑定属性。这可以使用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
分配false
之后的otherwise
时,第一部分(选择之后)会被分配到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
当你运行它时,你会得到输出:
{{1}}