如何使用SuperMixin创建Scala swing包装类?
我试图从这篇文章的答案中了解以下课程的工作原理: 因为这个问题已经很老了,我决定开始一个新的问题。我是一个Java背景的Scala新手,我想知道这个类是如何工作的。我读到一个与类同名的对象就像一个带有单例对象的类?但我不确定这与实现包装器有什么关系。。(为什么我们需要这个对象?) 超级混血儿的特质到底是什么?API说“这个特性用于将某些调用从对等端重定向到包装器,然后再返回。用于公开可通过重写进行自定义的方法。”这并不能很好地向初学者解释 如果有人能帮我向初学者解释这个类和对象(在我看来,很神奇)如何为JPopupMenu创建一个包装器类,并让我调用show方法,使弹出菜单出现在屏幕上,我将不胜感激。。而且似乎我可以设置它的内容(contents+=一些scala.swing.menuItem),而不必在下面的类中定义它如何使用SuperMixin创建Scala swing包装类?,swing,scala,mixins,traits,Swing,Scala,Mixins,Traits,我试图从这篇文章的答案中了解以下课程的工作原理: 因为这个问题已经很老了,我决定开始一个新的问题。我是一个Java背景的Scala新手,我想知道这个类是如何工作的。我读到一个与类同名的对象就像一个带有单例对象的类?但我不确定这与实现包装器有什么关系。。(为什么我们需要这个对象?) 超级混血儿的特质到底是什么?API说“这个特性用于将某些调用从对等端重定向到包装器,然后再返回。用于公开可通过重写进行自定义的方法。”这并不能很好地向初学者解释 如果有人能帮我向初学者解释这个类和对象(在我看来,很神
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()
}