如何使用SuperMixin创建Scala swing包装类?

如何使用SuperMixin创建Scala swing包装类?,swing,scala,mixins,traits,Swing,Scala,Mixins,Traits,我试图从这篇文章的答案中了解以下课程的工作原理: 因为这个问题已经很老了,我决定开始一个新的问题。我是一个Java背景的Scala新手,我想知道这个类是如何工作的。我读到一个与类同名的对象就像一个带有单例对象的类?但我不确定这与实现包装器有什么关系。。(为什么我们需要这个对象?) 超级混血儿的特质到底是什么?API说“这个特性用于将某些调用从对等端重定向到包装器,然后再返回。用于公开可通过重写进行自定义的方法。”这并不能很好地向初学者解释 如果有人能帮我向初学者解释这个类和对象(在我看来,很神

我试图从这篇文章的答案中了解以下课程的工作原理:

因为这个问题已经很老了,我决定开始一个新的问题。我是一个Java背景的Scala新手,我想知道这个类是如何工作的。我读到一个与类同名的对象就像一个带有单例对象的类?但我不确定这与实现包装器有什么关系。。(为什么我们需要这个对象?)

超级混血儿的特质到底是什么?API说“这个特性用于将某些调用从对等端重定向到包装器,然后再返回。用于公开可通过重写进行自定义的方法。”这并不能很好地向初学者解释

如果有人能帮我向初学者解释这个类和对象(在我看来,很神奇)如何为JPopupMenu创建一个包装器类,并让我调用show方法,使弹出菜单出现在屏幕上,我将不胜感激。。而且似乎我可以设置它的内容(contents+=一些scala.swing.menuItem),而不必在下面的类中定义它

import javax.swing.JPopupMenu
import scala.swing.{ Component, MenuItem }
import scala.swing.SequentialContainer.Wrapper

object PopupMenu {
  private[PopupMenu] trait JPopupMenuMixin { def popupMenuWrapper: PopupMenu }
}

class PopupMenu extends Component with Wrapper {

  override lazy val peer: JPopupMenu = new JPopupMenu with PopupMenu.JPopupMenuMixin with SuperMixin {
    def popupMenuWrapper = PopupMenu.this
  }

  def show(invoker: Component, x: Int, y: Int): Unit = peer.show(invoker.peer, x, y)

  /* Create any other peer methods here */
}
PopupMenu
的伴生对象在这里没有任何特定用途,只是用作辅助特征
JPopupMenuMixin
的名称空间。然后,通过将该特性设置为私有[PopupMenu],可以“隐藏”该特性,因此只有类
PopupMenu
及其伴生对象才知道该特性

坦率地说,我看不出这种特质的目的。它定义了一个指向外部Scala Swing组件的方法
PopupMenuRapper
,但根本不使用该方法。因此,一个不那么令人困惑的版本就是:

import scala.swing._
import javax.swing.JPopupMenu

class PopupMenu extends Component with SequentialContainer.Wrapper {
  override lazy val peer: JPopupMenu = new JPopupMenu with SuperMixin

  def show(invoker: Component, x: Int, y: Int): Unit = peer.show(invoker.peer, x, y)
}
测试:

包装器唯一需要的是扩展
scala.swing.Component
并用底层
javax.swing
组件覆盖
peer
值。该组件的带有SuperMixin的mixin
,例如
paintComponent
,以便将它们转发到外包装组件。就这些


包装器混合在
SequentialContainer中。包装器
允许
contents+=
操作添加菜单项。

谢谢,这更有意义注意:PopupMenu似乎是其中的一部分。
val pop = new PopupMenu {
  contents += new MenuItem("Foo")
}
lazy val but: Button = Button("Test") {
  pop.show(but, 0, 0)
}
val f = new Frame {
  contents = but
  pack().centerOnScreen()
  open()
}