0

这是 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)。

4

1 回答 1

0

lazy在这里没有必要。如果存在初始化顺序问题,则在 JFXApp 中使用它。

为中心工作。必须首先展示舞台。我不确定它是 JavaFX 8 中的新功能,还是原始StageCoachMain代码中存在错误。只需添加:

stage.show()

在最后三行之前。您也可以简单地替换它们:

stage.centerOnScreen()

感谢您指出了这一点。我清理了 ProScalaFX 存储库中的代码。

于 2015-09-19T03:12:37.113 回答