我正在尝试从这个帖子的答案中理解以下类是如何工作的: Scala Popup Menu
由于线程很老,我决定开始一个新问题。我是Scala的新手,有Java背景,我想知道这个类是如何工作的。我读到一个与类同名的对象就像一个带有单例对象的类?我不确定这对于实现包装器是否适合..(为什么我们需要对象?)
SuperMixin的特质究竟是什么? API说“这个特性用于将来自对等体的某些调用重定向到包装器并返回。用于公开可以通过覆盖自定义的方法。”这对初学者的解释不是很好。
如果有人可以帮助向初学者解释这个类和对象(在我看来,神奇地)让我成为JPopupMenu的包装类并让我调用show方法使popupMenu出现,我真的很感激。屏幕..而且似乎我可以设置其内容(内容+ =一些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 */
}
答案 0 :(得分:2)
PopupMenu
的伴随对象除了作为辅助特征JPopupMenuMixin
的名称空间之外,在此处没有任何特定用途。然后可以通过将其设为private[PopupMenu]
来“隐藏”此特征,因此只有类PopupMenu
及其伴随对象才能知道它。
popupMenuWrapper
,但根本不使用该方法。所以一个不那么令人困惑的版本就是:
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)
}
测试:
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()
}
包装器唯一需要的是扩展scala.swing.Component
并覆盖基础peer
组件的javax.swing
值。该组件的mixin with SuperMixin
overrides a few methods,例如paintComponent
,以便将它们转发到外部包装器组件。就是这样。
包装器混合在SequentialContainer.Wrapper
中,允许contents +=
操作添加菜单项。