我试图从该线程的答案中了解以下类的工作原理: Scala Popup Menu
由于该线程相当旧,我决定开始一个新问题。我是 Scala 新手,有 Java 背景,我想知道这个类是如何工作的。我读到一个与类同名的对象就像一个带有单例对象的类?我不确定这如何适合实现包装器。(为什么我们需要该对象?)
SuperMixin 特性到底有什么作用? API 表示“此特征用于将某些调用从对等方重定向到包装器并返回。对于公开可通过重写进行自定义的方法很有用。”这并不能很好地向初学者解释。
如果有人能帮助向初学者解释这个类和对象(在我看来,神奇地)如何为我提供 JPopupMenu 的包装类,并让我调用使 popupMenu 出现的 show 方法,我将非常感激屏幕..而且似乎我可以设置其内容(contents+= some 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
的命名空间之外,在这里没有任何特定用途。然后可以通过将其设置为 private[PopupMenu]
来“隐藏”此特征,因此只有类 PopupMenu
及其伴生对象才知道它。
坦白说,我不明白这个特性的目的。它定义了一个指向外部 Scala Swing 组件的方法 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 并使用底层 javax.swing 覆盖 peer
值成分。 mixin 与 SuperMixin
overrides a few methods该组件,例如 paintComponent
,以便将它们转发到外部包装器组件。仅此而已。
包装器混合在 SequentialContainer.Wrapper
中,允许使用 contents +=
操作来添加菜单项。
关于swing - 如何使用 SuperMixin 创建 Scala swing 包装类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21727586/