【问题标题】:How to create Scala swing wrapper classes with SuperMixin?如何使用 SuperMixin 创建 Scala swing 包装类?
【发布时间】:2014-02-12 12:10:57
【问题描述】:

我试图从这个线程的答案中了解以下类的工作原理: Scala Popup Menu

由于线程很老,我决定开始一个新问题。我是具有 Java 背景的 Scala 新手,我想知道这个类是如何工作的。我读到与类同名的对象就像具有单例对象的类?我不确定这如何适合实现包装器..(为什么我们需要对象?)

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 */
}

【问题讨论】:

    标签: swing scala mixins traits


    【解决方案1】:

    PopupMenucompanion 对象 在这里没有任何特定用途,除了作为辅助特征 JPopupMenuMixin 的名称空间。然后可以通过将其设置为 private[PopupMenu] 来“隐藏”该特征,因此它仅由类 PopupMenu 及其伴生对象知道。

    坦率地说,我看不出这种特质的目的。它定义了一个方法 popupMenuWrapper 指向外部 Scala Swing 组件,但根本没有使用该方法。所以一个不那么容易混淆的版本就是:

    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 with SuperMixin overrides a few methods,例如paintComponent,以便将它们转发到外包装组件。就是这样。

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

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-11
    • 1970-01-01
    • 2015-11-25
    • 2015-05-31
    • 2011-04-03
    • 1970-01-01
    • 2013-08-15
    • 2020-05-24
    相关资源
    最近更新 更多