首页 > 解决方案 > 我无法让我的 scalaFX 菜单栏显示在我的 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()

这样它就会在一条线上,但我仍然有一个命名列表要推送。

标签: scalamenubarscalafxborderpane

解决方案


这里的问题之一是它List()不像你想象的那样工作。

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

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

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

这是第一种方法,它首先填充列表,然后将它们分配给关联的 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(又名Dotty )。与此同时,如果你把它们放进去,你的意图可能会更清晰(并且你的代码对其他Scala程序员来说也不那么难看)。;-)

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


推荐阅读