ScalaFX节点中的懒惰

时间:2015-09-18 11:52:02

标签: scala user-interface javafx scalafx

以下是Pro ScalaFX的示例:

package proscalafx.ch02.stagecoach

import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.beans.property.StringProperty
import scalafx.geometry.VPos
import scalafx.scene.control.{Button, CheckBox, Label, TextField}
import scalafx.scene.input.MouseEvent
import scalafx.scene.layout.{HBox, VBox}
import scalafx.scene.paint.Color
import scalafx.scene.shape.Rectangle
import scalafx.scene.text.Text
import scalafx.scene.{Group, Scene}
import scalafx.stage.{Screen, StageStyle}


/** Stage property example.
  *
  * Can be run with various command line parameters to control stage style:
  * decorated - a solid white background and platform decorations (default).
  * transparent - transparent background and no decorations.
  * undecorated - a solid white background and no decorations.
  * utility - a solid white background and minimal platform decorations used for a utility window.
  * @author Rafael
  */
object StageCoachMain extends JFXApp {

  val titleProperty = StringProperty("")

  // Process command line parameters
  val stageStyle = parameters.unnamed match {
    case Seq("transparent") => StageStyle.TRANSPARENT
    case Seq("undecorated") => StageStyle.UNDECORATED
    case Seq("utility") => StageStyle.UTILITY
    case _ => StageStyle.DECORATED
  }

  lazy val textStageX = new Text {
    textOrigin = VPos.Top
  }
  lazy val textStageY = new Text {
    textOrigin = VPos.Top
  }
  lazy val textStageW = new Text {
    textOrigin = VPos.Top
  }
  lazy val textStageH = new Text {
    textOrigin = VPos.Top
  }
  lazy val textStageF = new Text {
    textOrigin = VPos.Top
  }
  lazy val checkBoxResizable = new CheckBox {
    text = "resizable"
//    disable = stageStyle == StageStyle.TRANSPARENT || stageStyle == StageStyle.UNDECORATED
  }
  lazy val checkBoxFullScreen = new CheckBox {
    text = "fullScreen"
  }
  lazy val titleTextField = new TextField {
    text = "Stage Coach"
    prefColumnCount = 15
  }

  stage = new PrimaryStage {
    resizable = false
    title <== titleProperty
    scene = new Scene(370, 370) {
      fill = Color.Transparent
      root = new Group {
        children = List(
          new Rectangle {
            width = 350
            height = 350
            arcWidth = 50
            arcHeight = 50
            fill = Color.SkyBlue
          },
          new VBox {
            layoutX = 30
            layoutY = 20
            spacing = 10
            children = List(
              textStageX,
              textStageY,
              textStageW,
              textStageH,
              textStageF,
              checkBoxResizable,
              checkBoxFullScreen,
              new HBox {
                spacing = 10
                children = List(
                  new Label("title:"),
                  titleTextField)
              },
              new Button {
                text = "toBack()"
                onAction = handle {stage.toBack()}
              },
              new Button {
                text = "toFront()"
                onAction = handle {stage.toFront()}
              },
              new Button {
                text = "close()"
                onAction = handle {stage.close()}
              }
            )
          }
        )
      }
    }
  }

  //when mouse button is pressed, save the initial position of screen
  val rootGroup = stage.scene().content(0)
  var dragAnchorX = 0.0
  var dragAnchorY = 0.0
  rootGroup.onMousePressed = (me: MouseEvent) => {
    dragAnchorX = me.screenX - stage.x.value
    dragAnchorY = me.screenY - stage.y.value
  }
  rootGroup.onMouseDragged = (me: MouseEvent) => {
    stage.x = me.screenX - dragAnchorX
    stage.y = me.screenY - dragAnchorY
  }

  textStageX.text <== new StringProperty("x: ") + stage.x.asString
  textStageY.text <== new StringProperty("y: ") + stage.y.asString
  textStageW.text <== new StringProperty("width: ") + stage.width.asString
  textStageH.text <== new StringProperty("height: ") + stage.height.asString
  textStageF.text <== new StringProperty("focused: ") + stage.focused.asString
  stage.resizable = false
  // NOTE: Due to a bug in JavaFX (2.2.3+) Stage.resizableProperty(), cannot directly use binding here,
  // see http://javafx-jira.kenai.com/browse/RT-25942
  // TODO: Revert to binding once JavaFX bug is corrected
  //    stage.resizable <==> checkBoxResizable.selected
  checkBoxResizable.selected.onChange {
    // To avoid using resizableProperty, use delegate.setResizable()
    // stage.resizable = checkBoxResizable.selected.get
    stage.delegate.setResizable(checkBoxResizable.selected())
  }
  checkBoxFullScreen.onAction = handle {
    stage.fullScreen = checkBoxFullScreen.selected()
  }
  stage.title <== titleTextField.text

  stage.initStyle(stageStyle)
  stage.onCloseRequest = handle {println("Stage is closing")}
  val primScreenBounds = Screen.primary.visualBounds
  stage.x = (primScreenBounds.width - stage.width()) / 2
  stage.y = (primScreenBounds.height - stage.height()) / 2
}

如果我在这些lazy对象之前移除Text,该应用似乎与以前完全相同。例如,textStageX对象应该实时显示舞台的x坐标,它仍然不是lazy。那么,lazy在这里服务的目的是什么?

另一个问题是这些代码行

val primScreenBounds = Screen.primary.visualBounds
stage.x = (primScreenBounds.width - stage.width()) / 2
stage.y = (primScreenBounds.height - stage.height()) / 2

似乎打算将窗口置于主屏幕的中心,但未能这样做(在OS X 10.10上,使用Java 1.8和Scala 2.11.7)。

0 个答案:

没有答案