我无法让我的 scalaFX 菜单栏显示在我的 gui 中

I can't get my scalaFX menubar to show up in my gui

我正在使用 ScalaFX,因为我想制作一个加密文件应用程序,但是,正如标题所说,我 运行 遇到了问题。我想避免使用括号,因为我认为它们很丑。

import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.scene.Scene
import scalafx.scene.control._
import scalafx.scene.layout.BorderPane
import scalafx.event.ActionEvent
import scalafx.scene.layout.HBox

object Start extends JFXApp {
  
  
  stage = new PrimaryStage {
    title = "Eencrypt THAT"
    
   
    scene = new Scene(600, 300) {
      val border = new BorderPane
      root = border
      
      val topMenuBar = new MenuBar
      border.top = topMenuBar
      val topMenuBarList = List()
      topMenuBar.menus = topMenuBarList
      
      val menuFileItems = List()
      val menuFile = new Menu("File")
          menuFile.items = menuFileItems
          val menuFileItemNew = new MenuItem("New...")
          menuFileItems :+ menuFileItemNew
          val menuFileItemSave = new MenuItem("Save")
          menuFileItems :+ menuFileItemSave
      topMenuBarList :+ menuFile
      
      val menuEditItems = List()
      val menuEdit = new Menu("Edit")
          menuEdit.items = menuEditItems
          val menuEditItemCut = new MenuItem("Cut")
          menuEditItems :+ menuEditItemCut
          val menuEditItemCopy  =  new MenuItem("Copy")
          menuEditItems :+ menuEditItemCopy
          val menuEditItemPaste  =  new MenuItem("Paste")
          menuEditItems :+ menuEditItemPaste 
      topMenuBarList :+ menuEdit
    
      border.bottom = Label("Lable")
     
    }
  }
  
}

还有什么办法可以做这样的事情:

topMenuBar.menus = val topMenuBarList = List()

那样它会在一行上,但我仍然有一个命名列表要推送。

这里的一个问题是 List() 并不像您认为的那样工作。

首先,:+ 运算符确实将一个元素附加到列表中(这是一个缓慢的操作,因为每次都必须复制整个列表;您应该更喜欢前置)。但是,此运算符 return 是一个包含附加元素的 新列表 ,但由于您不存储结果,因此将其丢弃。 (Scala Lists 是 immutable 元素,不能修改,所以 List operators return new List 个实例。这实际上非常适合 Scala 函数式编程 范例。)

其次,List无法观察到。即使您可以通过向列表添加元素来修改列表,topMenuBar.menusmenuFile.itemsmenuEdit.items 也无法知道添加到列表中的内容。因此,您所做的只是将空列表复制到每个元素。

有几种选择,一种涉及在将实例内容分配给 GUI 之前初始化 List 个实例,另一种使用 ObservableBuffer 而不是 List。 (如果使用 ObservableBuffer,您必须 将其绑定 到关联的 属性,使用 ScalaFX <== 运算符;在 ScalaFX 演示模型中有示例。为了进一步了解背景,ObservableBufferScalaFX 等同于 JavaFXObservableList.) 我更喜欢前者,因为 observable 元素通常只在需要动态修改它们时使用在程序执行期间。

这是第一种方法,它首先填充列表,然后将它们分配给关联的 GUI 元素:

import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.scene.Scene
import scalafx.scene.control._
import scalafx.scene.layout.BorderPane
import scalafx.event.ActionEvent
import scalafx.scene.layout.HBox

object Start extends JFXApp {

  stage = new PrimaryStage {
    title = "Encrypt THAT"

    scene = new Scene(600, 300) {

      // Create the border pane as the root of the scene.
      root = new BorderPane {

        // Create the menu bar as the top of the border pane.
        top = new MenuBar {

          // File menu.
          val menuFile = new Menu("File") {
            val itemNew = new MenuItem("New...")
            val itemSave = new MenuItem("Save")
            items = List(itemNew, itemSave)
          }

          // Edit menu
          val menuEdit = new Menu("Edit") {
            val itemCut = new MenuItem("Cut")
            val itemCopy = new MenuItem("Copy")
            val itemPaste = new MenuItem("Paste")
            items = List(itemCut, itemCopy, itemPaste)
          }

          // Add the File and Edit menu to the menu bar.
          menus = List(menuFile, menuEdit)
        }

        // Bottom label.
        bottom = Label("Label")
      }
    }
  }
}

顺便说一句,为了避免使用大括号,您可能需要等待 Scala 3 (a.k.a. Dotty),不需要它们。与此同时,如果你把它们放进去,你的意图可能会更清晰(并且你的代码 less 对其他 Scala 程序员来说很丑陋)。;-)

或者,如果您在将列表分配给 GUI 元素之前填充它们,您可以很容易地使此代码适应您的无括号样式。